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

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

Pull hwmon updates from Guenter Roeck:
"New drivers:

- Infineon TDA38640 Voltage Regulator

- NXP MC34VR500 PMIC

- GXP fan controller

- MPQ7932 Power Management IC

New chip or board support added to existing drivers:

- it87: IT87952E; also other cleanup/improvements

- intel-m10-bmc-hwmon: N6000

- pmbus/max16601: MAX16600

- aquacomputer_d5next: Aquacomputer Aquastream Ultimate, Aquacomputer
Poweradjust 3, Aquacomputer Aquaero

- nct6775: Support for B650/B660/X670 ASUS boards

- oxp-sensors: AYANEO AIR and AIR Pro

Other notable changes:

- Various kernel documentation fixes

- Various devicetree bindings fixes

- Explicitly deprecated [devm_]hwmon_device_register_with_groups

- ftsteutates: Support for fanX_fault and other cleanup

- ltc2945: Support for setting shunt resistor and other cleanup/fixes

- coretemp: Avoid RDMSR interrupts to isolated CPUs, and simplify
platform device handling

... and various other minor cleanups and fixes"

* tag 'hwmon-for-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (66 commits)
hwmon: Deprecate [devm_]hwmon_device_register_with_groups
hwmon: (mlxreg-fan) Return zero speed for broken fan
hwmon: (gxp-fan-ctrl) use devm_platform_get_and_ioremap_resource()
hwmon: (aquacomputer_d5next) Add support for Aquacomputer Aquastream Ultimate
hwmon: (aquacomputer_d5next) Add support for Aquacomputer Poweradjust 3
hwmon: (iio_hwmon) use dev_err_probe
hwmon: intel-m10-bmc-hwmon: Add N6000 sensors
Docs/hwmon/index: Add missing SPDX License Identifier
hwmon: (it87) Updated documentation for recent updates to it87
hwmon: (it87) Add new chipset IT87952E
hwmon: (it87) Allow multiple chip IDs for force_id
hwmon: (it87) Add chip_id in some info message
hwmon: (it87) List full chip model name
hwmon: (it87) Disable configuration exit for certain chips
hwmon: (it87) Allow disabling exiting of configuration mode
Documentation: hwmon: correct spelling
hwmon: (pmbus/max16601) Add support for MAX16600
hwmon: (ltc2945) Allow setting shunt resistor
hwmon: (ltc2945) Handle error case in ltc2945_value_store
hwmon: (ltc2945) Add devicetree match table
...

+2574 -777
+9
Documentation/ABI/testing/sysfs-class-hwmon
··· 276 276 277 277 RW 278 278 279 + What: /sys/class/hwmon/hwmonX/fanY_fault 280 + Description: 281 + Reports if a fan has reported failure. 282 + 283 + - 1: Failed 284 + - 0: Ok 285 + 286 + RO 287 + 279 288 What: /sys/class/hwmon/hwmonX/pwmY 280 289 Description: 281 290 Pulse width modulation fan control.
+6 -6
Documentation/devicetree/bindings/hwmon/adi,adm1177.yaml
··· 52 52 - | 53 53 #include <dt-bindings/gpio/gpio.h> 54 54 #include <dt-bindings/interrupt-controller/irq.h> 55 - i2c0 { 55 + i2c { 56 56 #address-cells = <1>; 57 57 #size-cells = <0>; 58 58 59 59 pwmon@5a { 60 - compatible = "adi,adm1177"; 61 - reg = <0x5a>; 62 - shunt-resistor-micro-ohms = <50000>; /* 50 mOhm */ 63 - adi,shutdown-threshold-microamp = <1059000>; /* 1.059 A */ 64 - adi,vrange-high-enable; 60 + compatible = "adi,adm1177"; 61 + reg = <0x5a>; 62 + shunt-resistor-micro-ohms = <50000>; /* 50 mOhm */ 63 + adi,shutdown-threshold-microamp = <1059000>; /* 1.059 A */ 64 + adi,vrange-high-enable; 65 65 }; 66 66 }; 67 67 ...
+3 -3
Documentation/devicetree/bindings/hwmon/adi,adm1266.yaml
··· 39 39 40 40 examples: 41 41 - | 42 - i2c0 { 42 + i2c { 43 43 #address-cells = <1>; 44 44 #size-cells = <0>; 45 45 46 46 adm1266@40 { 47 - compatible = "adi,adm1266"; 48 - reg = <0x40>; 47 + compatible = "adi,adm1266"; 48 + reg = <0x40>; 49 49 }; 50 50 }; 51 51 ...
+9 -9
Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
··· 49 49 examples: 50 50 - | 51 51 fpga_axi: fpga-axi { 52 - #address-cells = <0x2>; 53 - #size-cells = <0x1>; 52 + #address-cells = <0x2>; 53 + #size-cells = <0x1>; 54 54 55 - axi_fan_control: axi-fan-control@80000000 { 56 - compatible = "adi,axi-fan-control-1.00.a"; 57 - reg = <0x0 0x80000000 0x10000>; 58 - clocks = <&clk 71>; 59 - interrupts = <0 110 0>; 60 - pulses-per-revolution = <2>; 61 - }; 55 + axi_fan_control: axi-fan-control@80000000 { 56 + compatible = "adi,axi-fan-control-1.00.a"; 57 + reg = <0x0 0x80000000 0x10000>; 58 + clocks = <&clk 71>; 59 + interrupts = <0 110 0>; 60 + pulses-per-revolution = <2>; 61 + }; 62 62 }; 63 63 ...
+49
Documentation/devicetree/bindings/hwmon/adi,ltc2945.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,ltc2945.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Analog Devices LTC2945 wide range i2c power monitor 8 + 9 + maintainers: 10 + - Guenter Roeck <linux@roeck-us.net> 11 + 12 + description: | 13 + Analog Devices LTC2945 wide range i2c power monitor over I2C. 14 + 15 + https://www.analog.com/media/en/technical-documentation/data-sheets/LTC2945.pdf 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - adi,ltc2945 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + shunt-resistor-micro-ohms: 26 + description: 27 + Shunt resistor value in micro-Ohms 28 + default: 1000 29 + 30 + required: 31 + - compatible 32 + - reg 33 + 34 + additionalProperties: false 35 + 36 + examples: 37 + - | 38 + i2c { 39 + #address-cells = <1>; 40 + #size-cells = <0>; 41 + 42 + power-monitor@6e { 43 + compatible = "adi,ltc2945"; 44 + reg = <0x6e>; 45 + /* 10 milli-Ohm shunt resistor */ 46 + shunt-resistor-micro-ohms = <10000>; 47 + }; 48 + }; 49 + ...
+9 -9
Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml
··· 87 87 examples: 88 88 - | 89 89 spi { 90 - #address-cells = <1>; 91 - #size-cells = <0>; 90 + #address-cells = <1>; 91 + #size-cells = <0>; 92 92 93 - ltc2947_spi: ltc2947@0 { 94 - compatible = "adi,ltc2947"; 95 - reg = <0>; 96 - /* accumulation takes place always for energ1/charge1. */ 97 - /* accumulation only on positive current for energy2/charge2. */ 98 - adi,accumulator-ctl-pol = <0 1>; 99 - }; 93 + ltc2947_spi: ltc2947@0 { 94 + compatible = "adi,ltc2947"; 95 + reg = <0>; 96 + /* accumulation takes place always for energ1/charge1. */ 97 + /* accumulation only on positive current for energy2/charge2. */ 98 + adi,accumulator-ctl-pol = <0 1>; 99 + }; 100 100 }; 101 101 ...
+14 -14
Documentation/devicetree/bindings/hwmon/adi,ltc2992.yaml
··· 55 55 56 56 examples: 57 57 - | 58 - i2c1 { 58 + i2c { 59 59 #address-cells = <1>; 60 60 #size-cells = <0>; 61 61 62 - ltc2992@6F { 63 - #address-cells = <1>; 64 - #size-cells = <0>; 62 + ltc2992@6f { 63 + #address-cells = <1>; 64 + #size-cells = <0>; 65 65 66 - compatible = "adi,ltc2992"; 67 - reg = <0x6F>; 66 + compatible = "adi,ltc2992"; 67 + reg = <0x6f>; 68 68 69 - channel@0 { 70 - reg = <0x0>; 71 - shunt-resistor-micro-ohms = <10000>; 72 - }; 69 + channel@0 { 70 + reg = <0x0>; 71 + shunt-resistor-micro-ohms = <10000>; 72 + }; 73 73 74 - channel@1 { 75 - reg = <0x1>; 76 - shunt-resistor-micro-ohms = <10000>; 77 - }; 74 + channel@1 { 75 + reg = <0x1>; 76 + shunt-resistor-micro-ohms = <10000>; 77 + }; 78 78 }; 79 79 }; 80 80 ...
+3 -3
Documentation/devicetree/bindings/hwmon/amd,sbrmi.yaml
··· 41 41 42 42 examples: 43 43 - | 44 - i2c0 { 44 + i2c { 45 45 #address-cells = <1>; 46 46 #size-cells = <0>; 47 47 48 48 sbrmi@3c { 49 - compatible = "amd,sbrmi"; 50 - reg = <0x3c>; 49 + compatible = "amd,sbrmi"; 50 + reg = <0x3c>; 51 51 }; 52 52 }; 53 53 ...
+3 -3
Documentation/devicetree/bindings/hwmon/amd,sbtsi.yaml
··· 42 42 43 43 examples: 44 44 - | 45 - i2c0 { 45 + i2c { 46 46 #address-cells = <1>; 47 47 #size-cells = <0>; 48 48 49 49 sbtsi@4c { 50 - compatible = "amd,sbtsi"; 51 - reg = <0x4c>; 50 + compatible = "amd,sbtsi"; 51 + reg = <0x4c>; 52 52 }; 53 53 }; 54 54 ...
+45
Documentation/devicetree/bindings/hwmon/hpe,gxp-fan-ctrl.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/hpe,gxp-fan-ctrl.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: HPE GXP Fan Controller 8 + 9 + maintainers: 10 + - Nick Hawkins <nick.hawkins@hpe.com> 11 + 12 + description: | 13 + The HPE GXP fan controller controls the fans through an external CPLD 14 + device that connects to the fans. 15 + 16 + properties: 17 + compatible: 18 + const: hpe,gxp-fan-ctrl 19 + 20 + reg: 21 + items: 22 + - description: Fan controller PWM 23 + - description: Programmable logic 24 + - description: Function 2 25 + 26 + reg-names: 27 + items: 28 + - const: base 29 + - const: pl 30 + - const: fn2 31 + 32 + required: 33 + - compatible 34 + - reg 35 + - reg-names 36 + 37 + additionalProperties: false 38 + 39 + examples: 40 + - | 41 + fan-controller@1000c00 { 42 + compatible = "hpe,gxp-fan-ctrl"; 43 + reg = <0x1000c00 0x200>, <0xd1000000 0xff>, <0x80200000 0x100000>; 44 + reg-names = "base", "pl", "fn2"; 45 + };
+4 -4
Documentation/devicetree/bindings/hwmon/iio-hwmon.yaml
··· 31 31 32 32 examples: 33 33 - | 34 - iio-hwmon { 35 - compatible = "iio-hwmon"; 36 - io-channels = <&adc 1>, <&adc 2>; 37 - }; 34 + iio-hwmon { 35 + compatible = "iio-hwmon"; 36 + io-channels = <&adc 1>, <&adc 2>; 37 + };
+20 -20
Documentation/devicetree/bindings/hwmon/national,lm90.yaml
··· 198 198 }; 199 199 - | 200 200 i2c { 201 - #address-cells = <1>; 202 - #size-cells = <0>; 203 - 204 - sensor@4c { 205 - compatible = "adi,adt7481"; 206 - reg = <0x4c>; 207 201 #address-cells = <1>; 208 202 #size-cells = <0>; 209 203 210 - channel@0 { 211 - reg = <0x0>; 212 - label = "local"; 213 - }; 204 + sensor@4c { 205 + compatible = "adi,adt7481"; 206 + reg = <0x4c>; 207 + #address-cells = <1>; 208 + #size-cells = <0>; 214 209 215 - channel@1 { 216 - reg = <0x1>; 217 - label = "front"; 218 - temperature-offset-millicelsius = <4000>; 219 - }; 210 + channel@0 { 211 + reg = <0x0>; 212 + label = "local"; 213 + }; 220 214 221 - channel@2 { 222 - reg = <0x2>; 223 - label = "back"; 224 - temperature-offset-millicelsius = <750>; 215 + channel@1 { 216 + reg = <0x1>; 217 + label = "front"; 218 + temperature-offset-millicelsius = <4000>; 219 + }; 220 + 221 + channel@2 { 222 + reg = <0x2>; 223 + label = "back"; 224 + temperature-offset-millicelsius = <750>; 225 + }; 225 226 }; 226 - }; 227 227 };
+1 -1
Documentation/devicetree/bindings/hwmon/ntc-thermistor.yaml
··· 131 131 132 132 examples: 133 133 - | 134 - thermistor0 { 134 + thermistor { 135 135 compatible = "murata,ncp18wb473"; 136 136 io-channels = <&gpadc 0x06>; 137 137 pullup-uv = <1800000>;
+8 -8
Documentation/devicetree/bindings/hwmon/nuvoton,nct7802.yaml
··· 123 123 #size-cells = <0>; 124 124 125 125 channel@0 { /* LTD */ 126 - reg = <0>; 126 + reg = <0>; 127 127 }; 128 128 129 129 channel@1 { /* RTD1 */ 130 - reg = <1>; 131 - sensor-type = "voltage"; 130 + reg = <1>; 131 + sensor-type = "voltage"; 132 132 }; 133 133 134 134 channel@2 { /* RTD2 */ 135 - reg = <2>; 136 - sensor-type = "temperature"; 137 - temperature-mode = "thermal-diode"; 135 + reg = <2>; 136 + sensor-type = "temperature"; 137 + temperature-mode = "thermal-diode"; 138 138 }; 139 139 140 140 channel@3 { /* RTD3 */ 141 - reg = <3>; 142 - sensor-type = "temperature"; 141 + reg = <3>; 142 + sensor-type = "temperature"; 143 143 }; 144 144 }; 145 145 };
+36
Documentation/devicetree/bindings/hwmon/nxp,mc34vr500.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/nxp,mc34vr500.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: NXP MC34VR500 hwmon sensor 8 + 9 + maintainers: 10 + - Mario Kicherer <dev@kicherer.org> 11 + 12 + properties: 13 + compatible: 14 + enum: 15 + - nxp,mc34vr500 16 + 17 + reg: 18 + maxItems: 1 19 + 20 + required: 21 + - compatible 22 + - reg 23 + 24 + additionalProperties: false 25 + 26 + examples: 27 + - | 28 + i2c { 29 + #address-cells = <1>; 30 + #size-cells = <0>; 31 + 32 + pmic@8 { 33 + compatible = "nxp,mc34vr500"; 34 + reg = <0x08>; 35 + }; 36 + };
+10 -10
Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml
··· 77 77 examples: 78 78 - | 79 79 i2c { 80 - #address-cells = <1>; 81 - #size-cells = <0>; 80 + #address-cells = <1>; 81 + #size-cells = <0>; 82 82 83 - tmp513@5c { 84 - compatible = "ti,tmp513"; 85 - reg = <0x5C>; 86 - shunt-resistor-micro-ohms = <330000>; 87 - ti,bus-range-microvolt = <32000000>; 88 - ti,pga-gain = <8>; 89 - ti,nfactor = <0x1 0xF3 0x00>; 90 - }; 83 + tmp513@5c { 84 + compatible = "ti,tmp513"; 85 + reg = <0x5c>; 86 + shunt-resistor-micro-ohms = <330000>; 87 + ti,bus-range-microvolt = <32000000>; 88 + ti,pga-gain = <8>; 89 + ti,nfactor = <0x1 0xf3 0x00>; 90 + }; 91 91 };
+7 -7
Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml
··· 40 40 examples: 41 41 - | 42 42 i2c { 43 - #address-cells = <1>; 44 - #size-cells = <0>; 43 + #address-cells = <1>; 44 + #size-cells = <0>; 45 45 46 - tps23861@30 { 47 - compatible = "ti,tps23861"; 48 - reg = <0x30>; 49 - shunt-resistor-micro-ohms = <255000>; 50 - }; 46 + tps23861@30 { 47 + compatible = "ti,tps23861"; 48 + reg = <0x30>; 49 + shunt-resistor-micro-ohms = <255000>; 50 + }; 51 51 };
+2
Documentation/devicetree/bindings/trivial-devices.yaml
··· 143 143 - infineon,slb9645tt 144 144 # Infineon SLB9673 I2C TPM 2.0 145 145 - infineon,slb9673 146 + # Infineon TDA38640 Voltage Regulator 147 + - infineon,tda38640 146 148 # Infineon TLV493D-A1B6 I2C 3D Magnetic Sensor 147 149 - infineon,tlv493d-a1b6 148 150 # Infineon Multi-phase Digital VR Controller xdpe11280
+1 -1
Documentation/hwmon/aht10.rst
··· 38 38 ------------- 39 39 40 40 =============== ============================================ 41 - temp1_input Measured temperature in millidegrees Celcius 41 + temp1_input Measured temperature in millidegrees Celsius 42 42 humidity1_input Measured humidity in %H 43 43 update_interval The minimum interval for polling the sensor, 44 44 in milliseconds. Writable. Must be at
+13
Documentation/hwmon/aquacomputer_d5next.rst
··· 5 5 6 6 Supported devices: 7 7 8 + * Aquacomputer Aquaero 5/6 fan controllers 8 9 * Aquacomputer D5 Next watercooling pump 9 10 * Aquacomputer Farbwerk RGB controller 10 11 * Aquacomputer Farbwerk 360 RGB controller 11 12 * Aquacomputer Octo fan controller 12 13 * Aquacomputer Quadro fan controller 13 14 * Aquacomputer High Flow Next sensor 15 + * Aquacomputer Aquastream Ultimate watercooling pump 16 + * Aquacomputer Poweradjust 3 fan controller 14 17 15 18 Author: Aleksa Savic 16 19 ··· 22 19 23 20 This driver exposes hardware sensors of listed Aquacomputer devices, which 24 21 communicate through proprietary USB HID protocols. 22 + 23 + The Aquaero devices expose eight physical, eight virtual and four calculated 24 + virtual temperature sensors, as well as two flow sensors. The fans expose their 25 + speed (in RPM), power, voltage and current. 25 26 26 27 For the D5 Next pump, available sensors are pump and fan speed, power, voltage 27 28 and current, as well as coolant temperature and eight virtual temp sensors. Also ··· 54 47 The High Flow Next exposes +5V voltages, water quality, conductivity and flow readings. 55 48 A temperature sensor can be connected to it, in which case it provides its reading 56 49 and an estimation of the dissipated/absorbed power in the liquid cooling loop. 50 + 51 + The Aquastream Ultimate pump exposes coolant temp and an external temp sensor, along 52 + with speed, power, voltage and current of both the pump and optionally connected fan. 53 + It also exposes pressure and flow speed readings. 54 + 55 + The Poweradjust 3 controller exposes a single external temperature sensor. 57 56 58 57 Depending on the device, not all sysfs and debugfs entries will be available. 59 58 Writing to virtual temperature sensors is not currently supported.
+1 -1
Documentation/hwmon/aspeed-pwm-tacho.rst
··· 10 10 Description: 11 11 ------------ 12 12 This driver implements support for ASPEED AST2400/2500 PWM and Fan Tacho 13 - controller. The PWM controller supports upto 8 PWM outputs. The Fan tacho 13 + controller. The PWM controller supports up to 8 PWM outputs. The Fan tacho 14 14 controller supports up to 16 tachometer inputs. 15 15 16 16 The driver provides the following sensor accesses in sysfs:
+1
Documentation/hwmon/asus_ec_sensors.rst
··· 23 23 * ROG STRIX X570-I GAMING 24 24 * ROG STRIX Z690-A GAMING WIFI D4 25 25 * ROG ZENITH II EXTREME 26 + * ROG ZENITH II EXTREME ALPHA 26 27 27 28 Authors: 28 29 - Eugene Shalygin <eugene.shalygin@gmail.com>
+1 -1
Documentation/hwmon/corsair-psu.rst
··· 40 40 interface of the HXi and RMi series. 41 41 These power supplies provide access to a micro-controller with 2 attached 42 42 temperature sensors, 1 fan rpm sensor, 4 sensors for volt levels, 4 sensors for 43 - power usage and 4 sensors for current levels and addtional non-sensor information 43 + power usage and 4 sensors for current levels and additional non-sensor information 44 44 like uptimes. 45 45 46 46 Sysfs entries
+9
Documentation/hwmon/ftsteutates.rst
··· 22 22 8 fans. It also contains an integrated watchdog which is currently 23 23 implemented in this driver. 24 24 25 + The ``pwmX_auto_channels_temp`` attributes show which temperature sensor 26 + is currently driving which fan channel. This value might dynamically change 27 + during runtime depending on the temperature sensor selected by 28 + the fan control circuit. 29 + 30 + The 4 voltages require a board-specific multiplier, since the BMC can 31 + only measure voltages up to 3.3V and thus relies on voltage dividers. 32 + Consult your motherboard manual for details. 33 + 25 34 To clear a temperature or fan alarm, execute the following command with the 26 35 correct path to the alarm file:: 27 36
+3 -3
Documentation/hwmon/gsc-hwmon.rst
··· 31 31 32 32 Temperatures are measured with 12-bit or 10-bit resolution and are scaled 33 33 either internally or by the driver depending on the GSC version and firmware. 34 - The values returned by the driver reflect millidegree Celcius: 34 + The values returned by the driver reflect millidegree Celsius: 35 35 36 36 tempX_input Measured temperature. 37 37 tempX_label Name of temperature input. ··· 41 41 ------------------ 42 42 43 43 The GSC features 1 PWM output that operates in automatic mode where the 44 - PWM value will be scalled depending on 6 temperature boundaries. 45 - The tempeature boundaries are read-write and in millidegree Celcius and the 44 + PWM value will be scaled depending on 6 temperature boundaries. 45 + The tempeature boundaries are read-write and in millidegree Celsius and the 46 46 read-only PWM values range from 0 (off) to 255 (full speed). 47 47 Fan speed will be set to minimum (off) when the temperature sensor reads 48 48 less than pwm1_auto_point1_temp and maximum when the temperature sensor
+28
Documentation/hwmon/gxp-fan-ctrl.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-only 2 + 3 + Kernel driver gxp-fan-ctrl 4 + ========================== 5 + 6 + Supported chips: 7 + 8 + * HPE GXP SOC 9 + 10 + Author: Nick Hawkins <nick.hawkins@hpe.com> 11 + 12 + 13 + Description 14 + ----------- 15 + 16 + gxp-fan-ctrl is a driver which provides fan control for the hpe gxp soc. 17 + The driver allows the gathering of fan status and the use of fan 18 + PWM control. 19 + 20 + 21 + Sysfs attributes 22 + ---------------- 23 + 24 + ======================= =========================================================== 25 + pwm[0-7] Fan 0 to 7 respective PWM value (0-255) 26 + fan[0-7]_fault Fan 0 to 7 respective fault status: 1 fail, 0 ok 27 + fan[0-7]_enable Fan 0 to 7 respective enabled status: 1 enabled, 0 disabled 28 + ======================= ===========================================================
+3 -3
Documentation/hwmon/hwmon-kernel-api.rst
··· 57 57 hwmon_device_register_with_groups registers a hardware monitoring device. 58 58 The first parameter of this function is a pointer to the parent device. 59 59 The name parameter is a pointer to the hwmon device name. The registration 60 - function wil create a name sysfs attribute pointing to this name. 60 + function will create a name sysfs attribute pointing to this name. 61 61 The drvdata parameter is the pointer to the local driver data. 62 62 hwmon_device_register_with_groups will attach this pointer to the newly 63 63 allocated hwmon device. The pointer can be retrieved by the driver using ··· 299 299 300 300 Return value: 301 301 The file mode for this attribute. Typically, this will be 0 (the 302 - attribute will not be created), S_IRUGO, or 'S_IRUGO | S_IWUSR'. 302 + attribute will not be created), 0444, or 0644. 303 303 304 304 :: 305 305 ··· 360 360 The header file linux/hwmon-sysfs.h provides a number of useful macros to 361 361 declare and use hardware monitoring sysfs attributes. 362 362 363 - In many cases, you can use the exsting define DEVICE_ATTR or its variants 363 + In many cases, you can use the existing define DEVICE_ATTR or its variants 364 364 DEVICE_ATTR_{RW,RO,WO} to declare such attributes. This is feasible if an 365 365 attribute has no additional context. However, in many cases there will be 366 366 additional information such as a sensor index which will need to be passed
+4
Documentation/hwmon/index.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 1 3 ========================= 2 4 Linux Hardware Monitoring 3 5 ========================= ··· 75 73 g762 76 74 gsc-hwmon 77 75 gl518sm 76 + gxp-fan-ctrl 78 77 hih6130 79 78 ibmaem 80 79 ibm-cffps ··· 147 144 max6697 148 145 max8688 149 146 mc13783-adc 147 + mc34vr500 150 148 mcp3021 151 149 menf21bmc 152 150 mlxreg-fan
+42 -5
Documentation/hwmon/it87.rst
··· 145 145 146 146 Datasheet: Not publicly available 147 147 148 + * IT8792E/IT8795E 149 + 150 + Prefix: 'it8792' 151 + 152 + Addresses scanned: from Super I/O config space (8 I/O ports) 153 + 154 + Datasheet: Not publicly available 155 + 156 + * IT87952E 157 + 158 + Prefix: 'it87952' 159 + 160 + Addresses scanned: from Super I/O config space (8 I/O ports) 161 + 162 + Datasheet: Not publicly available 163 + 148 164 * SiS950 [clone of IT8705F] 149 165 150 166 Prefix: 'it87' ··· 178 162 Module Parameters 179 163 ----------------- 180 164 181 - * update_vbat: int 165 + * update_vbat bool 182 166 0 if vbat should report power on value, 1 if vbat should be updated after 183 167 each read. Default is 0. On some boards the battery voltage is provided 184 168 by either the battery or the onboard power supply. Only the first reading ··· 187 171 the chip so can be read at any time. Excessive reading may decrease 188 172 battery life but no information is given in the datasheet. 189 173 190 - * fix_pwm_polarity int 174 + * fix_pwm_polarity bool 191 175 Force PWM polarity to active high (DANGEROUS). Some chips are 192 176 misconfigured by BIOS - PWM values would be inverted. This option tries 193 177 to fix this. Please contact your BIOS manufacturer and ask him for fix. 178 + 179 + * force_id short, short 180 + 181 + Force multiple chip ID to specified value, separated by ','. 182 + For example "force_id=0x8689,0x8633". A value of 0 is ignored 183 + for that chip. 184 + Note: A single force_id value (e.g. "force_id=0x8689") is used for 185 + all chips, to only set the first chip use "force_id=0x8689,0". 186 + Should only be used for testing. 187 + 188 + * ignore_resource_conflict bool 189 + 190 + Similar to acpi_enforce_resources=lax, but only affects this driver. 191 + ACPI resource conflicts are ignored if this parameter is provided and 192 + set to 1. 193 + Provided since there are reports that system-wide acpi_enfore_resources=lax 194 + can result in boot failures on some systems. 195 + Note: This is inherently risky since it means that both ACPI and this driver 196 + may access the chip at the same time. This can result in race conditions and, 197 + worst case, result in unexpected system reboots. 194 198 195 199 196 200 Hardware Interfaces ··· 229 193 230 194 This driver implements support for the IT8603E, IT8620E, IT8623E, IT8628E, 231 195 IT8705F, IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F, 232 - IT8758E, IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, and 233 - SiS950 chips. 196 + IT8758E, IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, 197 + IT8792E/IT8795E, IT87952E and SiS950 chips. 234 198 235 199 These chips are 'Super I/O chips', supporting floppy disks, infrared ports, 236 200 joysticks and other miscellaneous stuff. For hardware monitoring, they ··· 274 238 The IT8620E and IT8628E are custom designs, hardware monitoring part is similar 275 239 to IT8728F. It only supports 16-bit fan mode. Both chips support up to 6 fans. 276 240 277 - The IT8790E supports up to 3 fans. 16-bit fan mode is always enabled. 241 + The IT8790E, IT8792E/IT8795E and IT87952E support up to 3 fans. 16-bit fan 242 + mode is always enabled. 278 243 279 244 The IT8732F supports a closed-loop mode for fan control, but this is not 280 245 currently implemented by the driver.
+1 -1
Documentation/hwmon/ltc2978.rst
··· 333 333 - On LTC3883, temp1 reports an external temperature, 334 334 and temp2 reports the chip temperature. 335 335 336 - temp[N]_min Mimimum temperature. 336 + temp[N]_min Minimum temperature. 337 337 338 338 LTC2972, LTC2974, LCT2977, LTM2980, LTC2978, 339 339 LTC2979, and LTM2987 only.
+10 -1
Documentation/hwmon/max16601.rst
··· 13 13 14 14 Datasheet: Not published 15 15 16 + * Maxim MAX16600 17 + 18 + Prefix: 'max16600' 19 + 20 + Addresses scanned: - 21 + 22 + Datasheet: Not published 23 + 16 24 * Maxim MAX16601 17 25 18 26 Prefix: 'max16601' ··· 44 36 ----------- 45 37 46 38 This driver supports the MAX16508 VR13 Dual-Output Voltage Regulator 47 - as well as the MAX16601 VR13.HC Dual-Output Voltage Regulator chipsets. 39 + as well as the MAX16600, MAX16601, and MAX16602 VR13.HC Dual-Output 40 + Voltage Regulator chipsets. 48 41 49 42 The driver is a client driver to the core PMBus driver. 50 43 Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
+1 -1
Documentation/hwmon/max6697.rst
··· 73 73 This driver implements support for several MAX6697 compatible temperature sensor 74 74 chips. The chips support one local temperature sensor plus four, six, or seven 75 75 remote temperature sensors. Remote temperature sensors are diode-connected 76 - thermal transitors, except for MAX6698 which supports three diode-connected 76 + thermal transistors, except for MAX6698 which supports three diode-connected 77 77 thermal transistors plus three thermistors in addition to the local temperature 78 78 sensor. 79 79
+32
Documentation/hwmon/mc34vr500.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver mc34vr500 4 + ======================= 5 + 6 + Supported Chips: 7 + 8 + * NXP MC34VR500 9 + 10 + Prefix: 'mc34vr500' 11 + 12 + Datasheet: https://www.nxp.com/docs/en/data-sheet/MC34VR500.pdf 13 + 14 + Author: Mario Kicherer <dev@kicherer.org> 15 + 16 + Description 17 + ----------- 18 + 19 + This driver implements initial support for the NXP MC34VR500 PMIC. The MC34VR500 20 + monitors the temperature, input voltage and output currents and provides 21 + corresponding alarms. For the temperature, the chip can send interrupts if 22 + the temperature rises above one of the following values: 110°, 120°, 125° and 23 + 130° Celsius. For the input voltage, an interrupt is sent when the voltage 24 + drops below 2.8V. 25 + 26 + Currently, this driver only implements the input voltage and temperature 27 + alarms. The interrupts are mapped as follows: 28 + 29 + <= 2.8V -> in0_min_alarm 30 + >110°c -> temp1_max_alarm 31 + >120°c -> temp1_crit_alarm 32 + >130°c -> temp1_emergency_alarm
+1 -1
Documentation/hwmon/menf21bmc.rst
··· 7 7 8 8 Prefix: 'menf21bmc_hwmon' 9 9 10 - Adresses scanned: - 10 + Addresses scanned: - 11 11 12 12 Author: Andreas Werner <andreas.werner@men.de> 13 13
+11 -6
Documentation/hwmon/oxp-sensors.rst
··· 3 3 Kernel driver oxp-sensors 4 4 ========================= 5 5 6 - Author: 6 + Authors: 7 + - Derek John Clark <derekjohn.clark@gmail.com> 7 8 - Joaquín Ignacio Aramendía <samsagax@gmail.com> 8 9 9 10 Description: 10 11 ------------ 11 12 12 - One X Player devices from One Netbook provide fan readings and fan control 13 - through its Embedded Controller. 13 + Handheld devices from One Netbook and Aya Neo provide fan readings and fan 14 + control through their embedded controllers. 14 15 15 - Currently only supports AMD boards from the One X Player and AOK ZOE lineup. 16 - Intel boards could be supported if we could figure out the EC registers and 17 - values to write to since the EC layout and model is different. 16 + Currently only supports AMD boards from One X Player, AOK ZOE, and some Aya 17 + Neo devices. One X Player Intel boards could be supported if we could figure 18 + out the EC registers and values to write to since the EC layout and model is 19 + different. Aya Neo devices preceding the AIR may not be supportable as the EC 20 + model is different and do not appear to have manual control capabilities. 18 21 19 22 Supported devices 20 23 ----------------- ··· 25 22 Currently the driver supports the following handhelds: 26 23 27 24 - AOK ZOE A1 25 + - Aya Neo AIR 26 + - Aya Neo AIR Pro 28 27 - OneXPlayer AMD 29 28 - OneXPlayer mini AMD 30 29 - OneXPlayer mini AMD PRO
+1 -1
Documentation/hwmon/pmbus-core.rst
··· 174 174 int (*read_word_data)(struct i2c_client *client, int page, int phase, 175 175 int reg); 176 176 177 - Read word from page <page>, phase <pase>, register <reg>. If the chip does not 177 + Read word from page <page>, phase <phase>, register <reg>. If the chip does not 178 178 support multiple phases, the phase parameter can be ignored. If the chip 179 179 supports multiple phases, a phase value of 0xff indicates all phases. 180 180
+1 -1
Documentation/hwmon/sht4x.rst
··· 37 37 ------------- 38 38 39 39 =============== ============================================ 40 - temp1_input Measured temperature in millidegrees Celcius 40 + temp1_input Measured temperature in millidegrees Celsius 41 41 humidity1_input Measured humidity in %H 42 42 update_interval The minimum interval for polling the sensor, 43 43 in milliseconds. Writable. Must be at least
+1 -1
Documentation/hwmon/smm665.rst
··· 180 180 in10_crit_alarm AIN2 critical alarm 181 181 182 182 temp1_input Chip temperature 183 - temp1_min Mimimum chip temperature 183 + temp1_min Minimum chip temperature 184 184 temp1_max Maximum chip temperature 185 185 temp1_crit Critical chip temperature 186 186 temp1_crit_alarm Temperature critical alarm
+1 -1
Documentation/hwmon/stpddc60.rst
··· 39 39 in 50mV steps. This means that the absolute values of the limits will change 40 40 when the commanded output voltage changes. Also, care should be taken when 41 41 writing to those limits since in the worst case the commanded output voltage 42 - could change at the same time as the limit is written to, wich will lead to 42 + could change at the same time as the limit is written to, which will lead to 43 43 unpredictable results. 44 44 45 45
+1 -1
Documentation/hwmon/submitting-patches.rst
··· 126 126 * Use devm_hwmon_device_register_with_info() or, if your driver needs a remove 127 127 function, hwmon_device_register_with_info() to register your driver with the 128 128 hwmon subsystem. Try using devm_add_action() instead of a remove function if 129 - possible. Do not use hwmon_device_register(). 129 + possible. Do not use any of the deprecated registration functions. 130 130 131 131 * Your driver should be buildable as module. If not, please be prepared to 132 132 explain why it has to be built into the kernel.
+1 -1
Documentation/hwmon/vexpress.rst
··· 27 27 reference & prototyping system for ARM Ltd. processors. It can be set up 28 28 from a wide range of boards, each of them containing (apart of the main 29 29 chip/FPGA) a number of microcontrollers responsible for platform 30 - configuration and control. Theses microcontrollers can also monitor the 30 + configuration and control. These microcontrollers can also monitor the 31 31 board and its environment by a number of internal and external sensors, 32 32 providing information about power lines voltages and currents, board 33 33 temperature and power usage. Some of them also calculate consumed energy
+1 -1
Documentation/hwmon/via686a.rst
··· 58 58 59 59 Voltage sensors (also known as IN sensors) report their values in volts. 60 60 An alarm is triggered if the voltage has crossed a programmable minimum 61 - or maximum limit. Voltages are internally scalled, so each voltage channel 61 + or maximum limit. Voltages are internally scaled, so each voltage channel 62 62 has a different resolution and range. 63 63 64 64 If an alarm triggers, it will remain triggered until the hardware register
+5
MAINTAINERS
··· 2234 2234 M: Jean-Marie Verdun <verdun@hpe.com> 2235 2235 M: Nick Hawkins <nick.hawkins@hpe.com> 2236 2236 S: Maintained 2237 + F: Documentation/hwmon/gxp-fan-ctrl.rst 2237 2238 F: Documentation/devicetree/bindings/arm/hpe,gxp.yaml 2239 + F: Documentation/devicetree/bindings/hwmon/hpe,gxp-fan-ctrl.yaml 2238 2240 F: Documentation/devicetree/bindings/spi/hpe,gxp-spifi.yaml 2239 2241 F: Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml 2240 2242 F: arch/arm/boot/dts/hpe-bmc* 2241 2243 F: arch/arm/boot/dts/hpe-gxp* 2242 2244 F: arch/arm/mach-hpe/ 2243 2245 F: drivers/clocksource/timer-gxp.c 2246 + F: drivers/hwmon/gxp-fan-ctrl.c 2244 2247 F: drivers/spi/spi-gxp.c 2245 2248 F: drivers/watchdog/gxp-wdt.c 2246 2249 ··· 14049 14046 S: Maintained 14050 14047 F: Documentation/devicetree/bindings/mfd/mps,mp2629.yaml 14051 14048 F: Documentation/devicetree/bindings/regulator/mps,mp*.yaml 14049 + F: drivers/hwmon/pmbus/mpq7932.c 14052 14050 F: drivers/iio/adc/mp2629_adc.c 14053 14051 F: drivers/mfd/mp2629.c 14054 14052 F: drivers/power/supply/mp2629_charger.c ··· 15485 15481 F: include/linux/mtd/onenand*.h 15486 15482 15487 15483 ONEXPLAYER FAN DRIVER 15484 + M: Derek John Clark <derekjohn.clark@gmail.com> 15488 15485 M: Joaquín Ignacio Aramendía <samsagax@gmail.com> 15489 15486 L: linux-hwmon@vger.kernel.org 15490 15487 S: Maintained
+17 -1
drivers/hwmon/Kconfig
··· 714 714 This driver can also be built as a module. If so, the module 715 715 will be called gpio-fan. 716 716 717 + config SENSORS_GXP_FAN_CTRL 718 + tristate "HPE GXP fan controller" 719 + depends on ARCH_HPE_GXP || COMPILE_TEST 720 + help 721 + If you say yes here you get support for GXP fan control functionality. 722 + 723 + The GXP controls fan function via the CPLD through the use of PWM 724 + registers. This driver reports status and pwm setting of the fans. 725 + 717 726 config SENSORS_HIH6130 718 727 tristate "Honeywell Humidicon HIH-6130 humidity/temperature sensor" 719 728 depends on I2C ··· 1175 1166 This driver can also be built as a module. If so, the module 1176 1167 will be called max31790. 1177 1168 1169 + config SENSORS_MC34VR500 1170 + tristate "NXP MC34VR500 hardware monitoring driver" 1171 + depends on I2C 1172 + help 1173 + If you say yes here you get support for the temperature and input 1174 + voltage sensors of the NXP MC34VR500. 1175 + 1178 1176 config SENSORS_MCP3021 1179 1177 tristate "Microchip MCP3021 and compatibles" 1180 1178 depends on I2C ··· 1532 1516 config SENSORS_NCT6775 1533 1517 tristate "Platform driver for Nuvoton NCT6775F and compatibles" 1534 1518 depends on !PPC 1535 - depends on ACPI_WMI || ACPI_WMI=n 1519 + depends on ACPI || ACPI=n 1536 1520 select HWMON_VID 1537 1521 select SENSORS_NCT6775_CORE 1538 1522 help
+2
drivers/hwmon/Makefile
··· 83 83 obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o 84 84 obj-$(CONFIG_SENSORS_GSC) += gsc-hwmon.o 85 85 obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o 86 + obj-$(CONFIG_SENSORS_GXP_FAN_CTRL) += gxp-fan-ctrl.o 86 87 obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o 87 88 obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o 88 89 obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o ··· 150 149 obj-$(CONFIG_SENSORS_MAX6697) += max6697.o 151 150 obj-$(CONFIG_SENSORS_MAX31790) += max31790.o 152 151 obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o 152 + obj-$(CONFIG_SENSORS_MC34VR500) += mc34vr500.o 153 153 obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o 154 154 obj-$(CONFIG_SENSORS_TC654) += tc654.o 155 155 obj-$(CONFIG_SENSORS_TPS23861) += tps23861.o
+1 -2
drivers/hwmon/aht10.c
··· 79 79 80 80 /** 81 81 * aht10_init() - Initialize an AHT10 chip 82 - * @client: the i2c client associated with the AHT10 83 82 * @data: the data associated with this AHT10 chip 84 83 * Return: 0 if succesfull, 1 if not 85 84 */ ··· 123 124 124 125 /** 125 126 * aht10_read_values() - read and parse the raw data from the AHT10 126 - * @aht10_data: the struct aht10_data to use for the lock 127 + * @data: the struct aht10_data to use for the lock 127 128 * Return: 0 if succesfull, 1 if not 128 129 */ 129 130 static int aht10_read_values(struct aht10_data *data)
+399 -45
drivers/hwmon/aquacomputer_d5next.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0+ 2 2 /* 3 3 * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo, 4 - * Quadro, High Flow Next) 4 + * Quadro, High Flow Next, Aquaero, Aquastream Ultimate) 5 5 * 6 6 * Aquacomputer devices send HID reports (with ID 0x01) every second to report 7 - * sensor values. 7 + * sensor values, except for devices that communicate through the 8 + * legacy way (currently, Poweradjust 3). 8 9 * 9 10 * Copyright 2021 Aleksa Savic <savicaleksa83@gmail.com> 10 11 * Copyright 2022 Jack Doan <me@jackdoan.com> ··· 22 21 #include <asm/unaligned.h> 23 22 24 23 #define USB_VENDOR_ID_AQUACOMPUTER 0x0c70 24 + #define USB_PRODUCT_ID_AQUAERO 0xf001 25 25 #define USB_PRODUCT_ID_FARBWERK 0xf00a 26 26 #define USB_PRODUCT_ID_QUADRO 0xf00d 27 27 #define USB_PRODUCT_ID_D5NEXT 0xf00e 28 28 #define USB_PRODUCT_ID_FARBWERK360 0xf010 29 29 #define USB_PRODUCT_ID_OCTO 0xf011 30 30 #define USB_PRODUCT_ID_HIGHFLOWNEXT 0xf012 31 + #define USB_PRODUCT_ID_AQUASTREAMULT 0xf00b 32 + #define USB_PRODUCT_ID_POWERADJUST3 0xf0bd 31 33 32 - enum kinds { d5next, farbwerk, farbwerk360, octo, quadro, highflownext }; 34 + enum kinds { 35 + d5next, farbwerk, farbwerk360, octo, quadro, 36 + highflownext, aquaero, poweradjust3, aquastreamult 37 + }; 33 38 34 39 static const char *const aqc_device_names[] = { 35 40 [d5next] = "d5next", ··· 43 36 [farbwerk360] = "farbwerk360", 44 37 [octo] = "octo", 45 38 [quadro] = "quadro", 46 - [highflownext] = "highflownext" 39 + [highflownext] = "highflownext", 40 + [aquaero] = "aquaero", 41 + [aquastreamult] = "aquastreamultimate", 42 + [poweradjust3] = "poweradjust3" 47 43 }; 48 44 49 45 #define DRIVER_NAME "aquacomputer_d5next" 50 46 51 47 #define STATUS_REPORT_ID 0x01 52 48 #define STATUS_UPDATE_INTERVAL (2 * HZ) /* In seconds */ 53 - #define SERIAL_FIRST_PART 3 54 - #define SERIAL_SECOND_PART 5 55 - #define FIRMWARE_VERSION 13 49 + #define SERIAL_PART_OFFSET 2 56 50 57 51 #define CTRL_REPORT_ID 0x03 58 52 ··· 67 59 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0xC6 68 60 }; 69 61 70 - /* Sensor sizes and offsets for all Aquacomputer devices */ 71 - #define AQC_TEMP_SENSOR_SIZE 0x02 62 + /* Report IDs for legacy devices */ 63 + #define POWERADJUST3_STATUS_REPORT_ID 0x03 64 + 65 + /* Info, sensor sizes and offsets for most Aquacomputer devices */ 66 + #define AQC_SERIAL_START 0x3 67 + #define AQC_FIRMWARE_VERSION 0xD 68 + 69 + #define AQC_SENSOR_SIZE 0x02 72 70 #define AQC_TEMP_SENSOR_DISCONNECTED 0x7FFF 73 71 #define AQC_FAN_PERCENT_OFFSET 0x00 74 72 #define AQC_FAN_VOLTAGE_OFFSET 0x02 75 73 #define AQC_FAN_CURRENT_OFFSET 0x04 76 74 #define AQC_FAN_POWER_OFFSET 0x06 77 75 #define AQC_FAN_SPEED_OFFSET 0x08 76 + 77 + /* Specs of the Aquaero fan controllers */ 78 + #define AQUAERO_SERIAL_START 0x07 79 + #define AQUAERO_FIRMWARE_VERSION 0x0B 80 + #define AQUAERO_NUM_FANS 4 81 + #define AQUAERO_NUM_SENSORS 8 82 + #define AQUAERO_NUM_VIRTUAL_SENSORS 8 83 + #define AQUAERO_NUM_CALC_VIRTUAL_SENSORS 4 84 + #define AQUAERO_NUM_FLOW_SENSORS 2 85 + 86 + /* Sensor report offsets for Aquaero fan controllers */ 87 + #define AQUAERO_SENSOR_START 0x65 88 + #define AQUAERO_VIRTUAL_SENSOR_START 0x85 89 + #define AQUAERO_CALC_VIRTUAL_SENSOR_START 0x95 90 + #define AQUAERO_FLOW_SENSORS_START 0xF9 91 + #define AQUAERO_FAN_VOLTAGE_OFFSET 0x04 92 + #define AQUAERO_FAN_CURRENT_OFFSET 0x06 93 + #define AQUAERO_FAN_POWER_OFFSET 0x08 94 + #define AQUAERO_FAN_SPEED_OFFSET 0x00 95 + static u16 aquaero_sensor_fan_offsets[] = { 0x167, 0x173, 0x17f, 0x18B }; 78 96 79 97 /* Specs of the D5 Next pump */ 80 98 #define D5NEXT_NUM_FANS 2 ··· 116 82 #define D5NEXT_5V_VOLTAGE 0x39 117 83 #define D5NEXT_12V_VOLTAGE 0x37 118 84 #define D5NEXT_VIRTUAL_SENSORS_START 0x3f 119 - static u8 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET }; 85 + static u16 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET }; 120 86 121 87 /* Control report offsets for the D5 Next pump */ 122 88 #define D5NEXT_TEMP_CTRL_OFFSET 0x2D /* Temperature sensor offsets location */ 123 89 static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; /* Pump and fan speed (from 0-100%) */ 90 + 91 + /* Specs of the Aquastream Ultimate pump */ 92 + /* Pump does not follow the standard structure, so only consider the fan */ 93 + #define AQUASTREAMULT_NUM_FANS 1 94 + #define AQUASTREAMULT_NUM_SENSORS 2 95 + 96 + /* Sensor report offsets for the Aquastream Ultimate pump */ 97 + #define AQUASTREAMULT_SENSOR_START 0x2D 98 + #define AQUASTREAMULT_PUMP_OFFSET 0x51 99 + #define AQUASTREAMULT_PUMP_VOLTAGE 0x3D 100 + #define AQUASTREAMULT_PUMP_CURRENT 0x53 101 + #define AQUASTREAMULT_PUMP_POWER 0x55 102 + #define AQUASTREAMULT_FAN_OFFSET 0x41 103 + #define AQUASTREAMULT_PRESSURE_OFFSET 0x57 104 + #define AQUASTREAMULT_FLOW_SENSOR_OFFSET 0x37 105 + #define AQUASTREAMULT_FAN_VOLTAGE_OFFSET 0x02 106 + #define AQUASTREAMULT_FAN_CURRENT_OFFSET 0x00 107 + #define AQUASTREAMULT_FAN_POWER_OFFSET 0x04 108 + #define AQUASTREAMULT_FAN_SPEED_OFFSET 0x06 109 + static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET }; 124 110 125 111 /* Spec and sensor report offset for the Farbwerk RGB controller */ 126 112 #define FARBWERK_NUM_SENSORS 4 ··· 168 114 #define OCTO_POWER_CYCLES 0x18 169 115 #define OCTO_SENSOR_START 0x3D 170 116 #define OCTO_VIRTUAL_SENSORS_START 0x45 171 - static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 }; 117 + static u16 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 }; 172 118 173 119 /* Control report offsets for the Octo */ 174 120 #define OCTO_TEMP_CTRL_OFFSET 0xA ··· 179 125 #define QUADRO_NUM_FANS 4 180 126 #define QUADRO_NUM_SENSORS 4 181 127 #define QUADRO_NUM_VIRTUAL_SENSORS 16 128 + #define QUADRO_NUM_FLOW_SENSORS 1 182 129 #define QUADRO_CTRL_REPORT_SIZE 0x3c1 183 130 184 131 /* Sensor report offsets for the Quadro */ ··· 187 132 #define QUADRO_SENSOR_START 0x34 188 133 #define QUADRO_VIRTUAL_SENSORS_START 0x3c 189 134 #define QUADRO_FLOW_SENSOR_OFFSET 0x6e 190 - static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 }; 135 + static u16 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 }; 191 136 192 137 /* Control report offsets for the Quadro */ 193 138 #define QUADRO_TEMP_CTRL_OFFSET 0xA ··· 196 141 197 142 /* Specs of High Flow Next flow sensor */ 198 143 #define HIGHFLOWNEXT_NUM_SENSORS 2 144 + #define HIGHFLOWNEXT_NUM_FLOW_SENSORS 1 199 145 200 146 /* Sensor report offsets for the High Flow Next */ 201 147 #define HIGHFLOWNEXT_SENSOR_START 85 ··· 206 150 #define HIGHFLOWNEXT_CONDUCTIVITY 95 207 151 #define HIGHFLOWNEXT_5V_VOLTAGE 97 208 152 #define HIGHFLOWNEXT_5V_VOLTAGE_USB 99 153 + 154 + /* Specs of the Poweradjust 3 */ 155 + #define POWERADJUST3_NUM_SENSORS 1 156 + #define POWERADJUST3_SENSOR_REPORT_SIZE 0x32 157 + 158 + /* Sensor report offsets for the Poweradjust 3 */ 159 + #define POWERADJUST3_SENSOR_START 0x03 209 160 210 161 /* Labels for D5 Next */ 211 162 static const char *const label_d5next_temp[] = { ··· 241 178 "Fan current" 242 179 }; 243 180 244 - /* Labels for Farbwerk, Farbwerk 360 and Octo and Quadro temperature sensors */ 181 + /* Labels for Aquaero, Farbwerk, Farbwerk 360 and Octo and Quadro temperature sensors */ 245 182 static const char *const label_temp_sensors[] = { 246 183 "Sensor 1", 247 184 "Sensor 2", 248 185 "Sensor 3", 249 - "Sensor 4" 186 + "Sensor 4", 187 + "Sensor 5", 188 + "Sensor 6", 189 + "Sensor 7", 190 + "Sensor 8" 250 191 }; 251 192 252 193 static const char *const label_virtual_temp_sensors[] = { ··· 270 203 "Virtual sensor 14", 271 204 "Virtual sensor 15", 272 205 "Virtual sensor 16", 206 + }; 207 + 208 + static const char *const label_aquaero_calc_temp_sensors[] = { 209 + "Calc. virtual sensor 1", 210 + "Calc. virtual sensor 2", 211 + "Calc. virtual sensor 3", 212 + "Calc. virtual sensor 4" 273 213 }; 274 214 275 215 /* Labels for Octo and Quadro (except speed) */ ··· 333 259 "Flow speed [dL/h]" 334 260 }; 335 261 262 + /* Labels for Aquaero fan speeds */ 263 + static const char *const label_aquaero_speeds[] = { 264 + "Fan 1 speed", 265 + "Fan 2 speed", 266 + "Fan 3 speed", 267 + "Fan 4 speed", 268 + "Flow sensor 1 [dL/h]", 269 + "Flow sensor 2 [dL/h]" 270 + }; 271 + 336 272 /* Labels for High Flow Next */ 337 273 static const char *const label_highflownext_temp_sensors[] = { 338 274 "Coolant temp", ··· 364 280 "+5V USB voltage" 365 281 }; 366 282 283 + /* Labels for Aquastream Ultimate */ 284 + static const char *const label_aquastreamult_temp[] = { 285 + "Coolant temp", 286 + "External temp" 287 + }; 288 + 289 + static const char *const label_aquastreamult_speeds[] = { 290 + "Fan speed", 291 + "Pump speed", 292 + "Pressure [mbar]", 293 + "Flow speed [dL/h]" 294 + }; 295 + 296 + static const char *const label_aquastreamult_power[] = { 297 + "Fan power", 298 + "Pump power" 299 + }; 300 + 301 + static const char *const label_aquastreamult_voltages[] = { 302 + "Fan voltage", 303 + "Pump voltage" 304 + }; 305 + 306 + static const char *const label_aquastreamult_current[] = { 307 + "Fan current", 308 + "Pump current" 309 + }; 310 + 311 + /* Labels for Poweradjust 3 */ 312 + static const char *const label_poweradjust3_temp_sensors[] = { 313 + "External sensor" 314 + }; 315 + 316 + struct aqc_fan_structure_offsets { 317 + u8 voltage; 318 + u8 curr; 319 + u8 power; 320 + u8 speed; 321 + }; 322 + 323 + /* Fan structure offsets for Aquaero */ 324 + static struct aqc_fan_structure_offsets aqc_aquaero_fan_structure = { 325 + .voltage = AQUAERO_FAN_VOLTAGE_OFFSET, 326 + .curr = AQUAERO_FAN_CURRENT_OFFSET, 327 + .power = AQUAERO_FAN_POWER_OFFSET, 328 + .speed = AQUAERO_FAN_SPEED_OFFSET 329 + }; 330 + 331 + /* Fan structure offsets for Aquastream Ultimate */ 332 + static struct aqc_fan_structure_offsets aqc_aquastreamult_fan_structure = { 333 + .voltage = AQUASTREAMULT_FAN_VOLTAGE_OFFSET, 334 + .curr = AQUASTREAMULT_FAN_CURRENT_OFFSET, 335 + .power = AQUASTREAMULT_FAN_POWER_OFFSET, 336 + .speed = AQUASTREAMULT_FAN_SPEED_OFFSET 337 + }; 338 + 339 + /* Fan structure offsets for all devices except those above */ 340 + static struct aqc_fan_structure_offsets aqc_general_fan_structure = { 341 + .voltage = AQC_FAN_VOLTAGE_OFFSET, 342 + .curr = AQC_FAN_CURRENT_OFFSET, 343 + .power = AQC_FAN_POWER_OFFSET, 344 + .speed = AQC_FAN_SPEED_OFFSET 345 + }; 346 + 367 347 struct aqc_data { 368 348 struct hid_device *hdev; 369 349 struct device *hwmon_dev; ··· 436 288 enum kinds kind; 437 289 const char *name; 438 290 291 + int status_report_id; /* Used for legacy devices, report is stored in buffer */ 292 + 439 293 int buffer_size; 440 294 u8 *buffer; 441 295 int checksum_start; ··· 445 295 int checksum_offset; 446 296 447 297 int num_fans; 448 - u8 *fan_sensor_offsets; 298 + u16 *fan_sensor_offsets; 449 299 u16 *fan_ctrl_offsets; 450 300 int num_temp_sensors; 451 301 int temp_sensor_start_offset; 452 302 int num_virtual_temp_sensors; 453 303 int virtual_temp_sensor_start_offset; 304 + int num_calc_virt_temp_sensors; 305 + int calc_virt_temp_sensor_start_offset; 454 306 u16 temp_ctrl_offset; 455 307 u16 power_cycle_count_offset; 456 - u8 flow_sensor_offset; 308 + int num_flow_sensors; 309 + u8 flow_sensors_start_offset; 457 310 u8 flow_pulses_ctrl_offset; 311 + struct aqc_fan_structure_offsets *fan_structure; 458 312 459 313 /* General info, same across all devices */ 314 + u8 serial_number_start_offset; 460 315 u32 serial_number[2]; 316 + u8 firmware_version_offset; 461 317 u16 firmware_version; 462 318 463 319 /* How many times the device was powered on, if available */ 464 320 u32 power_cycles; 465 321 466 322 /* Sensor values */ 467 - s32 temp_input[20]; /* Max 4 physical and 16 virtual */ 323 + s32 temp_input[20]; /* Max 4 physical and 16 virtual or 8 physical and 12 virtual */ 468 324 u16 speed_input[8]; 469 325 u32 power_input[8]; 470 326 u16 voltage_input[8]; ··· 479 323 /* Label values */ 480 324 const char *const *temp_label; 481 325 const char *const *virtual_temp_label; 326 + const char *const *calc_virt_temp_label; /* For Aquaero */ 482 327 const char *const *speed_label; 483 328 const char *const *power_label; 484 329 const char *const *voltage_label; ··· 600 443 } 601 444 } 602 445 603 - if (channel < priv->num_temp_sensors + priv->num_virtual_temp_sensors) 446 + if (channel < 447 + priv->num_temp_sensors + priv->num_virtual_temp_sensors + 448 + priv->num_calc_virt_temp_sensors) 604 449 switch (attr) { 605 450 case hwmon_temp_label: 606 451 case hwmon_temp_input: ··· 626 467 case hwmon_fan_input: 627 468 case hwmon_fan_label: 628 469 switch (priv->kind) { 470 + case aquastreamult: 471 + /* 472 + * Special case to support pump RPM, fan RPM, 473 + * pressure and flow sensor 474 + */ 475 + if (channel < 4) 476 + return 0444; 477 + break; 629 478 case highflownext: 630 479 /* Special case to support flow sensor, water quality 631 480 * and conductivity ··· 641 474 if (channel < 3) 642 475 return 0444; 643 476 break; 477 + case aquaero: 644 478 case quadro: 645 - /* Special case to support flow sensor */ 646 - if (channel < priv->num_fans + 1) 479 + /* Special case to support flow sensors */ 480 + if (channel < priv->num_fans + priv->num_flow_sensors) 647 481 return 0444; 648 482 break; 649 483 default: ··· 664 496 break; 665 497 case hwmon_power: 666 498 switch (priv->kind) { 499 + case aquastreamult: 500 + /* Special case to support pump and fan power */ 501 + if (channel < 2) 502 + return 0444; 503 + break; 667 504 case highflownext: 668 505 /* Special case to support one power sensor */ 669 506 if (channel == 0) ··· 681 508 } 682 509 break; 683 510 case hwmon_curr: 684 - if (channel < priv->num_fans) 685 - return 0444; 511 + switch (priv->kind) { 512 + case aquastreamult: 513 + /* Special case to support pump and fan current */ 514 + if (channel < 2) 515 + return 0444; 516 + break; 517 + default: 518 + if (channel < priv->num_fans) 519 + return 0444; 520 + break; 521 + } 686 522 break; 687 523 case hwmon_in: 688 524 switch (priv->kind) { ··· 700 518 if (channel < priv->num_fans + 2) 701 519 return 0444; 702 520 break; 521 + case aquastreamult: 703 522 case highflownext: 704 523 /* Special case to support two voltage sensors */ 705 524 if (channel < 2) ··· 719 536 return 0; 720 537 } 721 538 539 + /* Read device sensors by manually requesting the sensor report (legacy way) */ 540 + static int aqc_legacy_read(struct aqc_data *priv) 541 + { 542 + int ret, i, sensor_value; 543 + 544 + mutex_lock(&priv->mutex); 545 + 546 + memset(priv->buffer, 0x00, priv->buffer_size); 547 + ret = hid_hw_raw_request(priv->hdev, priv->status_report_id, priv->buffer, 548 + priv->buffer_size, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 549 + if (ret < 0) 550 + goto unlock_and_return; 551 + 552 + /* Temperature sensor readings */ 553 + for (i = 0; i < priv->num_temp_sensors; i++) { 554 + sensor_value = get_unaligned_le16(priv->buffer + priv->temp_sensor_start_offset + 555 + i * AQC_SENSOR_SIZE); 556 + priv->temp_input[i] = sensor_value * 10; 557 + } 558 + 559 + priv->updated = jiffies; 560 + 561 + unlock_and_return: 562 + mutex_unlock(&priv->mutex); 563 + return ret; 564 + } 565 + 722 566 static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, 723 567 int channel, long *val) 724 568 { 725 569 int ret; 726 570 struct aqc_data *priv = dev_get_drvdata(dev); 727 571 728 - if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL)) 729 - return -ENODATA; 572 + if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL)) { 573 + if (priv->status_report_id != 0) { 574 + /* Legacy devices require manual reads */ 575 + ret = aqc_legacy_read(priv); 576 + if (ret < 0) 577 + return -ENODATA; 578 + } else { 579 + return -ENODATA; 580 + } 581 + } 730 582 731 583 switch (type) { 732 584 case hwmon_temp: ··· 775 557 case hwmon_temp_offset: 776 558 ret = 777 559 aqc_get_ctrl_val(priv, priv->temp_ctrl_offset + 778 - channel * AQC_TEMP_SENSOR_SIZE, val); 560 + channel * AQC_SENSOR_SIZE, val); 779 561 if (ret < 0) 780 562 return ret; 781 563 ··· 829 611 { 830 612 struct aqc_data *priv = dev_get_drvdata(dev); 831 613 614 + /* Number of sensors that are not calculated */ 615 + int num_non_calc_sensors = priv->num_temp_sensors + priv->num_virtual_temp_sensors; 616 + 832 617 switch (type) { 833 618 case hwmon_temp: 834 - if (channel < priv->num_temp_sensors) 619 + if (channel < priv->num_temp_sensors) { 835 620 *str = priv->temp_label[channel]; 836 - else 837 - *str = priv->virtual_temp_label[channel - priv->num_temp_sensors]; 621 + } else { 622 + if (priv->kind == aquaero && channel >= num_non_calc_sensors) 623 + *str = 624 + priv->calc_virt_temp_label[channel - num_non_calc_sensors]; 625 + else 626 + *str = priv->virtual_temp_label[channel - priv->num_temp_sensors]; 627 + } 838 628 break; 839 629 case hwmon_fan: 840 630 *str = priv->speed_label[channel]; ··· 877 651 val = clamp_val(val, -15000, 15000) / 10; 878 652 ret = 879 653 aqc_set_ctrl_val(priv, priv->temp_ctrl_offset + 880 - channel * AQC_TEMP_SENSOR_SIZE, val); 654 + channel * AQC_SENSOR_SIZE, val); 881 655 if (ret < 0) 882 656 return ret; 883 657 break; ··· 1015 789 priv = hid_get_drvdata(hdev); 1016 790 1017 791 /* Info provided with every report */ 1018 - priv->serial_number[0] = get_unaligned_be16(data + SERIAL_FIRST_PART); 1019 - priv->serial_number[1] = get_unaligned_be16(data + SERIAL_SECOND_PART); 1020 - priv->firmware_version = get_unaligned_be16(data + FIRMWARE_VERSION); 792 + priv->serial_number[0] = get_unaligned_be16(data + priv->serial_number_start_offset); 793 + priv->serial_number[1] = get_unaligned_be16(data + priv->serial_number_start_offset + 794 + SERIAL_PART_OFFSET); 795 + priv->firmware_version = get_unaligned_be16(data + priv->firmware_version_offset); 1021 796 1022 797 /* Physical temperature sensor readings */ 1023 798 for (i = 0; i < priv->num_temp_sensors; i++) { 1024 799 sensor_value = get_unaligned_be16(data + 1025 800 priv->temp_sensor_start_offset + 1026 - i * AQC_TEMP_SENSOR_SIZE); 801 + i * AQC_SENSOR_SIZE); 1027 802 if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED) 1028 803 priv->temp_input[i] = -ENODATA; 1029 804 else ··· 1035 808 for (j = 0; j < priv->num_virtual_temp_sensors; j++) { 1036 809 sensor_value = get_unaligned_be16(data + 1037 810 priv->virtual_temp_sensor_start_offset + 1038 - j * AQC_TEMP_SENSOR_SIZE); 811 + j * AQC_SENSOR_SIZE); 1039 812 if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED) 1040 813 priv->temp_input[i] = -ENODATA; 1041 814 else ··· 1046 819 /* Fan speed and related readings */ 1047 820 for (i = 0; i < priv->num_fans; i++) { 1048 821 priv->speed_input[i] = 1049 - get_unaligned_be16(data + priv->fan_sensor_offsets[i] + AQC_FAN_SPEED_OFFSET); 822 + get_unaligned_be16(data + priv->fan_sensor_offsets[i] + 823 + priv->fan_structure->speed); 1050 824 priv->power_input[i] = 1051 825 get_unaligned_be16(data + priv->fan_sensor_offsets[i] + 1052 - AQC_FAN_POWER_OFFSET) * 10000; 826 + priv->fan_structure->power) * 10000; 1053 827 priv->voltage_input[i] = 1054 828 get_unaligned_be16(data + priv->fan_sensor_offsets[i] + 1055 - AQC_FAN_VOLTAGE_OFFSET) * 10; 829 + priv->fan_structure->voltage) * 10; 1056 830 priv->current_input[i] = 1057 - get_unaligned_be16(data + priv->fan_sensor_offsets[i] + AQC_FAN_CURRENT_OFFSET); 831 + get_unaligned_be16(data + priv->fan_sensor_offsets[i] + 832 + priv->fan_structure->curr); 833 + } 834 + 835 + /* Flow sensor readings */ 836 + for (j = 0; j < priv->num_flow_sensors; j++) { 837 + priv->speed_input[i] = get_unaligned_be16(data + priv->flow_sensors_start_offset + 838 + j * AQC_SENSOR_SIZE); 839 + i++; 1058 840 } 1059 841 1060 842 if (priv->power_cycle_count_offset != 0) ··· 1071 835 1072 836 /* Special-case sensor readings */ 1073 837 switch (priv->kind) { 838 + case aquaero: 839 + /* Read calculated virtual temp sensors */ 840 + i = priv->num_temp_sensors + priv->num_virtual_temp_sensors; 841 + for (j = 0; j < priv->num_calc_virt_temp_sensors; j++) { 842 + sensor_value = get_unaligned_be16(data + 843 + priv->calc_virt_temp_sensor_start_offset + 844 + j * AQC_SENSOR_SIZE); 845 + if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED) 846 + priv->temp_input[i] = -ENODATA; 847 + else 848 + priv->temp_input[i] = sensor_value * 10; 849 + i++; 850 + } 851 + break; 852 + case aquastreamult: 853 + priv->speed_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_OFFSET); 854 + priv->speed_input[2] = get_unaligned_be16(data + AQUASTREAMULT_PRESSURE_OFFSET); 855 + priv->speed_input[3] = get_unaligned_be16(data + AQUASTREAMULT_FLOW_SENSOR_OFFSET); 856 + 857 + priv->power_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_POWER) * 10000; 858 + 859 + priv->voltage_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_VOLTAGE) * 10; 860 + 861 + priv->current_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_CURRENT); 862 + break; 1074 863 case d5next: 1075 864 priv->voltage_input[2] = get_unaligned_be16(data + D5NEXT_5V_VOLTAGE) * 10; 1076 865 priv->voltage_input[3] = get_unaligned_be16(data + D5NEXT_12V_VOLTAGE) * 10; 1077 - break; 1078 - case quadro: 1079 - priv->speed_input[4] = get_unaligned_be16(data + priv->flow_sensor_offset); 1080 866 break; 1081 867 case highflownext: 1082 868 /* If external temp sensor is not connected, its power reading is also N/A */ ··· 1112 854 priv->voltage_input[1] = 1113 855 get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE_USB) * 10; 1114 856 1115 - priv->speed_input[0] = get_unaligned_be16(data + HIGHFLOWNEXT_FLOW); 1116 857 priv->speed_input[1] = get_unaligned_be16(data + HIGHFLOWNEXT_WATER_QUALITY); 1117 858 priv->speed_input[2] = get_unaligned_be16(data + HIGHFLOWNEXT_CONDUCTIVITY); 1118 859 break; ··· 1164 907 dev_name(&priv->hdev->dev)); 1165 908 1166 909 priv->debugfs = debugfs_create_dir(name, NULL); 1167 - debugfs_create_file("serial_number", 0444, priv->debugfs, priv, &serial_number_fops); 1168 - debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops); 1169 910 911 + if (priv->serial_number_start_offset != 0) 912 + debugfs_create_file("serial_number", 0444, priv->debugfs, priv, 913 + &serial_number_fops); 914 + if (priv->firmware_version_offset != 0) 915 + debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, 916 + &firmware_version_fops); 1170 917 if (priv->power_cycle_count_offset != 0) 1171 918 debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops); 1172 919 } ··· 1210 949 goto fail_and_stop; 1211 950 1212 951 switch (hdev->product) { 952 + case USB_PRODUCT_ID_AQUAERO: 953 + /* 954 + * Aquaero presents itself as three HID devices under the same product ID: 955 + * "aquaero keyboard/mouse", "aquaero System Control" and "aquaero Device", 956 + * which is the one we want to communicate with. Unlike most other Aquacomputer 957 + * devices, Aquaero does not return meaningful data when explicitly requested 958 + * using GET_FEATURE_REPORT. 959 + * 960 + * The difference between "aquaero Device" and the other two is in the collections 961 + * they present. The two other devices have the type of the second element in 962 + * their respective collections set to 1, while the real device has it set to 0. 963 + */ 964 + if (hdev->collection[1].type != 0) { 965 + ret = -ENODEV; 966 + goto fail_and_close; 967 + } 968 + 969 + priv->kind = aquaero; 970 + 971 + priv->num_fans = AQUAERO_NUM_FANS; 972 + priv->fan_sensor_offsets = aquaero_sensor_fan_offsets; 973 + 974 + priv->num_temp_sensors = AQUAERO_NUM_SENSORS; 975 + priv->temp_sensor_start_offset = AQUAERO_SENSOR_START; 976 + priv->num_virtual_temp_sensors = AQUAERO_NUM_VIRTUAL_SENSORS; 977 + priv->virtual_temp_sensor_start_offset = AQUAERO_VIRTUAL_SENSOR_START; 978 + priv->num_calc_virt_temp_sensors = AQUAERO_NUM_CALC_VIRTUAL_SENSORS; 979 + priv->calc_virt_temp_sensor_start_offset = AQUAERO_CALC_VIRTUAL_SENSOR_START; 980 + priv->num_flow_sensors = AQUAERO_NUM_FLOW_SENSORS; 981 + priv->flow_sensors_start_offset = AQUAERO_FLOW_SENSORS_START; 982 + 983 + priv->temp_label = label_temp_sensors; 984 + priv->virtual_temp_label = label_virtual_temp_sensors; 985 + priv->calc_virt_temp_label = label_aquaero_calc_temp_sensors; 986 + priv->speed_label = label_aquaero_speeds; 987 + priv->power_label = label_fan_power; 988 + priv->voltage_label = label_fan_voltage; 989 + priv->current_label = label_fan_current; 990 + break; 1213 991 case USB_PRODUCT_ID_D5NEXT: 1214 992 priv->kind = d5next; 1215 993 ··· 1334 1034 priv->temp_sensor_start_offset = QUADRO_SENSOR_START; 1335 1035 priv->num_virtual_temp_sensors = QUADRO_NUM_VIRTUAL_SENSORS; 1336 1036 priv->virtual_temp_sensor_start_offset = QUADRO_VIRTUAL_SENSORS_START; 1037 + priv->num_flow_sensors = QUADRO_NUM_FLOW_SENSORS; 1038 + priv->flow_sensors_start_offset = QUADRO_FLOW_SENSOR_OFFSET; 1039 + 1337 1040 priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET; 1338 1041 1339 1042 priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; 1340 1043 1341 - priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET; 1342 1044 priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET; 1343 1045 priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; 1344 1046 ··· 1358 1056 1359 1057 priv->num_temp_sensors = HIGHFLOWNEXT_NUM_SENSORS; 1360 1058 priv->temp_sensor_start_offset = HIGHFLOWNEXT_SENSOR_START; 1059 + priv->num_flow_sensors = HIGHFLOWNEXT_NUM_FLOW_SENSORS; 1060 + priv->flow_sensors_start_offset = HIGHFLOWNEXT_FLOW; 1361 1061 1362 1062 priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; 1363 1063 ··· 1368 1064 priv->power_label = label_highflownext_power; 1369 1065 priv->voltage_label = label_highflownext_voltage; 1370 1066 break; 1067 + case USB_PRODUCT_ID_AQUASTREAMULT: 1068 + priv->kind = aquastreamult; 1069 + 1070 + priv->num_fans = AQUASTREAMULT_NUM_FANS; 1071 + priv->fan_sensor_offsets = aquastreamult_sensor_fan_offsets; 1072 + 1073 + priv->num_temp_sensors = AQUASTREAMULT_NUM_SENSORS; 1074 + priv->temp_sensor_start_offset = AQUASTREAMULT_SENSOR_START; 1075 + 1076 + priv->temp_label = label_aquastreamult_temp; 1077 + priv->speed_label = label_aquastreamult_speeds; 1078 + priv->power_label = label_aquastreamult_power; 1079 + priv->voltage_label = label_aquastreamult_voltages; 1080 + priv->current_label = label_aquastreamult_current; 1081 + break; 1082 + case USB_PRODUCT_ID_POWERADJUST3: 1083 + priv->kind = poweradjust3; 1084 + 1085 + priv->num_fans = 0; 1086 + 1087 + priv->num_temp_sensors = POWERADJUST3_NUM_SENSORS; 1088 + priv->temp_sensor_start_offset = POWERADJUST3_SENSOR_START; 1089 + priv->buffer_size = POWERADJUST3_SENSOR_REPORT_SIZE; 1090 + 1091 + priv->temp_label = label_poweradjust3_temp_sensors; 1092 + break; 1371 1093 default: 1094 + break; 1095 + } 1096 + 1097 + switch (priv->kind) { 1098 + case aquaero: 1099 + priv->serial_number_start_offset = AQUAERO_SERIAL_START; 1100 + priv->firmware_version_offset = AQUAERO_FIRMWARE_VERSION; 1101 + 1102 + priv->fan_structure = &aqc_aquaero_fan_structure; 1103 + break; 1104 + case poweradjust3: 1105 + priv->status_report_id = POWERADJUST3_STATUS_REPORT_ID; 1106 + break; 1107 + default: 1108 + priv->serial_number_start_offset = AQC_SERIAL_START; 1109 + priv->firmware_version_offset = AQC_FIRMWARE_VERSION; 1110 + 1111 + if (priv->kind == aquastreamult) 1112 + priv->fan_structure = &aqc_aquastreamult_fan_structure; 1113 + else 1114 + priv->fan_structure = &aqc_general_fan_structure; 1372 1115 break; 1373 1116 } 1374 1117 ··· 1466 1115 } 1467 1116 1468 1117 static const struct hid_device_id aqc_table[] = { 1118 + { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUAERO) }, 1469 1119 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_D5NEXT) }, 1470 1120 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK) }, 1471 1121 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK360) }, 1472 1122 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_OCTO) }, 1473 1123 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_QUADRO) }, 1474 1124 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_HIGHFLOWNEXT) }, 1125 + { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUASTREAMULT) }, 1126 + { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_POWERADJUST3) }, 1475 1127 { } 1476 1128 }; 1477 1129
+3
drivers/hwmon/asus-ec-sensors.c
··· 299 299 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 300 300 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 301 301 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 302 + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 302 303 .family = family_amd_500_series, 303 304 }; 304 305 ··· 466 465 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4", 467 466 &board_info_strix_z690_a_gaming_wifi_d4), 468 467 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME", 468 + &board_info_zenith_ii_extreme), 469 + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME ALPHA", 469 470 &board_info_zenith_ii_extreme), 470 471 {}, 471 472 };
+65 -73
drivers/hwmon/coretemp.c
··· 27 27 #include <asm/msr.h> 28 28 #include <asm/processor.h> 29 29 #include <asm/cpu_device_id.h> 30 + #include <linux/sched/isolation.h> 30 31 31 32 #define DRVNAME "coretemp" 32 33 ··· 503 502 u32 eax, edx; 504 503 int err, index, attr_no; 505 504 505 + if (!housekeeping_cpu(cpu, HK_TYPE_MISC)) 506 + return 0; 507 + 506 508 /* 507 509 * Find attr number for sysfs: 508 510 * We map the attr number to core id of the CPU ··· 592 588 ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO); 593 589 } 594 590 595 - static int coretemp_probe(struct platform_device *pdev) 591 + static int coretemp_device_add(int zoneid) 596 592 { 597 - struct device *dev = &pdev->dev; 593 + struct platform_device *pdev; 598 594 struct platform_data *pdata; 595 + int err; 599 596 600 597 /* Initialize the per-zone data structures */ 601 - pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL); 598 + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 602 599 if (!pdata) 603 600 return -ENOMEM; 604 601 605 - pdata->pkg_id = pdev->id; 602 + pdata->pkg_id = zoneid; 606 603 ida_init(&pdata->ida); 607 - platform_set_drvdata(pdev, pdata); 608 - 609 - pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME, 610 - pdata, NULL); 611 - return PTR_ERR_OR_ZERO(pdata->hwmon_dev); 612 - } 613 - 614 - static int coretemp_remove(struct platform_device *pdev) 615 - { 616 - struct platform_data *pdata = platform_get_drvdata(pdev); 617 - int i; 618 - 619 - for (i = MAX_CORE_DATA - 1; i >= 0; --i) 620 - if (pdata->core_data[i]) 621 - coretemp_remove_core(pdata, i); 622 - 623 - ida_destroy(&pdata->ida); 624 - return 0; 625 - } 626 - 627 - static struct platform_driver coretemp_driver = { 628 - .driver = { 629 - .name = DRVNAME, 630 - }, 631 - .probe = coretemp_probe, 632 - .remove = coretemp_remove, 633 - }; 634 - 635 - static struct platform_device *coretemp_device_add(unsigned int cpu) 636 - { 637 - int err, zoneid = topology_logical_die_id(cpu); 638 - struct platform_device *pdev; 639 - 640 - if (zoneid < 0) 641 - return ERR_PTR(-ENOMEM); 642 604 643 605 pdev = platform_device_alloc(DRVNAME, zoneid); 644 - if (!pdev) 645 - return ERR_PTR(-ENOMEM); 646 - 647 - err = platform_device_add(pdev); 648 - if (err) { 649 - platform_device_put(pdev); 650 - return ERR_PTR(err); 606 + if (!pdev) { 607 + err = -ENOMEM; 608 + goto err_free_pdata; 651 609 } 652 610 611 + err = platform_device_add(pdev); 612 + if (err) 613 + goto err_put_dev; 614 + 615 + platform_set_drvdata(pdev, pdata); 653 616 zone_devices[zoneid] = pdev; 654 - return pdev; 617 + return 0; 618 + 619 + err_put_dev: 620 + platform_device_put(pdev); 621 + err_free_pdata: 622 + kfree(pdata); 623 + return err; 624 + } 625 + 626 + static void coretemp_device_remove(int zoneid) 627 + { 628 + struct platform_device *pdev = zone_devices[zoneid]; 629 + struct platform_data *pdata = platform_get_drvdata(pdev); 630 + 631 + ida_destroy(&pdata->ida); 632 + kfree(pdata); 633 + platform_device_unregister(pdev); 655 634 } 656 635 657 636 static int coretemp_cpu_online(unsigned int cpu) ··· 658 671 if (!cpu_has(c, X86_FEATURE_DTHERM)) 659 672 return -ENODEV; 660 673 661 - if (!pdev) { 674 + pdata = platform_get_drvdata(pdev); 675 + if (!pdata->hwmon_dev) { 676 + struct device *hwmon; 677 + 662 678 /* Check the microcode version of the CPU */ 663 679 if (chk_ucode_version(cpu)) 664 680 return -EINVAL; ··· 672 682 * online. So, initialize per-pkg data structures and 673 683 * then bring this core online. 674 684 */ 675 - pdev = coretemp_device_add(cpu); 676 - if (IS_ERR(pdev)) 677 - return PTR_ERR(pdev); 685 + hwmon = hwmon_device_register_with_groups(&pdev->dev, DRVNAME, 686 + pdata, NULL); 687 + if (IS_ERR(hwmon)) 688 + return PTR_ERR(hwmon); 689 + pdata->hwmon_dev = hwmon; 678 690 679 691 /* 680 692 * Check whether pkgtemp support is available. ··· 686 694 coretemp_add_core(pdev, cpu, 1); 687 695 } 688 696 689 - pdata = platform_get_drvdata(pdev); 690 697 /* 691 698 * Check whether a thread sibling is already online. If not add the 692 699 * interface for this CPU core. ··· 704 713 struct temp_data *tdata; 705 714 int i, indx = -1, target; 706 715 707 - /* 708 - * Don't execute this on suspend as the device remove locks 709 - * up the machine. 710 - */ 716 + /* No need to tear down any interfaces for suspend */ 711 717 if (cpuhp_tasks_frozen) 712 718 return 0; 713 719 714 720 /* If the physical CPU device does not exist, just return */ 715 - if (!pdev) 716 - return 0; 717 - 718 721 pd = platform_get_drvdata(pdev); 722 + if (!pd->hwmon_dev) 723 + return 0; 719 724 720 725 for (i = 0; i < NUM_REAL_CORES; i++) { 721 726 if (pd->cpu_map[i] == topology_core_id(cpu)) { ··· 743 756 } 744 757 745 758 /* 746 - * If all cores in this pkg are offline, remove the device. This 747 - * will invoke the platform driver remove function, which cleans up 748 - * the rest. 759 + * If all cores in this pkg are offline, remove the interface. 749 760 */ 761 + tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; 750 762 if (cpumask_empty(&pd->cpumask)) { 751 - zone_devices[topology_logical_die_id(cpu)] = NULL; 752 - platform_device_unregister(pdev); 763 + if (tdata) 764 + coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO); 765 + hwmon_device_unregister(pd->hwmon_dev); 766 + pd->hwmon_dev = NULL; 753 767 return 0; 754 768 } 755 769 ··· 758 770 * Check whether this core is the target for the package 759 771 * interface. We need to assign it to some other cpu. 760 772 */ 761 - tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; 762 773 if (tdata && tdata->cpu == cpu) { 763 774 target = cpumask_first(&pd->cpumask); 764 775 mutex_lock(&tdata->update_lock); ··· 776 789 777 790 static int __init coretemp_init(void) 778 791 { 779 - int err; 792 + int i, err; 780 793 781 794 /* 782 795 * CPUID.06H.EAX[0] indicates whether the CPU has thermal ··· 792 805 if (!zone_devices) 793 806 return -ENOMEM; 794 807 795 - err = platform_driver_register(&coretemp_driver); 796 - if (err) 797 - goto outzone; 808 + for (i = 0; i < max_zones; i++) { 809 + err = coretemp_device_add(i); 810 + if (err) 811 + goto outzone; 812 + } 798 813 799 814 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online", 800 815 coretemp_cpu_online, coretemp_cpu_offline); 801 816 if (err < 0) 802 - goto outdrv; 817 + goto outzone; 803 818 coretemp_hp_online = err; 804 819 return 0; 805 820 806 - outdrv: 807 - platform_driver_unregister(&coretemp_driver); 808 821 outzone: 822 + while (i--) 823 + coretemp_device_remove(i); 809 824 kfree(zone_devices); 810 825 return err; 811 826 } ··· 815 826 816 827 static void __exit coretemp_exit(void) 817 828 { 829 + int i; 830 + 818 831 cpuhp_remove_state(coretemp_hp_online); 819 - platform_driver_unregister(&coretemp_driver); 832 + for (i = 0; i < max_zones; i++) 833 + coretemp_device_remove(i); 820 834 kfree(zone_devices); 821 835 } 822 836 module_exit(coretemp_exit)
+13 -11
drivers/hwmon/emc2305.c
··· 59 59 MODULE_DEVICE_TABLE(i2c, emc2305_ids); 60 60 61 61 /** 62 - * @cdev: cooling device; 63 - * @curr_state: cooling current state; 64 - * @last_hwmon_state: last cooling state updated by hwmon subsystem; 65 - * @last_thermal_state: last cooling state updated by thermal subsystem; 62 + * struct emc2305_cdev_data - device-specific cooling device state 63 + * @cdev: cooling device 64 + * @cur_state: cooling current state 65 + * @last_hwmon_state: last cooling state updated by hwmon subsystem 66 + * @last_thermal_state: last cooling state updated by thermal subsystem 66 67 * 67 68 * The 'last_hwmon_state' and 'last_thermal_state' fields are provided to support fan low limit 68 69 * speed feature. The purpose of this feature is to provides ability to limit fan speed ··· 87 86 }; 88 87 89 88 /** 90 - * @client: i2c client; 91 - * @hwmon_dev: hwmon device; 92 - * @max_state: maximum cooling state of the cooling device; 93 - * @pwm_num: number of PWM channels; 94 - * @pwm_separate: separate PWM settings for every channel; 95 - * @pwm_min: array of minimum PWM per channel; 96 - * @cdev_data: array of cooling devices data; 89 + * struct emc2305_data - device-specific data 90 + * @client: i2c client 91 + * @hwmon_dev: hwmon device 92 + * @max_state: maximum cooling state of the cooling device 93 + * @pwm_num: number of PWM channels 94 + * @pwm_separate: separate PWM settings for every channel 95 + * @pwm_min: array of minimum PWM per channel 96 + * @cdev_data: array of cooling devices data 97 97 */ 98 98 struct emc2305_data { 99 99 struct i2c_client *client;
+211 -352
drivers/hwmon/ftsteutates.c
··· 6 6 * Thilo Cestonaro <thilo.cestonaro@ts.fujitsu.com> 7 7 */ 8 8 #include <linux/err.h> 9 - #include <linux/fs.h> 10 9 #include <linux/hwmon.h> 11 - #include <linux/hwmon-sysfs.h> 12 10 #include <linux/i2c.h> 13 11 #include <linux/init.h> 14 12 #include <linux/jiffies.h> 13 + #include <linux/math.h> 15 14 #include <linux/module.h> 16 15 #include <linux/mutex.h> 17 16 #include <linux/slab.h> 18 - #include <linux/sysfs.h> 19 - #include <linux/uaccess.h> 20 17 #include <linux/watchdog.h> 21 18 22 19 #define FTS_DEVICE_ID_REG 0x0000 ··· 44 47 #define FTS_NO_FAN_SENSORS 0x08 45 48 #define FTS_NO_TEMP_SENSORS 0x10 46 49 #define FTS_NO_VOLT_SENSORS 0x04 50 + 51 + #define FTS_FAN_SOURCE_INVALID 0xff 47 52 48 53 static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; 49 54 ··· 186 187 data->fan_source[i] = err; 187 188 } else { 188 189 data->fan_input[i] = 0; 189 - data->fan_source[i] = 0; 190 + data->fan_source[i] = FTS_FAN_SOURCE_INVALID; 190 191 } 191 192 } 192 193 ··· 335 336 /* max timeout 255 minutes. */ 336 337 data->wdd.max_hw_heartbeat_ms = 0xFF * 60 * MSEC_PER_SEC; 337 338 338 - return watchdog_register_device(&data->wdd); 339 + return devm_watchdog_register_device(&data->client->dev, &data->wdd); 339 340 } 340 341 341 - /*****************************************************************************/ 342 - /* SysFS handler functions */ 343 - /*****************************************************************************/ 344 - static ssize_t in_value_show(struct device *dev, 345 - struct device_attribute *devattr, char *buf) 342 + static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, u32 attr, 343 + int channel) 346 344 { 347 - struct fts_data *data = dev_get_drvdata(dev); 348 - int index = to_sensor_dev_attr(devattr)->index; 349 - int err; 345 + switch (type) { 346 + case hwmon_temp: 347 + switch (attr) { 348 + case hwmon_temp_input: 349 + case hwmon_temp_fault: 350 + return 0444; 351 + case hwmon_temp_alarm: 352 + return 0644; 353 + default: 354 + break; 355 + } 356 + break; 357 + case hwmon_fan: 358 + switch (attr) { 359 + case hwmon_fan_input: 360 + case hwmon_fan_fault: 361 + return 0444; 362 + case hwmon_fan_alarm: 363 + return 0644; 364 + default: 365 + break; 366 + } 367 + break; 368 + case hwmon_pwm: 369 + case hwmon_in: 370 + return 0444; 371 + default: 372 + break; 373 + } 350 374 351 - err = fts_update_device(data); 352 - if (err < 0) 353 - return err; 354 - 355 - return sprintf(buf, "%u\n", data->volt[index]); 375 + return 0; 356 376 } 357 377 358 - static ssize_t temp_value_show(struct device *dev, 359 - struct device_attribute *devattr, char *buf) 378 + static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 379 + long *val) 360 380 { 361 381 struct fts_data *data = dev_get_drvdata(dev); 362 - int index = to_sensor_dev_attr(devattr)->index; 363 - int err; 382 + int ret = fts_update_device(data); 364 383 365 - err = fts_update_device(data); 366 - if (err < 0) 367 - return err; 368 - 369 - return sprintf(buf, "%u\n", data->temp_input[index]); 370 - } 371 - 372 - static ssize_t temp_fault_show(struct device *dev, 373 - struct device_attribute *devattr, char *buf) 374 - { 375 - struct fts_data *data = dev_get_drvdata(dev); 376 - int index = to_sensor_dev_attr(devattr)->index; 377 - int err; 378 - 379 - err = fts_update_device(data); 380 - if (err < 0) 381 - return err; 382 - 383 - /* 00h Temperature = Sensor Error */ 384 - return sprintf(buf, "%d\n", data->temp_input[index] == 0); 385 - } 386 - 387 - static ssize_t temp_alarm_show(struct device *dev, 388 - struct device_attribute *devattr, char *buf) 389 - { 390 - struct fts_data *data = dev_get_drvdata(dev); 391 - int index = to_sensor_dev_attr(devattr)->index; 392 - int err; 393 - 394 - err = fts_update_device(data); 395 - if (err < 0) 396 - return err; 397 - 398 - return sprintf(buf, "%u\n", !!(data->temp_alarm & BIT(index))); 399 - } 400 - 401 - static ssize_t 402 - temp_alarm_store(struct device *dev, struct device_attribute *devattr, 403 - const char *buf, size_t count) 404 - { 405 - struct fts_data *data = dev_get_drvdata(dev); 406 - int index = to_sensor_dev_attr(devattr)->index; 407 - long ret; 408 - 409 - ret = fts_update_device(data); 410 384 if (ret < 0) 411 385 return ret; 412 386 413 - if (kstrtoul(buf, 10, &ret) || ret != 0) 414 - return -EINVAL; 387 + switch (type) { 388 + case hwmon_temp: 389 + switch (attr) { 390 + case hwmon_temp_input: 391 + *val = (data->temp_input[channel] - 64) * 1000; 415 392 416 - mutex_lock(&data->update_lock); 417 - ret = fts_read_byte(data->client, FTS_REG_TEMP_CONTROL(index)); 418 - if (ret < 0) 419 - goto error; 393 + return 0; 394 + case hwmon_temp_alarm: 395 + *val = !!(data->temp_alarm & BIT(channel)); 420 396 421 - ret = fts_write_byte(data->client, FTS_REG_TEMP_CONTROL(index), 422 - ret | 0x1); 423 - if (ret < 0) 424 - goto error; 397 + return 0; 398 + case hwmon_temp_fault: 399 + /* 00h Temperature = Sensor Error */; 400 + *val = (data->temp_input[channel] == 0); 425 401 426 - data->valid = false; 427 - ret = count; 428 - error: 429 - mutex_unlock(&data->update_lock); 430 - return ret; 402 + return 0; 403 + default: 404 + break; 405 + } 406 + break; 407 + case hwmon_fan: 408 + switch (attr) { 409 + case hwmon_fan_input: 410 + *val = data->fan_input[channel] * 60; 411 + 412 + return 0; 413 + case hwmon_fan_alarm: 414 + *val = !!(data->fan_alarm & BIT(channel)); 415 + 416 + return 0; 417 + case hwmon_fan_fault: 418 + *val = !(data->fan_present & BIT(channel)); 419 + 420 + return 0; 421 + default: 422 + break; 423 + } 424 + break; 425 + case hwmon_pwm: 426 + switch (attr) { 427 + case hwmon_pwm_auto_channels_temp: 428 + if (data->fan_source[channel] == FTS_FAN_SOURCE_INVALID) 429 + *val = 0; 430 + else 431 + *val = BIT(data->fan_source[channel]); 432 + 433 + return 0; 434 + default: 435 + break; 436 + } 437 + break; 438 + case hwmon_in: 439 + switch (attr) { 440 + case hwmon_in_input: 441 + *val = DIV_ROUND_CLOSEST(data->volt[channel] * 3300, 255); 442 + 443 + return 0; 444 + default: 445 + break; 446 + } 447 + break; 448 + default: 449 + break; 450 + } 451 + 452 + return -EOPNOTSUPP; 431 453 } 432 454 433 - static ssize_t fan_value_show(struct device *dev, 434 - struct device_attribute *devattr, char *buf) 455 + static int fts_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 456 + long val) 435 457 { 436 458 struct fts_data *data = dev_get_drvdata(dev); 437 - int index = to_sensor_dev_attr(devattr)->index; 438 - int err; 459 + int ret = fts_update_device(data); 439 460 440 - err = fts_update_device(data); 441 - if (err < 0) 442 - return err; 443 - 444 - return sprintf(buf, "%u\n", data->fan_input[index]); 445 - } 446 - 447 - static ssize_t fan_source_show(struct device *dev, 448 - struct device_attribute *devattr, char *buf) 449 - { 450 - struct fts_data *data = dev_get_drvdata(dev); 451 - int index = to_sensor_dev_attr(devattr)->index; 452 - int err; 453 - 454 - err = fts_update_device(data); 455 - if (err < 0) 456 - return err; 457 - 458 - return sprintf(buf, "%u\n", data->fan_source[index]); 459 - } 460 - 461 - static ssize_t fan_alarm_show(struct device *dev, 462 - struct device_attribute *devattr, char *buf) 463 - { 464 - struct fts_data *data = dev_get_drvdata(dev); 465 - int index = to_sensor_dev_attr(devattr)->index; 466 - int err; 467 - 468 - err = fts_update_device(data); 469 - if (err < 0) 470 - return err; 471 - 472 - return sprintf(buf, "%d\n", !!(data->fan_alarm & BIT(index))); 473 - } 474 - 475 - static ssize_t 476 - fan_alarm_store(struct device *dev, struct device_attribute *devattr, 477 - const char *buf, size_t count) 478 - { 479 - struct fts_data *data = dev_get_drvdata(dev); 480 - int index = to_sensor_dev_attr(devattr)->index; 481 - long ret; 482 - 483 - ret = fts_update_device(data); 484 461 if (ret < 0) 485 462 return ret; 486 463 487 - if (kstrtoul(buf, 10, &ret) || ret != 0) 488 - return -EINVAL; 464 + switch (type) { 465 + case hwmon_temp: 466 + switch (attr) { 467 + case hwmon_temp_alarm: 468 + if (val) 469 + return -EINVAL; 489 470 490 - mutex_lock(&data->update_lock); 491 - ret = fts_read_byte(data->client, FTS_REG_FAN_CONTROL(index)); 492 - if (ret < 0) 493 - goto error; 471 + mutex_lock(&data->update_lock); 472 + ret = fts_read_byte(data->client, FTS_REG_TEMP_CONTROL(channel)); 473 + if (ret >= 0) 474 + ret = fts_write_byte(data->client, FTS_REG_TEMP_CONTROL(channel), 475 + ret | 0x1); 476 + if (ret >= 0) 477 + data->valid = false; 494 478 495 - ret = fts_write_byte(data->client, FTS_REG_FAN_CONTROL(index), 496 - ret | 0x1); 497 - if (ret < 0) 498 - goto error; 479 + mutex_unlock(&data->update_lock); 480 + if (ret < 0) 481 + return ret; 499 482 500 - data->valid = false; 501 - ret = count; 502 - error: 503 - mutex_unlock(&data->update_lock); 504 - return ret; 483 + return 0; 484 + default: 485 + break; 486 + } 487 + break; 488 + case hwmon_fan: 489 + switch (attr) { 490 + case hwmon_fan_alarm: 491 + if (val) 492 + return -EINVAL; 493 + 494 + mutex_lock(&data->update_lock); 495 + ret = fts_read_byte(data->client, FTS_REG_FAN_CONTROL(channel)); 496 + if (ret >= 0) 497 + ret = fts_write_byte(data->client, FTS_REG_FAN_CONTROL(channel), 498 + ret | 0x1); 499 + if (ret >= 0) 500 + data->valid = false; 501 + 502 + mutex_unlock(&data->update_lock); 503 + if (ret < 0) 504 + return ret; 505 + 506 + return 0; 507 + default: 508 + break; 509 + } 510 + break; 511 + default: 512 + break; 513 + } 514 + 515 + return -EOPNOTSUPP; 505 516 } 506 517 507 - /*****************************************************************************/ 508 - /* SysFS structs */ 509 - /*****************************************************************************/ 518 + static const struct hwmon_ops fts_ops = { 519 + .is_visible = fts_is_visible, 520 + .read = fts_read, 521 + .write = fts_write, 522 + }; 510 523 511 - /* Temperature sensors */ 512 - static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_value, 0); 513 - static SENSOR_DEVICE_ATTR_RO(temp2_input, temp_value, 1); 514 - static SENSOR_DEVICE_ATTR_RO(temp3_input, temp_value, 2); 515 - static SENSOR_DEVICE_ATTR_RO(temp4_input, temp_value, 3); 516 - static SENSOR_DEVICE_ATTR_RO(temp5_input, temp_value, 4); 517 - static SENSOR_DEVICE_ATTR_RO(temp6_input, temp_value, 5); 518 - static SENSOR_DEVICE_ATTR_RO(temp7_input, temp_value, 6); 519 - static SENSOR_DEVICE_ATTR_RO(temp8_input, temp_value, 7); 520 - static SENSOR_DEVICE_ATTR_RO(temp9_input, temp_value, 8); 521 - static SENSOR_DEVICE_ATTR_RO(temp10_input, temp_value, 9); 522 - static SENSOR_DEVICE_ATTR_RO(temp11_input, temp_value, 10); 523 - static SENSOR_DEVICE_ATTR_RO(temp12_input, temp_value, 11); 524 - static SENSOR_DEVICE_ATTR_RO(temp13_input, temp_value, 12); 525 - static SENSOR_DEVICE_ATTR_RO(temp14_input, temp_value, 13); 526 - static SENSOR_DEVICE_ATTR_RO(temp15_input, temp_value, 14); 527 - static SENSOR_DEVICE_ATTR_RO(temp16_input, temp_value, 15); 528 - 529 - static SENSOR_DEVICE_ATTR_RO(temp1_fault, temp_fault, 0); 530 - static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp_fault, 1); 531 - static SENSOR_DEVICE_ATTR_RO(temp3_fault, temp_fault, 2); 532 - static SENSOR_DEVICE_ATTR_RO(temp4_fault, temp_fault, 3); 533 - static SENSOR_DEVICE_ATTR_RO(temp5_fault, temp_fault, 4); 534 - static SENSOR_DEVICE_ATTR_RO(temp6_fault, temp_fault, 5); 535 - static SENSOR_DEVICE_ATTR_RO(temp7_fault, temp_fault, 6); 536 - static SENSOR_DEVICE_ATTR_RO(temp8_fault, temp_fault, 7); 537 - static SENSOR_DEVICE_ATTR_RO(temp9_fault, temp_fault, 8); 538 - static SENSOR_DEVICE_ATTR_RO(temp10_fault, temp_fault, 9); 539 - static SENSOR_DEVICE_ATTR_RO(temp11_fault, temp_fault, 10); 540 - static SENSOR_DEVICE_ATTR_RO(temp12_fault, temp_fault, 11); 541 - static SENSOR_DEVICE_ATTR_RO(temp13_fault, temp_fault, 12); 542 - static SENSOR_DEVICE_ATTR_RO(temp14_fault, temp_fault, 13); 543 - static SENSOR_DEVICE_ATTR_RO(temp15_fault, temp_fault, 14); 544 - static SENSOR_DEVICE_ATTR_RO(temp16_fault, temp_fault, 15); 545 - 546 - static SENSOR_DEVICE_ATTR_RW(temp1_alarm, temp_alarm, 0); 547 - static SENSOR_DEVICE_ATTR_RW(temp2_alarm, temp_alarm, 1); 548 - static SENSOR_DEVICE_ATTR_RW(temp3_alarm, temp_alarm, 2); 549 - static SENSOR_DEVICE_ATTR_RW(temp4_alarm, temp_alarm, 3); 550 - static SENSOR_DEVICE_ATTR_RW(temp5_alarm, temp_alarm, 4); 551 - static SENSOR_DEVICE_ATTR_RW(temp6_alarm, temp_alarm, 5); 552 - static SENSOR_DEVICE_ATTR_RW(temp7_alarm, temp_alarm, 6); 553 - static SENSOR_DEVICE_ATTR_RW(temp8_alarm, temp_alarm, 7); 554 - static SENSOR_DEVICE_ATTR_RW(temp9_alarm, temp_alarm, 8); 555 - static SENSOR_DEVICE_ATTR_RW(temp10_alarm, temp_alarm, 9); 556 - static SENSOR_DEVICE_ATTR_RW(temp11_alarm, temp_alarm, 10); 557 - static SENSOR_DEVICE_ATTR_RW(temp12_alarm, temp_alarm, 11); 558 - static SENSOR_DEVICE_ATTR_RW(temp13_alarm, temp_alarm, 12); 559 - static SENSOR_DEVICE_ATTR_RW(temp14_alarm, temp_alarm, 13); 560 - static SENSOR_DEVICE_ATTR_RW(temp15_alarm, temp_alarm, 14); 561 - static SENSOR_DEVICE_ATTR_RW(temp16_alarm, temp_alarm, 15); 562 - 563 - static struct attribute *fts_temp_attrs[] = { 564 - &sensor_dev_attr_temp1_input.dev_attr.attr, 565 - &sensor_dev_attr_temp2_input.dev_attr.attr, 566 - &sensor_dev_attr_temp3_input.dev_attr.attr, 567 - &sensor_dev_attr_temp4_input.dev_attr.attr, 568 - &sensor_dev_attr_temp5_input.dev_attr.attr, 569 - &sensor_dev_attr_temp6_input.dev_attr.attr, 570 - &sensor_dev_attr_temp7_input.dev_attr.attr, 571 - &sensor_dev_attr_temp8_input.dev_attr.attr, 572 - &sensor_dev_attr_temp9_input.dev_attr.attr, 573 - &sensor_dev_attr_temp10_input.dev_attr.attr, 574 - &sensor_dev_attr_temp11_input.dev_attr.attr, 575 - &sensor_dev_attr_temp12_input.dev_attr.attr, 576 - &sensor_dev_attr_temp13_input.dev_attr.attr, 577 - &sensor_dev_attr_temp14_input.dev_attr.attr, 578 - &sensor_dev_attr_temp15_input.dev_attr.attr, 579 - &sensor_dev_attr_temp16_input.dev_attr.attr, 580 - 581 - &sensor_dev_attr_temp1_fault.dev_attr.attr, 582 - &sensor_dev_attr_temp2_fault.dev_attr.attr, 583 - &sensor_dev_attr_temp3_fault.dev_attr.attr, 584 - &sensor_dev_attr_temp4_fault.dev_attr.attr, 585 - &sensor_dev_attr_temp5_fault.dev_attr.attr, 586 - &sensor_dev_attr_temp6_fault.dev_attr.attr, 587 - &sensor_dev_attr_temp7_fault.dev_attr.attr, 588 - &sensor_dev_attr_temp8_fault.dev_attr.attr, 589 - &sensor_dev_attr_temp9_fault.dev_attr.attr, 590 - &sensor_dev_attr_temp10_fault.dev_attr.attr, 591 - &sensor_dev_attr_temp11_fault.dev_attr.attr, 592 - &sensor_dev_attr_temp12_fault.dev_attr.attr, 593 - &sensor_dev_attr_temp13_fault.dev_attr.attr, 594 - &sensor_dev_attr_temp14_fault.dev_attr.attr, 595 - &sensor_dev_attr_temp15_fault.dev_attr.attr, 596 - &sensor_dev_attr_temp16_fault.dev_attr.attr, 597 - 598 - &sensor_dev_attr_temp1_alarm.dev_attr.attr, 599 - &sensor_dev_attr_temp2_alarm.dev_attr.attr, 600 - &sensor_dev_attr_temp3_alarm.dev_attr.attr, 601 - &sensor_dev_attr_temp4_alarm.dev_attr.attr, 602 - &sensor_dev_attr_temp5_alarm.dev_attr.attr, 603 - &sensor_dev_attr_temp6_alarm.dev_attr.attr, 604 - &sensor_dev_attr_temp7_alarm.dev_attr.attr, 605 - &sensor_dev_attr_temp8_alarm.dev_attr.attr, 606 - &sensor_dev_attr_temp9_alarm.dev_attr.attr, 607 - &sensor_dev_attr_temp10_alarm.dev_attr.attr, 608 - &sensor_dev_attr_temp11_alarm.dev_attr.attr, 609 - &sensor_dev_attr_temp12_alarm.dev_attr.attr, 610 - &sensor_dev_attr_temp13_alarm.dev_attr.attr, 611 - &sensor_dev_attr_temp14_alarm.dev_attr.attr, 612 - &sensor_dev_attr_temp15_alarm.dev_attr.attr, 613 - &sensor_dev_attr_temp16_alarm.dev_attr.attr, 524 + static const struct hwmon_channel_info *fts_info[] = { 525 + HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 526 + HWMON_CHANNEL_INFO(temp, 527 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 528 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 529 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 530 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 531 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 532 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 533 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 534 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 535 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 536 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 537 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 538 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 539 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 540 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 541 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, 542 + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT 543 + ), 544 + HWMON_CHANNEL_INFO(fan, 545 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 546 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 547 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 548 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 549 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 550 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 551 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, 552 + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT 553 + ), 554 + HWMON_CHANNEL_INFO(pwm, 555 + HWMON_PWM_AUTO_CHANNELS_TEMP, 556 + HWMON_PWM_AUTO_CHANNELS_TEMP, 557 + HWMON_PWM_AUTO_CHANNELS_TEMP, 558 + HWMON_PWM_AUTO_CHANNELS_TEMP, 559 + HWMON_PWM_AUTO_CHANNELS_TEMP, 560 + HWMON_PWM_AUTO_CHANNELS_TEMP, 561 + HWMON_PWM_AUTO_CHANNELS_TEMP, 562 + HWMON_PWM_AUTO_CHANNELS_TEMP 563 + ), 564 + HWMON_CHANNEL_INFO(in, 565 + HWMON_I_INPUT, 566 + HWMON_I_INPUT, 567 + HWMON_I_INPUT, 568 + HWMON_I_INPUT 569 + ), 614 570 NULL 615 571 }; 616 572 617 - /* Fans */ 618 - static SENSOR_DEVICE_ATTR_RO(fan1_input, fan_value, 0); 619 - static SENSOR_DEVICE_ATTR_RO(fan2_input, fan_value, 1); 620 - static SENSOR_DEVICE_ATTR_RO(fan3_input, fan_value, 2); 621 - static SENSOR_DEVICE_ATTR_RO(fan4_input, fan_value, 3); 622 - static SENSOR_DEVICE_ATTR_RO(fan5_input, fan_value, 4); 623 - static SENSOR_DEVICE_ATTR_RO(fan6_input, fan_value, 5); 624 - static SENSOR_DEVICE_ATTR_RO(fan7_input, fan_value, 6); 625 - static SENSOR_DEVICE_ATTR_RO(fan8_input, fan_value, 7); 626 - 627 - static SENSOR_DEVICE_ATTR_RO(fan1_source, fan_source, 0); 628 - static SENSOR_DEVICE_ATTR_RO(fan2_source, fan_source, 1); 629 - static SENSOR_DEVICE_ATTR_RO(fan3_source, fan_source, 2); 630 - static SENSOR_DEVICE_ATTR_RO(fan4_source, fan_source, 3); 631 - static SENSOR_DEVICE_ATTR_RO(fan5_source, fan_source, 4); 632 - static SENSOR_DEVICE_ATTR_RO(fan6_source, fan_source, 5); 633 - static SENSOR_DEVICE_ATTR_RO(fan7_source, fan_source, 6); 634 - static SENSOR_DEVICE_ATTR_RO(fan8_source, fan_source, 7); 635 - 636 - static SENSOR_DEVICE_ATTR_RW(fan1_alarm, fan_alarm, 0); 637 - static SENSOR_DEVICE_ATTR_RW(fan2_alarm, fan_alarm, 1); 638 - static SENSOR_DEVICE_ATTR_RW(fan3_alarm, fan_alarm, 2); 639 - static SENSOR_DEVICE_ATTR_RW(fan4_alarm, fan_alarm, 3); 640 - static SENSOR_DEVICE_ATTR_RW(fan5_alarm, fan_alarm, 4); 641 - static SENSOR_DEVICE_ATTR_RW(fan6_alarm, fan_alarm, 5); 642 - static SENSOR_DEVICE_ATTR_RW(fan7_alarm, fan_alarm, 6); 643 - static SENSOR_DEVICE_ATTR_RW(fan8_alarm, fan_alarm, 7); 644 - 645 - static struct attribute *fts_fan_attrs[] = { 646 - &sensor_dev_attr_fan1_input.dev_attr.attr, 647 - &sensor_dev_attr_fan2_input.dev_attr.attr, 648 - &sensor_dev_attr_fan3_input.dev_attr.attr, 649 - &sensor_dev_attr_fan4_input.dev_attr.attr, 650 - &sensor_dev_attr_fan5_input.dev_attr.attr, 651 - &sensor_dev_attr_fan6_input.dev_attr.attr, 652 - &sensor_dev_attr_fan7_input.dev_attr.attr, 653 - &sensor_dev_attr_fan8_input.dev_attr.attr, 654 - 655 - &sensor_dev_attr_fan1_source.dev_attr.attr, 656 - &sensor_dev_attr_fan2_source.dev_attr.attr, 657 - &sensor_dev_attr_fan3_source.dev_attr.attr, 658 - &sensor_dev_attr_fan4_source.dev_attr.attr, 659 - &sensor_dev_attr_fan5_source.dev_attr.attr, 660 - &sensor_dev_attr_fan6_source.dev_attr.attr, 661 - &sensor_dev_attr_fan7_source.dev_attr.attr, 662 - &sensor_dev_attr_fan8_source.dev_attr.attr, 663 - 664 - &sensor_dev_attr_fan1_alarm.dev_attr.attr, 665 - &sensor_dev_attr_fan2_alarm.dev_attr.attr, 666 - &sensor_dev_attr_fan3_alarm.dev_attr.attr, 667 - &sensor_dev_attr_fan4_alarm.dev_attr.attr, 668 - &sensor_dev_attr_fan5_alarm.dev_attr.attr, 669 - &sensor_dev_attr_fan6_alarm.dev_attr.attr, 670 - &sensor_dev_attr_fan7_alarm.dev_attr.attr, 671 - &sensor_dev_attr_fan8_alarm.dev_attr.attr, 672 - NULL 673 - }; 674 - 675 - /* Voltages */ 676 - static SENSOR_DEVICE_ATTR_RO(in1_input, in_value, 0); 677 - static SENSOR_DEVICE_ATTR_RO(in2_input, in_value, 1); 678 - static SENSOR_DEVICE_ATTR_RO(in3_input, in_value, 2); 679 - static SENSOR_DEVICE_ATTR_RO(in4_input, in_value, 3); 680 - static struct attribute *fts_voltage_attrs[] = { 681 - &sensor_dev_attr_in1_input.dev_attr.attr, 682 - &sensor_dev_attr_in2_input.dev_attr.attr, 683 - &sensor_dev_attr_in3_input.dev_attr.attr, 684 - &sensor_dev_attr_in4_input.dev_attr.attr, 685 - NULL 686 - }; 687 - 688 - static const struct attribute_group fts_voltage_attr_group = { 689 - .attrs = fts_voltage_attrs 690 - }; 691 - 692 - static const struct attribute_group fts_temp_attr_group = { 693 - .attrs = fts_temp_attrs 694 - }; 695 - 696 - static const struct attribute_group fts_fan_attr_group = { 697 - .attrs = fts_fan_attrs 698 - }; 699 - 700 - static const struct attribute_group *fts_attr_groups[] = { 701 - &fts_voltage_attr_group, 702 - &fts_temp_attr_group, 703 - &fts_fan_attr_group, 704 - NULL 573 + static const struct hwmon_chip_info fts_chip_info = { 574 + .ops = &fts_ops, 575 + .info = fts_info, 705 576 }; 706 577 707 578 /*****************************************************************************/ ··· 611 742 strscpy(info->type, fts_id[0].name, I2C_NAME_SIZE); 612 743 info->flags = 0; 613 744 return 0; 614 - } 615 - 616 - static void fts_remove(struct i2c_client *client) 617 - { 618 - struct fts_data *data = dev_get_drvdata(&client->dev); 619 - 620 - watchdog_unregister_device(&data->wdd); 621 745 } 622 746 623 747 static int fts_probe(struct i2c_client *client) ··· 655 793 return err; 656 794 revision = err; 657 795 658 - hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, 659 - "ftsteutates", 660 - data, 661 - fts_attr_groups); 796 + hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, "ftsteutates", data, 797 + &fts_chip_info, NULL); 662 798 if (IS_ERR(hwmon_dev)) 663 799 return PTR_ERR(hwmon_dev); 664 800 ··· 679 819 }, 680 820 .id_table = fts_id, 681 821 .probe_new = fts_probe, 682 - .remove = fts_remove, 683 822 .detect = fts_detect, 684 823 .address_list = normal_i2c, 685 824 };
+253
drivers/hwmon/gxp-fan-ctrl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P. */ 3 + 4 + #include <linux/bits.h> 5 + #include <linux/err.h> 6 + #include <linux/hwmon.h> 7 + #include <linux/io.h> 8 + #include <linux/module.h> 9 + #include <linux/of_device.h> 10 + #include <linux/platform_device.h> 11 + 12 + #define OFS_FAN_INST 0 /* Is 0 because plreg base will be set at INST */ 13 + #define OFS_FAN_FAIL 2 /* Is 2 bytes after base */ 14 + #define OFS_SEVSTAT 0 /* Is 0 because fn2 base will be set at SEVSTAT */ 15 + #define POWER_BIT 24 16 + 17 + struct gxp_fan_ctrl_drvdata { 18 + void __iomem *base; 19 + void __iomem *plreg; 20 + void __iomem *fn2; 21 + }; 22 + 23 + static bool fan_installed(struct device *dev, int fan) 24 + { 25 + struct gxp_fan_ctrl_drvdata *drvdata = dev_get_drvdata(dev); 26 + u8 val; 27 + 28 + val = readb(drvdata->plreg + OFS_FAN_INST); 29 + 30 + return !!(val & BIT(fan)); 31 + } 32 + 33 + static long fan_failed(struct device *dev, int fan) 34 + { 35 + struct gxp_fan_ctrl_drvdata *drvdata = dev_get_drvdata(dev); 36 + u8 val; 37 + 38 + val = readb(drvdata->plreg + OFS_FAN_FAIL); 39 + 40 + return !!(val & BIT(fan)); 41 + } 42 + 43 + static long fan_enabled(struct device *dev, int fan) 44 + { 45 + struct gxp_fan_ctrl_drvdata *drvdata = dev_get_drvdata(dev); 46 + u32 val; 47 + 48 + /* 49 + * Check the power status as if the platform is off the value 50 + * reported for the PWM will be incorrect. Report fan as 51 + * disabled. 52 + */ 53 + val = readl(drvdata->fn2 + OFS_SEVSTAT); 54 + 55 + return !!((val & BIT(POWER_BIT)) && fan_installed(dev, fan)); 56 + } 57 + 58 + static int gxp_pwm_write(struct device *dev, u32 attr, int channel, long val) 59 + { 60 + struct gxp_fan_ctrl_drvdata *drvdata = dev_get_drvdata(dev); 61 + 62 + switch (attr) { 63 + case hwmon_pwm_input: 64 + if (val > 255 || val < 0) 65 + return -EINVAL; 66 + writeb(val, drvdata->base + channel); 67 + return 0; 68 + default: 69 + return -EOPNOTSUPP; 70 + } 71 + } 72 + 73 + static int gxp_fan_ctrl_write(struct device *dev, enum hwmon_sensor_types type, 74 + u32 attr, int channel, long val) 75 + { 76 + switch (type) { 77 + case hwmon_pwm: 78 + return gxp_pwm_write(dev, attr, channel, val); 79 + default: 80 + return -EOPNOTSUPP; 81 + } 82 + } 83 + 84 + static int gxp_fan_read(struct device *dev, u32 attr, int channel, long *val) 85 + { 86 + switch (attr) { 87 + case hwmon_fan_enable: 88 + *val = fan_enabled(dev, channel); 89 + return 0; 90 + case hwmon_fan_fault: 91 + *val = fan_failed(dev, channel); 92 + return 0; 93 + default: 94 + return -EOPNOTSUPP; 95 + } 96 + } 97 + 98 + static int gxp_pwm_read(struct device *dev, u32 attr, int channel, long *val) 99 + { 100 + struct gxp_fan_ctrl_drvdata *drvdata = dev_get_drvdata(dev); 101 + u32 reg; 102 + 103 + /* 104 + * Check the power status of the platform. If the platform is off 105 + * the value reported for the PWM will be incorrect. In this case 106 + * report a PWM of zero. 107 + */ 108 + 109 + reg = readl(drvdata->fn2 + OFS_SEVSTAT); 110 + 111 + if (reg & BIT(POWER_BIT)) 112 + *val = fan_installed(dev, channel) ? readb(drvdata->base + channel) : 0; 113 + else 114 + *val = 0; 115 + 116 + return 0; 117 + } 118 + 119 + static int gxp_fan_ctrl_read(struct device *dev, enum hwmon_sensor_types type, 120 + u32 attr, int channel, long *val) 121 + { 122 + switch (type) { 123 + case hwmon_fan: 124 + return gxp_fan_read(dev, attr, channel, val); 125 + case hwmon_pwm: 126 + return gxp_pwm_read(dev, attr, channel, val); 127 + default: 128 + return -EOPNOTSUPP; 129 + } 130 + } 131 + 132 + static umode_t gxp_fan_ctrl_is_visible(const void *_data, 133 + enum hwmon_sensor_types type, 134 + u32 attr, int channel) 135 + { 136 + umode_t mode = 0; 137 + 138 + switch (type) { 139 + case hwmon_fan: 140 + switch (attr) { 141 + case hwmon_fan_enable: 142 + case hwmon_fan_fault: 143 + mode = 0444; 144 + break; 145 + default: 146 + break; 147 + } 148 + break; 149 + case hwmon_pwm: 150 + switch (attr) { 151 + case hwmon_pwm_input: 152 + mode = 0644; 153 + break; 154 + default: 155 + break; 156 + } 157 + break; 158 + default: 159 + break; 160 + } 161 + 162 + return mode; 163 + } 164 + 165 + static const struct hwmon_ops gxp_fan_ctrl_ops = { 166 + .is_visible = gxp_fan_ctrl_is_visible, 167 + .read = gxp_fan_ctrl_read, 168 + .write = gxp_fan_ctrl_write, 169 + }; 170 + 171 + static const struct hwmon_channel_info *gxp_fan_ctrl_info[] = { 172 + HWMON_CHANNEL_INFO(fan, 173 + HWMON_F_FAULT | HWMON_F_ENABLE, 174 + HWMON_F_FAULT | HWMON_F_ENABLE, 175 + HWMON_F_FAULT | HWMON_F_ENABLE, 176 + HWMON_F_FAULT | HWMON_F_ENABLE, 177 + HWMON_F_FAULT | HWMON_F_ENABLE, 178 + HWMON_F_FAULT | HWMON_F_ENABLE, 179 + HWMON_F_FAULT | HWMON_F_ENABLE, 180 + HWMON_F_FAULT | HWMON_F_ENABLE), 181 + HWMON_CHANNEL_INFO(pwm, 182 + HWMON_PWM_INPUT, 183 + HWMON_PWM_INPUT, 184 + HWMON_PWM_INPUT, 185 + HWMON_PWM_INPUT, 186 + HWMON_PWM_INPUT, 187 + HWMON_PWM_INPUT, 188 + HWMON_PWM_INPUT, 189 + HWMON_PWM_INPUT), 190 + NULL 191 + }; 192 + 193 + static const struct hwmon_chip_info gxp_fan_ctrl_chip_info = { 194 + .ops = &gxp_fan_ctrl_ops, 195 + .info = gxp_fan_ctrl_info, 196 + 197 + }; 198 + 199 + static int gxp_fan_ctrl_probe(struct platform_device *pdev) 200 + { 201 + struct gxp_fan_ctrl_drvdata *drvdata; 202 + struct device *dev = &pdev->dev; 203 + struct device *hwmon_dev; 204 + 205 + drvdata = devm_kzalloc(dev, sizeof(struct gxp_fan_ctrl_drvdata), 206 + GFP_KERNEL); 207 + if (!drvdata) 208 + return -ENOMEM; 209 + 210 + drvdata->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 211 + if (IS_ERR(drvdata->base)) 212 + return dev_err_probe(dev, PTR_ERR(drvdata->base), 213 + "failed to map base\n"); 214 + 215 + drvdata->plreg = devm_platform_ioremap_resource_byname(pdev, 216 + "pl"); 217 + if (IS_ERR(drvdata->plreg)) 218 + return dev_err_probe(dev, PTR_ERR(drvdata->plreg), 219 + "failed to map plreg\n"); 220 + 221 + drvdata->fn2 = devm_platform_ioremap_resource_byname(pdev, 222 + "fn2"); 223 + if (IS_ERR(drvdata->fn2)) 224 + return dev_err_probe(dev, PTR_ERR(drvdata->fn2), 225 + "failed to map fn2\n"); 226 + 227 + hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, 228 + "hpe_gxp_fan_ctrl", 229 + drvdata, 230 + &gxp_fan_ctrl_chip_info, 231 + NULL); 232 + 233 + return PTR_ERR_OR_ZERO(hwmon_dev); 234 + } 235 + 236 + static const struct of_device_id gxp_fan_ctrl_of_match[] = { 237 + { .compatible = "hpe,gxp-fan-ctrl", }, 238 + {}, 239 + }; 240 + MODULE_DEVICE_TABLE(of, gxp_fan_ctrl_of_match); 241 + 242 + static struct platform_driver gxp_fan_ctrl_driver = { 243 + .probe = gxp_fan_ctrl_probe, 244 + .driver = { 245 + .name = "gxp-fan-ctrl", 246 + .of_match_table = gxp_fan_ctrl_of_match, 247 + }, 248 + }; 249 + module_platform_driver(gxp_fan_ctrl_driver); 250 + 251 + MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>"); 252 + MODULE_DESCRIPTION("HPE GXP fan controller"); 253 + MODULE_LICENSE("GPL");
+2 -2
drivers/hwmon/hih6130.c
··· 150 150 } 151 151 152 152 /** 153 - * hih6130_show_temperature() - show temperature measurement value in sysfs 153 + * hih6130_temperature_show() - show temperature measurement value in sysfs 154 154 * @dev: device 155 155 * @attr: device attribute 156 156 * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to ··· 172 172 } 173 173 174 174 /** 175 - * hih6130_show_humidity() - show humidity measurement value in sysfs 175 + * hih6130_humidity_show() - show humidity measurement value in sysfs 176 176 * @dev: device 177 177 * @attr: device attribute 178 178 * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to
+1 -1
drivers/hwmon/ibmpex.c
··· 546 546 547 547 static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) 548 548 { 549 - struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; 549 + struct ibmpex_bmc_data *data = user_msg_data; 550 550 551 551 if (msg->msgid != data->tx_msgid) { 552 552 dev_err(data->bmc_device,
+5 -3
drivers/hwmon/iio_hwmon.c
··· 77 77 78 78 channels = devm_iio_channel_get_all(dev); 79 79 if (IS_ERR(channels)) { 80 - if (PTR_ERR(channels) == -ENODEV) 81 - return -EPROBE_DEFER; 82 - return PTR_ERR(channels); 80 + ret = PTR_ERR(channels); 81 + if (ret == -ENODEV) 82 + ret = -EPROBE_DEFER; 83 + return dev_err_probe(dev, ret, 84 + "Failed to get channels\n"); 83 85 } 84 86 85 87 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
+229
drivers/hwmon/intel-m10-bmc-hwmon.c
··· 340 340 .hinfo = n5010bmc_hinfo, 341 341 }; 342 342 343 + static const struct m10bmc_sdata n6000bmc_temp_tbl[] = { 344 + { 0x444, 0x448, 0x44c, 0x0, 0x0, 500, "FPGA E-TILE Temperature #1" }, 345 + { 0x450, 0x454, 0x458, 0x0, 0x0, 500, "FPGA E-TILE Temperature #2" }, 346 + { 0x45c, 0x460, 0x464, 0x0, 0x0, 500, "FPGA E-TILE Temperature #3" }, 347 + { 0x468, 0x46c, 0x470, 0x0, 0x0, 500, "FPGA E-TILE Temperature #4" }, 348 + { 0x474, 0x478, 0x47c, 0x0, 0x0, 500, "FPGA P-TILE Temperature" }, 349 + { 0x484, 0x488, 0x48c, 0x0, 0x0, 500, "FPGA FABRIC Digital Temperature #1" }, 350 + { 0x490, 0x494, 0x498, 0x0, 0x0, 500, "FPGA FABRIC Digital Temperature #2" }, 351 + { 0x49c, 0x4a0, 0x4a4, 0x0, 0x0, 500, "FPGA FABRIC Digital Temperature #3" }, 352 + { 0x4a8, 0x4ac, 0x4b0, 0x0, 0x0, 500, "FPGA FABRIC Digital Temperature #4" }, 353 + { 0x4b4, 0x4b8, 0x4bc, 0x0, 0x0, 500, "FPGA FABRIC Digital Temperature #5" }, 354 + { 0x4c0, 0x4c4, 0x4c8, 0x0, 0x0, 500, "FPGA FABRIC Remote Digital Temperature #1" }, 355 + { 0x4cc, 0x4d0, 0x4d4, 0x0, 0x0, 500, "FPGA FABRIC Remote Digital Temperature #2" }, 356 + { 0x4d8, 0x4dc, 0x4e0, 0x0, 0x0, 500, "FPGA FABRIC Remote Digital Temperature #3" }, 357 + { 0x4e4, 0x4e8, 0x4ec, 0x0, 0x0, 500, "FPGA FABRIC Remote Digital Temperature #4" }, 358 + { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, 359 + { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, 360 + { 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" }, 361 + { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "Columbiaville Die Temperature" }, 362 + { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, 363 + { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, 364 + { 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" }, 365 + { 0x548, 0x54c, 0x550, 0x0, 0x0, 500, "QSFP2 Case Temperature" }, 366 + { 0x554, 0x0, 0x0, 0x0, 0x0, 500, "FPGA Core Voltage Phase 0 VR Temperature" }, 367 + { 0x560, 0x0, 0x0, 0x0, 0x0, 500, "FPGA Core Voltage Phase 1 VR Temperature" }, 368 + { 0x56c, 0x0, 0x0, 0x0, 0x0, 500, "FPGA Core Voltage Phase 2 VR Temperature" }, 369 + { 0x578, 0x0, 0x0, 0x0, 0x0, 500, "FPGA Core Voltage VR Controller Temperature" }, 370 + { 0x584, 0x0, 0x0, 0x0, 0x0, 500, "FPGA VCCH VR Temperature" }, 371 + { 0x590, 0x0, 0x0, 0x0, 0x0, 500, "FPGA VCC_1V2 VR Temperature" }, 372 + { 0x59c, 0x0, 0x0, 0x0, 0x0, 500, "FPGA VCCH, VCC_1V2 VR Controller Temperature" }, 373 + { 0x5a8, 0x0, 0x0, 0x0, 0x0, 500, "3V3 VR Temperature" }, 374 + { 0x5b4, 0x0, 0x0, 0x0, 0x0, 500, "CVL Core Voltage VR Temperature" }, 375 + { 0x5c4, 0x5c8, 0x5cc, 0x5c0, 0x0, 500, "FPGA P-Tile Temperature [Remote]" }, 376 + { 0x5d0, 0x5d4, 0x5d8, 0x5c0, 0x0, 500, "FPGA E-Tile Temperature [Remote]" }, 377 + { 0x5dc, 0x5e0, 0x5e4, 0x5c0, 0x0, 500, "FPGA SDM Temperature [Remote]" }, 378 + { 0x5e8, 0x5ec, 0x5f0, 0x5c0, 0x0, 500, "FPGA Corner Temperature [Remote]" }, 379 + }; 380 + 381 + static const struct m10bmc_sdata n6000bmc_in_tbl[] = { 382 + { 0x5f4, 0x0, 0x0, 0x0, 0x0, 1, "Inlet 12V PCIe Rail Voltage" }, 383 + { 0x60c, 0x0, 0x0, 0x0, 0x0, 1, "Inlet 12V Aux Rail Voltage" }, 384 + { 0x624, 0x0, 0x0, 0x0, 0x0, 1, "Inlet 3V3 PCIe Rail Voltage" }, 385 + { 0x63c, 0x0, 0x0, 0x0, 0x0, 1, "FPGA Core Voltage Rail Voltage" }, 386 + { 0x644, 0x0, 0x0, 0x0, 0x0, 1, "FPGA VCCH Rail Voltage" }, 387 + { 0x64c, 0x0, 0x0, 0x0, 0x0, 1, "FPGA VCC_1V2 Rail Voltage" }, 388 + { 0x654, 0x0, 0x0, 0x0, 0x0, 1, "FPGA VCCH_GXER_1V1, VCCA_1V8 Voltage" }, 389 + { 0x664, 0x0, 0x0, 0x0, 0x0, 1, "FPGA VCCIO_1V2 Voltage" }, 390 + { 0x674, 0x0, 0x0, 0x0, 0x0, 1, "CVL Non Core Rails Inlet Voltage" }, 391 + { 0x684, 0x0, 0x0, 0x0, 0x0, 1, "MAX10 & Board CLK PWR 3V3 Inlet Voltage" }, 392 + { 0x694, 0x0, 0x0, 0x0, 0x0, 1, "CVL Core Voltage Rail Voltage" }, 393 + { 0x6ac, 0x0, 0x0, 0x0, 0x0, 1, "Board 3V3 VR Voltage" }, 394 + { 0x6b4, 0x0, 0x0, 0x0, 0x0, 1, "QSFP 3V3 Rail Voltage" }, 395 + { 0x6c4, 0x0, 0x0, 0x0, 0x0, 1, "QSFP (Primary) Supply Rail Voltage" }, 396 + { 0x6c8, 0x0, 0x0, 0x0, 0x0, 1, "QSFP (Secondary) Supply Rail Voltage" }, 397 + { 0x6cc, 0x0, 0x0, 0x0, 0x0, 1, "VCCCLK_GXER_2V5 Voltage" }, 398 + { 0x6d0, 0x0, 0x0, 0x0, 0x0, 1, "AVDDH_1V1_CVL Voltage" }, 399 + { 0x6d4, 0x0, 0x0, 0x0, 0x0, 1, "VDDH_1V8_CVL Voltage" }, 400 + { 0x6d8, 0x0, 0x0, 0x0, 0x0, 1, "VCCA_PLL Voltage" }, 401 + { 0x6e0, 0x0, 0x0, 0x0, 0x0, 1, "VCCRT_GXER_0V9 Voltage" }, 402 + { 0x6e8, 0x0, 0x0, 0x0, 0x0, 1, "VCCRT_GXPL_0V9 Voltage" }, 403 + { 0x6f0, 0x0, 0x0, 0x0, 0x0, 1, "VCCH_GXPL_1V8 Voltage" }, 404 + { 0x6f4, 0x0, 0x0, 0x0, 0x0, 1, "VCCPT_1V8 Voltage" }, 405 + { 0x6fc, 0x0, 0x0, 0x0, 0x0, 1, "VCC_3V3_M10 Voltage" }, 406 + { 0x700, 0x0, 0x0, 0x0, 0x0, 1, "VCC_1V8_M10 Voltage" }, 407 + { 0x704, 0x0, 0x0, 0x0, 0x0, 1, "VCC_1V2_EMIF1_2_3 Voltage" }, 408 + { 0x70c, 0x0, 0x0, 0x0, 0x0, 1, "VCC_1V2_EMIF4_5 Voltage" }, 409 + { 0x714, 0x0, 0x0, 0x0, 0x0, 1, "VCCA_1V8 Voltage" }, 410 + { 0x718, 0x0, 0x0, 0x0, 0x0, 1, "VCCH_GXER_1V1 Voltage" }, 411 + { 0x71c, 0x0, 0x0, 0x0, 0x0, 1, "AVDD_ETH_0V9_CVL Voltage" }, 412 + { 0x720, 0x0, 0x0, 0x0, 0x0, 1, "AVDD_PCIE_0V9_CVL Voltage" }, 413 + }; 414 + 415 + static const struct m10bmc_sdata n6000bmc_curr_tbl[] = { 416 + { 0x600, 0x604, 0x608, 0x0, 0x0, 1, "Inlet 12V PCIe Rail Current" }, 417 + { 0x618, 0x61c, 0x620, 0x0, 0x0, 1, "Inlet 12V Aux Rail Current" }, 418 + { 0x630, 0x634, 0x638, 0x0, 0x0, 1, "Inlet 3V3 PCIe Rail Current" }, 419 + { 0x640, 0x0, 0x0, 0x0, 0x0, 1, "FPGA Core Voltage Rail Current" }, 420 + { 0x648, 0x0, 0x0, 0x0, 0x0, 1, "FPGA VCCH Rail Current" }, 421 + { 0x650, 0x0, 0x0, 0x0, 0x0, 1, "FPGA VCC_1V2 Rail Current" }, 422 + { 0x658, 0x65c, 0x660, 0x0, 0x0, 1, "FPGA VCCH_GXER_1V1, VCCA_1V8 Current" }, 423 + { 0x668, 0x66c, 0x670, 0x0, 0x0, 1, "FPGA VCCIO_1V2 Current" }, 424 + { 0x678, 0x67c, 0x680, 0x0, 0x0, 1, "CVL Non Core Rails Inlet Current" }, 425 + { 0x688, 0x68c, 0x690, 0x0, 0x0, 1, "MAX10 & Board CLK PWR 3V3 Inlet Current" }, 426 + { 0x698, 0x0, 0x0, 0x0, 0x0, 1, "CVL Core Voltage Rail Current" }, 427 + { 0x6b0, 0x0, 0x0, 0x0, 0x0, 1, "Board 3V3 VR Current" }, 428 + { 0x6b8, 0x6bc, 0x6c0, 0x0, 0x0, 1, "QSFP 3V3 Rail Current" }, 429 + }; 430 + 431 + static const struct m10bmc_sdata n6000bmc_power_tbl[] = { 432 + { 0x724, 0x0, 0x0, 0x0, 0x0, 1, "Board Power" }, 433 + }; 434 + 435 + static const struct hwmon_channel_info *n6000bmc_hinfo[] = { 436 + HWMON_CHANNEL_INFO(temp, 437 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 438 + HWMON_T_LABEL, 439 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 440 + HWMON_T_LABEL, 441 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 442 + HWMON_T_LABEL, 443 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 444 + HWMON_T_LABEL, 445 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 446 + HWMON_T_LABEL, 447 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 448 + HWMON_T_LABEL, 449 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 450 + HWMON_T_LABEL, 451 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 452 + HWMON_T_LABEL, 453 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 454 + HWMON_T_LABEL, 455 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 456 + HWMON_T_LABEL, 457 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 458 + HWMON_T_LABEL, 459 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 460 + HWMON_T_LABEL, 461 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 462 + HWMON_T_LABEL, 463 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 464 + HWMON_T_LABEL, 465 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 466 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 467 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 468 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 469 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 470 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 471 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 472 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 473 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 474 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 475 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 476 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 477 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 478 + HWMON_T_LABEL, 479 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 480 + HWMON_T_LABEL, 481 + HWMON_T_INPUT | HWMON_T_LABEL, 482 + HWMON_T_INPUT | HWMON_T_LABEL, 483 + HWMON_T_INPUT | HWMON_T_LABEL, 484 + HWMON_T_INPUT | HWMON_T_LABEL, 485 + HWMON_T_INPUT | HWMON_T_LABEL, 486 + HWMON_T_INPUT | HWMON_T_LABEL, 487 + HWMON_T_INPUT | HWMON_T_LABEL, 488 + HWMON_T_INPUT | HWMON_T_LABEL, 489 + HWMON_T_INPUT | HWMON_T_LABEL, 490 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 491 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 492 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 493 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 494 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 495 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL, 496 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 497 + HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_LABEL), 498 + HWMON_CHANNEL_INFO(in, 499 + HWMON_I_INPUT | HWMON_I_LABEL, 500 + HWMON_I_INPUT | HWMON_I_LABEL, 501 + HWMON_I_INPUT | HWMON_I_LABEL, 502 + HWMON_I_INPUT | HWMON_I_LABEL, 503 + HWMON_I_INPUT | HWMON_I_LABEL, 504 + HWMON_I_INPUT | HWMON_I_LABEL, 505 + HWMON_I_INPUT | HWMON_I_LABEL, 506 + HWMON_I_INPUT | HWMON_I_LABEL, 507 + HWMON_I_INPUT | HWMON_I_LABEL, 508 + HWMON_I_INPUT | HWMON_I_LABEL, 509 + HWMON_I_INPUT | HWMON_I_LABEL, 510 + HWMON_I_INPUT | HWMON_I_LABEL, 511 + HWMON_I_INPUT | HWMON_I_LABEL, 512 + HWMON_I_INPUT | HWMON_I_LABEL, 513 + HWMON_I_INPUT | HWMON_I_LABEL, 514 + HWMON_I_INPUT | HWMON_I_LABEL, 515 + HWMON_I_INPUT | HWMON_I_LABEL, 516 + HWMON_I_INPUT | HWMON_I_LABEL, 517 + HWMON_I_INPUT | HWMON_I_LABEL, 518 + HWMON_I_INPUT | HWMON_I_LABEL, 519 + HWMON_I_INPUT | HWMON_I_LABEL, 520 + HWMON_I_INPUT | HWMON_I_LABEL, 521 + HWMON_I_INPUT | HWMON_I_LABEL, 522 + HWMON_I_INPUT | HWMON_I_LABEL, 523 + HWMON_I_INPUT | HWMON_I_LABEL, 524 + HWMON_I_INPUT | HWMON_I_LABEL, 525 + HWMON_I_INPUT | HWMON_I_LABEL, 526 + HWMON_I_INPUT | HWMON_I_LABEL, 527 + HWMON_I_INPUT | HWMON_I_LABEL, 528 + HWMON_I_INPUT | HWMON_I_LABEL, 529 + HWMON_I_INPUT | HWMON_I_LABEL), 530 + HWMON_CHANNEL_INFO(curr, 531 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 532 + HWMON_C_LABEL, 533 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 534 + HWMON_C_LABEL, 535 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 536 + HWMON_C_LABEL, 537 + HWMON_C_INPUT | HWMON_C_LABEL, 538 + HWMON_C_INPUT | HWMON_C_LABEL, 539 + HWMON_C_INPUT | HWMON_C_LABEL, 540 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 541 + HWMON_C_LABEL, 542 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 543 + HWMON_C_LABEL, 544 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 545 + HWMON_C_LABEL, 546 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 547 + HWMON_C_LABEL, 548 + HWMON_C_INPUT | HWMON_C_LABEL, 549 + HWMON_C_INPUT | HWMON_C_LABEL, 550 + HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | 551 + HWMON_C_LABEL), 552 + HWMON_CHANNEL_INFO(power, 553 + HWMON_P_INPUT | HWMON_P_LABEL), 554 + NULL 555 + }; 556 + 557 + static const struct m10bmc_hwmon_board_data n6000bmc_hwmon_bdata = { 558 + .tables = { 559 + [hwmon_temp] = n6000bmc_temp_tbl, 560 + [hwmon_in] = n6000bmc_in_tbl, 561 + [hwmon_curr] = n6000bmc_curr_tbl, 562 + [hwmon_power] = n6000bmc_power_tbl, 563 + }, 564 + 565 + .hinfo = n6000bmc_hinfo, 566 + }; 567 + 343 568 static umode_t 344 569 m10bmc_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, 345 570 u32 attr, int channel) ··· 773 548 { 774 549 .name = "n5010bmc-hwmon", 775 550 .driver_data = (unsigned long)&n5010bmc_hwmon_bdata, 551 + }, 552 + { 553 + .name = "n6000bmc-hwmon", 554 + .driver_data = (unsigned long)&n6000bmc_hwmon_bdata, 776 555 }, 777 556 { } 778 557 };
+143 -52
drivers/hwmon/it87.c
··· 34 34 * IT8786E Super I/O chip w/LPC interface 35 35 * IT8790E Super I/O chip w/LPC interface 36 36 * IT8792E Super I/O chip w/LPC interface 37 + * IT87952E Super I/O chip w/LPC interface 37 38 * Sis950 A clone of the IT8705F 38 39 * 39 40 * Copyright (C) 2001 Chris Gauthron ··· 64 63 65 64 enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732, 66 65 it8771, it8772, it8781, it8782, it8783, it8786, it8790, 67 - it8792, it8603, it8620, it8622, it8628 }; 68 - 69 - static unsigned short force_id; 70 - module_param(force_id, ushort, 0); 71 - MODULE_PARM_DESC(force_id, "Override the detected device ID"); 72 - 73 - static bool ignore_resource_conflict; 74 - module_param(ignore_resource_conflict, bool, 0); 75 - MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict"); 66 + it8792, it8603, it8620, it8622, it8628, it87952 }; 76 67 77 68 static struct platform_device *it87_pdev[2]; 78 69 ··· 79 86 80 87 #define DEVID 0x20 /* Register: Device ID */ 81 88 #define DEVREV 0x22 /* Register: Device Revision */ 89 + 90 + static inline void __superio_enter(int ioreg) 91 + { 92 + outb(0x87, ioreg); 93 + outb(0x01, ioreg); 94 + outb(0x55, ioreg); 95 + outb(ioreg == REG_4E ? 0xaa : 0x55, ioreg); 96 + } 82 97 83 98 static inline int superio_inb(int ioreg, int reg) 84 99 { ··· 125 124 if (!request_muxed_region(ioreg, 2, DRVNAME)) 126 125 return -EBUSY; 127 126 128 - outb(0x87, ioreg); 129 - outb(0x01, ioreg); 130 - outb(0x55, ioreg); 131 - outb(ioreg == REG_4E ? 0xaa : 0x55, ioreg); 127 + __superio_enter(ioreg); 132 128 return 0; 133 129 } 134 130 135 - static inline void superio_exit(int ioreg) 131 + static inline void superio_exit(int ioreg, bool noexit) 136 132 { 137 - outb(0x02, ioreg); 138 - outb(0x02, ioreg + 1); 133 + if (!noexit) { 134 + outb(0x02, ioreg); 135 + outb(0x02, ioreg + 1); 136 + } 139 137 release_region(ioreg, 2); 140 138 } 141 139 ··· 161 161 #define IT8622E_DEVID 0x8622 162 162 #define IT8623E_DEVID 0x8623 163 163 #define IT8628E_DEVID 0x8628 164 + #define IT87952E_DEVID 0x8695 164 165 #define IT87_ACT_REG 0x30 165 166 #define IT87_BASE_REG 0x60 166 167 ··· 176 175 #define IT87_SIO_SPI_REG 0xef /* SPI function pin select */ 177 176 #define IT87_SIO_VID_REG 0xfc /* VID value */ 178 177 #define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */ 178 + 179 + /* Force chip IDs to specified values. Should only be used for testing */ 180 + static unsigned short force_id[2]; 181 + static unsigned int force_id_cnt; 182 + 183 + /* ACPI resource conflicts are ignored if this parameter is set to 1 */ 184 + static bool ignore_resource_conflict; 179 185 180 186 /* Update battery voltage after every reading if true */ 181 187 static bool update_vbat; ··· 280 272 281 273 struct it87_devices { 282 274 const char *name; 283 - const char * const suffix; 275 + const char * const model; 284 276 u32 features; 285 277 u8 peci_mask; 286 278 u8 old_peci_mask; ··· 305 297 #define FEAT_PWM_FREQ2 BIT(16) /* Separate pwm freq 2 */ 306 298 #define FEAT_SIX_TEMP BIT(17) /* Up to 6 temp sensors */ 307 299 #define FEAT_VIN3_5V BIT(18) /* VIN3 connected to +5V */ 300 + /* 301 + * Disabling configuration mode on some chips can result in system 302 + * hang-ups and access failures to the Super-IO chip at the 303 + * second SIO address. Never exit configuration mode on these 304 + * chips to avoid the problem. 305 + */ 306 + #define FEAT_CONF_NOEXIT BIT(19) /* Chip should not exit conf mode */ 308 307 309 308 static const struct it87_devices it87_devices[] = { 310 309 [it87] = { 311 310 .name = "it87", 312 - .suffix = "F", 311 + .model = "IT87F", 313 312 .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ 314 313 }, 315 314 [it8712] = { 316 315 .name = "it8712", 317 - .suffix = "F", 316 + .model = "IT8712F", 318 317 .features = FEAT_OLD_AUTOPWM | FEAT_VID, 319 318 /* may need to overwrite */ 320 319 }, 321 320 [it8716] = { 322 321 .name = "it8716", 323 - .suffix = "F", 322 + .model = "IT8716F", 324 323 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID 325 324 | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2, 326 325 }, 327 326 [it8718] = { 328 327 .name = "it8718", 329 - .suffix = "F", 328 + .model = "IT8718F", 330 329 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID 331 330 | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS 332 331 | FEAT_PWM_FREQ2, ··· 341 326 }, 342 327 [it8720] = { 343 328 .name = "it8720", 344 - .suffix = "F", 329 + .model = "IT8720F", 345 330 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID 346 331 | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS 347 332 | FEAT_PWM_FREQ2, ··· 349 334 }, 350 335 [it8721] = { 351 336 .name = "it8721", 352 - .suffix = "F", 337 + .model = "IT8721F", 353 338 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 354 339 | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI 355 340 | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL ··· 359 344 }, 360 345 [it8728] = { 361 346 .name = "it8728", 362 - .suffix = "F", 347 + .model = "IT8728F", 363 348 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 364 349 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS 365 350 | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2, ··· 367 352 }, 368 353 [it8732] = { 369 354 .name = "it8732", 370 - .suffix = "F", 355 + .model = "IT8732F", 371 356 .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS 372 357 | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI 373 358 | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL, ··· 376 361 }, 377 362 [it8771] = { 378 363 .name = "it8771", 379 - .suffix = "E", 364 + .model = "IT8771E", 380 365 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 381 366 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL 382 367 | FEAT_PWM_FREQ2, ··· 388 373 }, 389 374 [it8772] = { 390 375 .name = "it8772", 391 - .suffix = "E", 376 + .model = "IT8772E", 392 377 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 393 378 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL 394 379 | FEAT_PWM_FREQ2, ··· 400 385 }, 401 386 [it8781] = { 402 387 .name = "it8781", 403 - .suffix = "F", 388 + .model = "IT8781F", 404 389 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET 405 390 | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, 406 391 .old_peci_mask = 0x4, 407 392 }, 408 393 [it8782] = { 409 394 .name = "it8782", 410 - .suffix = "F", 395 + .model = "IT8782F", 411 396 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET 412 397 | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, 413 398 .old_peci_mask = 0x4, 414 399 }, 415 400 [it8783] = { 416 401 .name = "it8783", 417 - .suffix = "E/F", 402 + .model = "IT8783E/F", 418 403 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET 419 404 | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, 420 405 .old_peci_mask = 0x4, 421 406 }, 422 407 [it8786] = { 423 408 .name = "it8786", 424 - .suffix = "E", 409 + .model = "IT8786E", 425 410 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 426 411 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL 427 412 | FEAT_PWM_FREQ2, ··· 429 414 }, 430 415 [it8790] = { 431 416 .name = "it8790", 432 - .suffix = "E", 417 + .model = "IT8790E", 433 418 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 434 419 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL 435 - | FEAT_PWM_FREQ2, 420 + | FEAT_PWM_FREQ2 | FEAT_CONF_NOEXIT, 436 421 .peci_mask = 0x07, 437 422 }, 438 423 [it8792] = { 439 424 .name = "it8792", 440 - .suffix = "E", 425 + .model = "IT8792E/IT8795E", 441 426 .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS 442 427 | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI 443 - | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL, 428 + | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_CONF_NOEXIT, 444 429 .peci_mask = 0x07, 445 430 .old_peci_mask = 0x02, /* Actually reports PCH */ 446 431 }, 447 432 [it8603] = { 448 433 .name = "it8603", 449 - .suffix = "E", 434 + .model = "IT8603E", 450 435 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 451 436 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL 452 437 | FEAT_AVCC3 | FEAT_PWM_FREQ2, ··· 454 439 }, 455 440 [it8620] = { 456 441 .name = "it8620", 457 - .suffix = "E", 442 + .model = "IT8620E", 458 443 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 459 444 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS 460 445 | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 ··· 463 448 }, 464 449 [it8622] = { 465 450 .name = "it8622", 466 - .suffix = "E", 451 + .model = "IT8622E", 467 452 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 468 453 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS 469 454 | FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 ··· 472 457 }, 473 458 [it8628] = { 474 459 .name = "it8628", 475 - .suffix = "E", 460 + .model = "IT8628E", 476 461 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 477 462 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS 478 463 | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 479 464 | FEAT_SIX_TEMP | FEAT_VIN3_5V, 480 465 .peci_mask = 0x07, 466 + }, 467 + [it87952] = { 468 + .name = "it87952", 469 + .model = "IT87952E", 470 + .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS 471 + | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI 472 + | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_CONF_NOEXIT, 473 + .peci_mask = 0x07, 474 + .old_peci_mask = 0x02, /* Actually reports PCH */ 481 475 }, 482 476 }; 483 477 ··· 514 490 #define has_pwm_freq2(data) ((data)->features & FEAT_PWM_FREQ2) 515 491 #define has_six_temp(data) ((data)->features & FEAT_SIX_TEMP) 516 492 #define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V) 493 + #define has_conf_noexit(data) ((data)->features & FEAT_CONF_NOEXIT) 517 494 518 495 struct it87_sio_data { 519 496 int sioaddr; ··· 2422 2397 2423 2398 /* SuperIO detection - will change isa_address if a chip is found */ 2424 2399 static int __init it87_find(int sioaddr, unsigned short *address, 2425 - struct it87_sio_data *sio_data) 2400 + struct it87_sio_data *sio_data, int chip_cnt) 2426 2401 { 2427 2402 int err; 2428 2403 u16 chip_type; 2429 - const struct it87_devices *config; 2404 + const struct it87_devices *config = NULL; 2430 2405 2431 2406 err = superio_enter(sioaddr); 2432 2407 if (err) ··· 2438 2413 if (chip_type == 0xffff) 2439 2414 goto exit; 2440 2415 2441 - if (force_id) 2442 - chip_type = force_id; 2416 + if (force_id_cnt == 1) { 2417 + /* If only one value given use for all chips */ 2418 + if (force_id[0]) 2419 + chip_type = force_id[0]; 2420 + } else if (force_id[chip_cnt]) 2421 + chip_type = force_id[chip_cnt]; 2443 2422 2444 2423 switch (chip_type) { 2445 2424 case IT8705F_DEVID: ··· 2508 2479 case IT8628E_DEVID: 2509 2480 sio_data->type = it8628; 2510 2481 break; 2482 + case IT87952E_DEVID: 2483 + sio_data->type = it87952; 2484 + break; 2511 2485 case 0xffff: /* No device at all */ 2512 2486 goto exit; 2513 2487 default: ··· 2518 2486 goto exit; 2519 2487 } 2520 2488 2489 + config = &it87_devices[sio_data->type]; 2490 + 2521 2491 superio_select(sioaddr, PME); 2522 2492 if (!(superio_inb(sioaddr, IT87_ACT_REG) & 0x01)) { 2523 - pr_info("Device not activated, skipping\n"); 2493 + pr_info("Device (chip %s ioreg 0x%x) not activated, skipping\n", 2494 + config->model, sioaddr); 2524 2495 goto exit; 2525 2496 } 2526 2497 2527 2498 *address = superio_inw(sioaddr, IT87_BASE_REG) & ~(IT87_EXTENT - 1); 2528 2499 if (*address == 0) { 2529 - pr_info("Base address not set, skipping\n"); 2500 + pr_info("Base address not set (chip %s ioreg 0x%x), skipping\n", 2501 + config->model, sioaddr); 2530 2502 goto exit; 2531 2503 } 2532 2504 2533 2505 err = 0; 2534 2506 sio_data->sioaddr = sioaddr; 2535 2507 sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f; 2536 - pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type, 2537 - it87_devices[sio_data->type].suffix, 2508 + pr_info("Found %s chip at 0x%x, revision %d\n", 2509 + it87_devices[sio_data->type].model, 2538 2510 *address, sio_data->revision); 2539 - 2540 - config = &it87_devices[sio_data->type]; 2541 2511 2542 2512 /* in7 (VSB or VCCH5V) is always internal on some chips */ 2543 2513 if (has_in7_internal(config)) ··· 2858 2824 sio_data->skip_pwm |= dmi_data->skip_pwm; 2859 2825 2860 2826 exit: 2861 - superio_exit(sioaddr); 2827 + superio_exit(sioaddr, config ? has_conf_noexit(config) : false); 2862 2828 return err; 2863 2829 } 2864 2830 ··· 3244 3210 reg2c); 3245 3211 } 3246 3212 3247 - superio_exit(data->sioaddr); 3213 + superio_exit(data->sioaddr, has_conf_noexit(data)); 3248 3214 } 3249 3215 3250 3216 static int it87_resume(struct device *dev) ··· 3345 3311 } 3346 3312 3347 3313 /* 3314 + * On various Gigabyte AM4 boards (AB350, AX370), the second Super-IO chip 3315 + * (IT8792E) needs to be in configuration mode before accessing the first 3316 + * due to a bug in IT8792E which otherwise results in LPC bus access errors. 3317 + * This needs to be done before accessing the first Super-IO chip since 3318 + * the second chip may have been accessed prior to loading this driver. 3319 + * 3320 + * The problem is also reported to affect IT8795E, which is used on X299 boards 3321 + * and has the same chip ID as IT8792E (0x8733). It also appears to affect 3322 + * systems with IT8790E, which is used on some Z97X-Gaming boards as well as 3323 + * Z87X-OC. 3324 + * DMI entries for those systems will be added as they become available and 3325 + * as the problem is confirmed to affect those boards. 3326 + */ 3327 + static int it87_sio_force(const struct dmi_system_id *dmi_entry) 3328 + { 3329 + __superio_enter(REG_4E); 3330 + 3331 + return it87_dmi_cb(dmi_entry); 3332 + }; 3333 + 3334 + /* 3348 3335 * On the Shuttle SN68PT, FAN_CTL2 is apparently not 3349 3336 * connected to a fan, but to something else. One user 3350 3337 * has reported instant system power-off when changing ··· 3387 3332 .driver_data = data, \ 3388 3333 } 3389 3334 3335 + #define IT87_DMI_MATCH_GBT(name, cb, data) \ 3336 + IT87_DMI_MATCH_VND("Gigabyte Technology Co., Ltd.", name, cb, data) 3337 + 3390 3338 static const struct dmi_system_id it87_dmi_table[] __initconst = { 3339 + IT87_DMI_MATCH_GBT("AB350", it87_sio_force, NULL), 3340 + /* ? + IT8792E/IT8795E */ 3341 + IT87_DMI_MATCH_GBT("AX370", it87_sio_force, NULL), 3342 + /* ? + IT8792E/IT8795E */ 3343 + IT87_DMI_MATCH_GBT("Z97X-Gaming G1", it87_sio_force, NULL), 3344 + /* ? + IT8790E */ 3345 + IT87_DMI_MATCH_GBT("TRX40 AORUS XTREME", it87_sio_force, NULL), 3346 + /* IT8688E + IT8792E/IT8795E */ 3347 + IT87_DMI_MATCH_GBT("Z390 AORUS ULTRA-CF", it87_sio_force, NULL), 3348 + /* IT8688E + IT8792E/IT8795E */ 3349 + IT87_DMI_MATCH_GBT("B550 AORUS PRO AC", it87_sio_force, NULL), 3350 + /* IT8688E + IT8792E/IT8795E */ 3351 + IT87_DMI_MATCH_GBT("X570 AORUS MASTER", it87_sio_force, NULL), 3352 + /* IT8688E + IT8792E/IT8795E */ 3353 + IT87_DMI_MATCH_GBT("X570 AORUS PRO", it87_sio_force, NULL), 3354 + /* IT8688E + IT8792E/IT8795E */ 3355 + IT87_DMI_MATCH_GBT("X570 AORUS PRO WIFI", it87_sio_force, NULL), 3356 + /* IT8688E + IT8792E/IT8795E */ 3357 + IT87_DMI_MATCH_GBT("X570S AERO G", it87_sio_force, NULL), 3358 + /* IT8689E + IT87952E */ 3359 + IT87_DMI_MATCH_GBT("Z690 AORUS PRO DDR4", it87_sio_force, NULL), 3360 + /* IT8689E + IT87952E */ 3361 + IT87_DMI_MATCH_GBT("Z690 AORUS PRO", it87_sio_force, NULL), 3362 + /* IT8689E + IT87952E */ 3391 3363 IT87_DMI_MATCH_VND("nVIDIA", "FN68PT", it87_dmi_cb, &nvidia_fn68pt), 3392 3364 { } 3393 3365 ··· 3438 3356 for (i = 0; i < ARRAY_SIZE(sioaddr); i++) { 3439 3357 memset(&sio_data, 0, sizeof(struct it87_sio_data)); 3440 3358 isa_address[i] = 0; 3441 - err = it87_find(sioaddr[i], &isa_address[i], &sio_data); 3359 + err = it87_find(sioaddr[i], &isa_address[i], &sio_data, i); 3442 3360 if (err || isa_address[i] == 0) 3443 3361 continue; 3444 3362 /* ··· 3486 3404 3487 3405 MODULE_AUTHOR("Chris Gauthron, Jean Delvare <jdelvare@suse.de>"); 3488 3406 MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver"); 3407 + 3408 + module_param_array(force_id, ushort, &force_id_cnt, 0); 3409 + MODULE_PARM_DESC(force_id, "Override one or more detected device ID(s)"); 3410 + 3411 + module_param(ignore_resource_conflict, bool, 0); 3412 + MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict"); 3413 + 3489 3414 module_param(update_vbat, bool, 0); 3490 3415 MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); 3416 + 3491 3417 module_param(fix_pwm_polarity, bool, 0); 3492 3418 MODULE_PARM_DESC(fix_pwm_polarity, 3493 3419 "Force PWM polarity to active high (DANGEROUS)"); 3420 + 3494 3421 MODULE_LICENSE("GPL"); 3495 3422 3496 3423 module_init(sm_it87_init);
+87 -45
drivers/hwmon/ltc2945.c
··· 58 58 #define CONTROL_MULT_SELECT (1 << 0) 59 59 #define CONTROL_TEST_MODE (1 << 4) 60 60 61 + static const struct of_device_id __maybe_unused ltc2945_of_match[] = { 62 + { .compatible = "adi,ltc2945" }, 63 + { } 64 + }; 65 + MODULE_DEVICE_TABLE(of, ltc2945_of_match); 66 + 67 + /** 68 + * struct ltc2945_data - LTC2945 device data 69 + * @regmap: regmap device 70 + * @shunt_resistor: shunt resistor value in micro ohms (1000 by default) 71 + */ 72 + struct ltc2945_data { 73 + struct regmap *regmap; 74 + u32 shunt_resistor; 75 + }; 76 + 61 77 static inline bool is_power_reg(u8 reg) 62 78 { 63 79 return reg < LTC2945_SENSE_H; ··· 82 66 /* Return the value from the given register in uW, mV, or mA */ 83 67 static long long ltc2945_reg_to_val(struct device *dev, u8 reg) 84 68 { 85 - struct regmap *regmap = dev_get_drvdata(dev); 69 + struct ltc2945_data *data = dev_get_drvdata(dev); 70 + struct regmap *regmap = data->regmap; 71 + u32 shunt_resistor = data->shunt_resistor; 86 72 unsigned int control; 87 73 u8 buf[3]; 88 74 long long val; ··· 96 78 return ret; 97 79 98 80 if (is_power_reg(reg)) { 99 - /* power */ 81 + /* 24-bit power */ 100 82 val = (buf[0] << 16) + (buf[1] << 8) + buf[2]; 101 83 } else { 102 - /* current, voltage */ 84 + /* 12-bit current, voltage */ 103 85 val = (buf[0] << 4) + (buf[1] >> 4); 104 86 } 105 87 ··· 110 92 case LTC2945_MAX_POWER_THRES_H: 111 93 case LTC2945_MIN_POWER_THRES_H: 112 94 /* 113 - * Convert to uW by assuming current is measured with 114 - * an 1mOhm sense resistor, similar to current 115 - * measurements. 95 + * Convert to uW 116 96 * Control register bit 0 selects if voltage at SENSE+/VDD 117 97 * or voltage at ADIN is used to measure power. 118 98 */ ··· 124 108 /* 0.5 mV * 25 uV = 0.0125 uV resolution. */ 125 109 val = (val * 25LL) >> 1; 126 110 } 111 + val *= 1000; 112 + /* Overflow check: Assuming max 24-bit power, val is at most 53 bits right now. */ 113 + val = DIV_ROUND_CLOSEST_ULL(val, shunt_resistor); 114 + /* 115 + * Overflow check: After division, depending on shunt resistor, 116 + * val can still be > 32 bits so returning long long makes sense 117 + */ 118 + 127 119 break; 128 120 case LTC2945_VIN_H: 129 121 case LTC2945_MAX_VIN_H: ··· 154 130 case LTC2945_MIN_SENSE_H: 155 131 case LTC2945_MAX_SENSE_THRES_H: 156 132 case LTC2945_MIN_SENSE_THRES_H: 157 - /* 158 - * 25 uV resolution. Convert to current as measured with 159 - * an 1 mOhm sense resistor, in mA. If a different sense 160 - * resistor is installed, calculate the actual current by 161 - * dividing the reported current by the sense resistor value 162 - * in mOhm. 163 - */ 164 - val *= 25; 133 + /* 25 uV resolution. Convert to mA. */ 134 + val *= 25 * 1000; 135 + /* Overflow check: Assuming max 12-bit sense, val is at most 27 bits right now */ 136 + val = DIV_ROUND_CLOSEST_ULL(val, shunt_resistor); 137 + /* Overflow check: After division, <= 27 bits */ 165 138 break; 166 139 default: 167 140 return -EINVAL; ··· 166 145 return val; 167 146 } 168 147 169 - static int ltc2945_val_to_reg(struct device *dev, u8 reg, 170 - unsigned long val) 148 + static long long ltc2945_val_to_reg(struct device *dev, u8 reg, 149 + unsigned long long val) 171 150 { 172 - struct regmap *regmap = dev_get_drvdata(dev); 151 + struct ltc2945_data *data = dev_get_drvdata(dev); 152 + struct regmap *regmap = data->regmap; 153 + u32 shunt_resistor = data->shunt_resistor; 173 154 unsigned int control; 174 155 int ret; 156 + 157 + /* Ensure we don't overflow */ 158 + val = clamp_val(val, 0, U32_MAX); 175 159 176 160 switch (reg) { 177 161 case LTC2945_POWER_H: ··· 185 159 case LTC2945_MAX_POWER_THRES_H: 186 160 case LTC2945_MIN_POWER_THRES_H: 187 161 /* 188 - * Convert to register value by assuming current is measured 189 - * with an 1mOhm sense resistor, similar to current 190 - * measurements. 191 162 * Control register bit 0 selects if voltage at SENSE+/VDD 192 163 * or voltage at ADIN is used to measure power, which in turn 193 164 * determines register calculations. ··· 194 171 return ret; 195 172 if (control & CONTROL_MULT_SELECT) { 196 173 /* 25 mV * 25 uV = 0.625 uV resolution. */ 197 - val = DIV_ROUND_CLOSEST(val, 625); 174 + val *= shunt_resistor; 175 + /* Overflow check: Assuming 32-bit val and shunt resistor, val <= 64bits */ 176 + val = DIV_ROUND_CLOSEST_ULL(val, 625 * 1000); 177 + /* Overflow check: val is now <= 44 bits */ 198 178 } else { 199 - /* 200 - * 0.5 mV * 25 uV = 0.0125 uV resolution. 201 - * Divide first to avoid overflow; 202 - * accept loss of accuracy. 203 - */ 204 - val = DIV_ROUND_CLOSEST(val, 25) * 2; 179 + /* 0.5 mV * 25 uV = 0.0125 uV resolution. */ 180 + val *= shunt_resistor; 181 + /* Overflow check: Assuming 32-bit val and shunt resistor, val <= 64bits */ 182 + val = DIV_ROUND_CLOSEST_ULL(val, 25 * 1000) * 2; 183 + /* Overflow check: val is now <= 51 bits */ 205 184 } 206 185 break; 207 186 case LTC2945_VIN_H: ··· 212 187 case LTC2945_MAX_VIN_THRES_H: 213 188 case LTC2945_MIN_VIN_THRES_H: 214 189 /* 25 mV resolution. */ 215 - val /= 25; 190 + val = DIV_ROUND_CLOSEST_ULL(val, 25); 216 191 break; 217 192 case LTC2945_ADIN_H: 218 193 case LTC2945_MAX_ADIN_H: ··· 227 202 case LTC2945_MIN_SENSE_H: 228 203 case LTC2945_MAX_SENSE_THRES_H: 229 204 case LTC2945_MIN_SENSE_THRES_H: 230 - /* 231 - * 25 uV resolution. Convert to current as measured with 232 - * an 1 mOhm sense resistor, in mA. If a different sense 233 - * resistor is installed, calculate the actual current by 234 - * dividing the reported current by the sense resistor value 235 - * in mOhm. 236 - */ 237 - val = DIV_ROUND_CLOSEST(val, 25); 205 + /* 25 uV resolution. Convert to mA. */ 206 + val *= shunt_resistor; 207 + /* Overflow check: Assuming 32-bit val and 32-bit shunt resistor, val is 64bits */ 208 + val = DIV_ROUND_CLOSEST_ULL(val, 25 * 1000); 209 + /* Overflow check: val is now <= 50 bits */ 238 210 break; 239 211 default: 240 212 return -EINVAL; ··· 256 234 const char *buf, size_t count) 257 235 { 258 236 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 259 - struct regmap *regmap = dev_get_drvdata(dev); 237 + struct ltc2945_data *data = dev_get_drvdata(dev); 238 + struct regmap *regmap = data->regmap; 260 239 u8 reg = attr->index; 261 - unsigned long val; 240 + unsigned int val; 262 241 u8 regbuf[3]; 263 242 int num_regs; 264 - int regval; 243 + long long regval; 265 244 int ret; 266 245 267 - ret = kstrtoul(buf, 10, &val); 246 + ret = kstrtouint(buf, 10, &val); 268 247 if (ret) 269 248 return ret; 270 249 271 250 /* convert to register value, then clamp and write result */ 272 251 regval = ltc2945_val_to_reg(dev, reg, val); 252 + if (regval < 0) 253 + return regval; 273 254 if (is_power_reg(reg)) { 274 255 regval = clamp_val(regval, 0, 0xffffff); 275 256 regbuf[0] = regval >> 16; ··· 294 269 const char *buf, size_t count) 295 270 { 296 271 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 297 - struct regmap *regmap = dev_get_drvdata(dev); 272 + struct ltc2945_data *data = dev_get_drvdata(dev); 273 + struct regmap *regmap = data->regmap; 298 274 u8 reg = attr->index; 299 275 int num_regs = is_power_reg(reg) ? 3 : 2; 300 276 u8 buf_min[3] = { 0xff, 0xff, 0xff }; ··· 347 321 struct device_attribute *da, char *buf) 348 322 { 349 323 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 350 - struct regmap *regmap = dev_get_drvdata(dev); 324 + struct ltc2945_data *data = dev_get_drvdata(dev); 325 + struct regmap *regmap = data->regmap; 351 326 unsigned int fault; 352 327 int ret; 353 328 ··· 477 450 struct device *dev = &client->dev; 478 451 struct device *hwmon_dev; 479 452 struct regmap *regmap; 453 + struct ltc2945_data *data; 454 + 455 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 456 + if (!data) 457 + return -ENOMEM; 458 + dev_set_drvdata(dev, data); 480 459 481 460 regmap = devm_regmap_init_i2c(client, &ltc2945_regmap_config); 482 461 if (IS_ERR(regmap)) { ··· 490 457 return PTR_ERR(regmap); 491 458 } 492 459 460 + data->regmap = regmap; 461 + if (device_property_read_u32(dev, "shunt-resistor-micro-ohms", 462 + &data->shunt_resistor)) 463 + data->shunt_resistor = 1000; 464 + 465 + if (data->shunt_resistor == 0) 466 + return -EINVAL; 467 + 493 468 /* Clear faults */ 494 469 regmap_write(regmap, LTC2945_FAULT, 0x00); 495 470 496 471 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 497 - regmap, 472 + data, 498 473 ltc2945_groups); 499 474 return PTR_ERR_OR_ZERO(hwmon_dev); 500 475 } ··· 516 475 517 476 static struct i2c_driver ltc2945_driver = { 518 477 .driver = { 519 - .name = "ltc2945", 520 - }, 478 + .name = "ltc2945", 479 + .of_match_table = of_match_ptr(ltc2945_of_match), 480 + }, 521 481 .probe_new = ltc2945_probe, 522 482 .id_table = ltc2945_id, 523 483 };
+263
drivers/hwmon/mc34vr500.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * An hwmon driver for the NXP MC34VR500 PMIC 4 + * 5 + * Author: Mario Kicherer <dev@kicherer.org> 6 + */ 7 + 8 + #include <linux/bits.h> 9 + #include <linux/dev_printk.h> 10 + #include <linux/device.h> 11 + #include <linux/err.h> 12 + #include <linux/errno.h> 13 + #include <linux/hwmon.h> 14 + #include <linux/i2c.h> 15 + #include <linux/interrupt.h> 16 + #include <linux/irqreturn.h> 17 + #include <linux/module.h> 18 + #include <linux/of.h> 19 + #include <linux/regmap.h> 20 + 21 + #define MC34VR500_I2C_ADDR 0x08 22 + #define MC34VR500_DEVICEID_VALUE 0x14 23 + 24 + /* INTSENSE0 */ 25 + #define ENS_BIT BIT(0) 26 + #define LOWVINS_BIT BIT(1) 27 + #define THERM110S_BIT BIT(2) 28 + #define THERM120S_BIT BIT(3) 29 + #define THERM125S_BIT BIT(4) 30 + #define THERM130S_BIT BIT(5) 31 + 32 + #define MC34VR500_DEVICEID 0x00 33 + 34 + #define MC34VR500_SILICONREVID 0x03 35 + #define MC34VR500_FABID 0x04 36 + #define MC34VR500_INTSTAT0 0x05 37 + #define MC34VR500_INTMASK0 0x06 38 + #define MC34VR500_INTSENSE0 0x07 39 + 40 + struct mc34vr500_data { 41 + struct device *hwmon_dev; 42 + struct regmap *regmap; 43 + }; 44 + 45 + static irqreturn_t mc34vr500_process_interrupt(int irq, void *userdata) 46 + { 47 + struct mc34vr500_data *data = (struct mc34vr500_data *)userdata; 48 + unsigned int reg; 49 + int ret; 50 + 51 + ret = regmap_read(data->regmap, MC34VR500_INTSTAT0, &reg); 52 + if (ret < 0) 53 + return IRQ_HANDLED; 54 + 55 + if (reg) { 56 + if (reg & LOWVINS_BIT) 57 + hwmon_notify_event(data->hwmon_dev, hwmon_in, 58 + hwmon_in_min_alarm, 0); 59 + 60 + if (reg & THERM110S_BIT) 61 + hwmon_notify_event(data->hwmon_dev, hwmon_temp, 62 + hwmon_temp_max_alarm, 0); 63 + 64 + if (reg & THERM120S_BIT) 65 + hwmon_notify_event(data->hwmon_dev, hwmon_temp, 66 + hwmon_temp_crit_alarm, 0); 67 + 68 + if (reg & THERM130S_BIT) 69 + hwmon_notify_event(data->hwmon_dev, hwmon_temp, 70 + hwmon_temp_emergency_alarm, 0); 71 + 72 + /* write 1 to clear */ 73 + regmap_write(data->regmap, MC34VR500_INTSTAT0, LOWVINS_BIT | 74 + THERM110S_BIT | THERM120S_BIT | THERM130S_BIT); 75 + } 76 + 77 + return IRQ_HANDLED; 78 + } 79 + 80 + static umode_t mc34vr500_is_visible(const void *data, 81 + enum hwmon_sensor_types type, 82 + u32 attr, int channel) 83 + { 84 + switch (attr) { 85 + case hwmon_in_min_alarm: 86 + case hwmon_temp_max_alarm: 87 + case hwmon_temp_crit_alarm: 88 + case hwmon_temp_emergency_alarm: 89 + return 0444; 90 + default: 91 + break; 92 + } 93 + 94 + return 0; 95 + } 96 + 97 + static int mc34vr500_alarm_read(struct mc34vr500_data *data, int index, 98 + long *val) 99 + { 100 + unsigned int reg; 101 + int ret; 102 + 103 + ret = regmap_read(data->regmap, MC34VR500_INTSENSE0, &reg); 104 + if (ret < 0) 105 + return ret; 106 + 107 + *val = !!(reg & index); 108 + 109 + return 0; 110 + } 111 + 112 + static int mc34vr500_read(struct device *dev, enum hwmon_sensor_types type, 113 + u32 attr, int channel, long *val) 114 + { 115 + struct mc34vr500_data *data = dev_get_drvdata(dev); 116 + 117 + switch (type) { 118 + case hwmon_in: 119 + switch (attr) { 120 + case hwmon_in_min_alarm: 121 + return mc34vr500_alarm_read(data, LOWVINS_BIT, val); 122 + default: 123 + return -EOPNOTSUPP; 124 + } 125 + case hwmon_temp: 126 + switch (attr) { 127 + case hwmon_temp_max_alarm: 128 + return mc34vr500_alarm_read(data, THERM110S_BIT, val); 129 + case hwmon_temp_crit_alarm: 130 + return mc34vr500_alarm_read(data, THERM120S_BIT, val); 131 + case hwmon_temp_emergency_alarm: 132 + return mc34vr500_alarm_read(data, THERM130S_BIT, val); 133 + default: 134 + return -EOPNOTSUPP; 135 + } 136 + default: 137 + return -EOPNOTSUPP; 138 + } 139 + } 140 + 141 + static const struct hwmon_channel_info *mc34vr500_info[] = { 142 + HWMON_CHANNEL_INFO(in, HWMON_I_MIN_ALARM), 143 + HWMON_CHANNEL_INFO(temp, HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM 144 + | HWMON_T_EMERGENCY_ALARM), 145 + NULL, 146 + }; 147 + 148 + static const struct hwmon_ops mc34vr500_hwmon_ops = { 149 + .is_visible = mc34vr500_is_visible, 150 + .read = mc34vr500_read, 151 + }; 152 + 153 + static const struct hwmon_chip_info mc34vr500_chip_info = { 154 + .ops = &mc34vr500_hwmon_ops, 155 + .info = mc34vr500_info, 156 + }; 157 + 158 + static const struct regmap_config mc34vr500_regmap_config = { 159 + .reg_bits = 8, 160 + .val_bits = 8, 161 + .max_register = MC34VR500_INTSENSE0, 162 + }; 163 + 164 + static int mc34vr500_probe(struct i2c_client *client) 165 + { 166 + struct device *dev = &client->dev; 167 + struct mc34vr500_data *data; 168 + struct device *hwmon_dev; 169 + int ret; 170 + unsigned int reg, revid, fabid; 171 + struct regmap *regmap; 172 + 173 + regmap = devm_regmap_init_i2c(client, &mc34vr500_regmap_config); 174 + if (IS_ERR(regmap)) 175 + return PTR_ERR(regmap); 176 + 177 + data = devm_kzalloc(dev, sizeof(struct mc34vr500_data), GFP_KERNEL); 178 + if (!data) 179 + return -ENOMEM; 180 + 181 + data->regmap = regmap; 182 + 183 + ret = regmap_read(regmap, MC34VR500_DEVICEID, &reg); 184 + if (ret < 0) 185 + return ret; 186 + 187 + if (reg != MC34VR500_DEVICEID_VALUE) 188 + return -ENODEV; 189 + 190 + ret = regmap_read(regmap, MC34VR500_SILICONREVID, &revid); 191 + if (ret < 0) 192 + return ret; 193 + 194 + ret = regmap_read(regmap, MC34VR500_FABID, &fabid); 195 + if (ret < 0) 196 + return ret; 197 + 198 + dev_dbg(dev, "mc34vr500: revid 0x%x fabid 0x%x\n", revid, fabid); 199 + 200 + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 201 + data, 202 + &mc34vr500_chip_info, 203 + NULL); 204 + if (IS_ERR(hwmon_dev)) 205 + return PTR_ERR(hwmon_dev); 206 + 207 + data->hwmon_dev = hwmon_dev; 208 + 209 + if (client->irq) { 210 + ret = devm_request_threaded_irq(dev, client->irq, NULL, 211 + mc34vr500_process_interrupt, 212 + IRQF_TRIGGER_RISING | 213 + IRQF_ONESHOT | 214 + IRQF_SHARED, 215 + dev_name(dev), data); 216 + if (ret) 217 + return ret; 218 + 219 + /* write 1 to clear interrupts */ 220 + ret = regmap_write(regmap, MC34VR500_INTSTAT0, LOWVINS_BIT | 221 + THERM110S_BIT | THERM120S_BIT | 222 + THERM130S_BIT); 223 + if (ret) 224 + return ret; 225 + 226 + /* unmask interrupts */ 227 + ret = regmap_write(regmap, MC34VR500_INTMASK0, 228 + (unsigned int) ~(LOWVINS_BIT | THERM110S_BIT | 229 + THERM120S_BIT | THERM130S_BIT)); 230 + if (ret) 231 + return ret; 232 + } 233 + 234 + return 0; 235 + } 236 + 237 + static const struct i2c_device_id mc34vr500_id[] = { 238 + { "mc34vr500", 0 }, 239 + { }, 240 + }; 241 + MODULE_DEVICE_TABLE(i2c, mc34vr500_id); 242 + 243 + static const struct of_device_id __maybe_unused mc34vr500_of_match[] = { 244 + { .compatible = "nxp,mc34vr500" }, 245 + { }, 246 + }; 247 + MODULE_DEVICE_TABLE(of, mc34vr500_of_match); 248 + 249 + static struct i2c_driver mc34vr500_driver = { 250 + .driver = { 251 + .name = "mc34vr500", 252 + .of_match_table = of_match_ptr(mc34vr500_of_match), 253 + }, 254 + .probe_new = mc34vr500_probe, 255 + .id_table = mc34vr500_id, 256 + }; 257 + 258 + module_i2c_driver(mc34vr500_driver); 259 + 260 + MODULE_AUTHOR("Mario Kicherer <dev@kicherer.org>"); 261 + 262 + MODULE_DESCRIPTION("MC34VR500 driver"); 263 + MODULE_LICENSE("GPL");
+6
drivers/hwmon/mlxreg-fan.c
··· 155 155 if (err) 156 156 return err; 157 157 158 + if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) { 159 + /* FAN is broken - return zero for FAN speed. */ 160 + *val = 0; 161 + return 0; 162 + } 163 + 158 164 *val = MLXREG_FAN_GET_RPM(regval, fan->divider, 159 165 fan->samples); 160 166 break;
+1 -1
drivers/hwmon/nct6775-core.c
··· 1150 1150 if (err) 1151 1151 return err; 1152 1152 reg &= 0x70 >> oddshift; 1153 - reg |= data->fan_div[nr] & (0x7 << oddshift); 1153 + reg |= (data->fan_div[nr] & 0x7) << oddshift; 1154 1154 return nct6775_write_value(data, fandiv_reg, reg); 1155 1155 } 1156 1156
+120 -28
drivers/hwmon/nct6775-platform.c
··· 17 17 #include <linux/module.h> 18 18 #include <linux/platform_device.h> 19 19 #include <linux/regmap.h> 20 - #include <linux/wmi.h> 21 20 22 21 #include "nct6775.h" 23 22 ··· 106 107 void (*sio_exit)(struct nct6775_sio_data *sio_data); 107 108 }; 108 109 109 - #define ASUSWMI_MONITORING_GUID "466747A0-70EC-11DE-8A39-0800200C9A66" 110 + #define ASUSWMI_METHOD "WMBD" 110 111 #define ASUSWMI_METHODID_RSIO 0x5253494F 111 112 #define ASUSWMI_METHODID_WSIO 0x5753494F 112 113 #define ASUSWMI_METHODID_RHWM 0x5248574D 113 114 #define ASUSWMI_METHODID_WHWM 0x5748574D 114 115 #define ASUSWMI_UNSUPPORTED_METHOD 0xFFFFFFFE 116 + #define ASUSWMI_DEVICE_HID "PNP0C14" 117 + #define ASUSWMI_DEVICE_UID "ASUSWMI" 118 + #define ASUSMSI_DEVICE_UID "AsusMbSwInterface" 119 + 120 + #if IS_ENABLED(CONFIG_ACPI) 121 + /* 122 + * ASUS boards have only one device with WMI "WMBD" method and have provided 123 + * access to only one SuperIO chip at 0x0290. 124 + */ 125 + static struct acpi_device *asus_acpi_dev; 126 + #endif 115 127 116 128 static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval) 117 129 { 118 - #if IS_ENABLED(CONFIG_ACPI_WMI) 130 + #if IS_ENABLED(CONFIG_ACPI) 131 + acpi_handle handle = acpi_device_handle(asus_acpi_dev); 119 132 u32 args = bank | (reg << 8) | (val << 16); 120 - struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; 121 - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 133 + struct acpi_object_list input; 134 + union acpi_object params[3]; 135 + unsigned long long result; 122 136 acpi_status status; 123 - union acpi_object *obj; 124 - u32 tmp = ASUSWMI_UNSUPPORTED_METHOD; 125 137 126 - status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0, 127 - method_id, &input, &output); 138 + params[0].type = ACPI_TYPE_INTEGER; 139 + params[0].integer.value = 0; 140 + params[1].type = ACPI_TYPE_INTEGER; 141 + params[1].integer.value = method_id; 142 + params[2].type = ACPI_TYPE_BUFFER; 143 + params[2].buffer.length = sizeof(args); 144 + params[2].buffer.pointer = (void *)&args; 145 + input.count = 3; 146 + input.pointer = params; 128 147 148 + status = acpi_evaluate_integer(handle, ASUSWMI_METHOD, &input, &result); 129 149 if (ACPI_FAILURE(status)) 130 150 return -EIO; 131 151 132 - obj = output.pointer; 133 - if (obj && obj->type == ACPI_TYPE_INTEGER) 134 - tmp = obj->integer.value; 135 - 136 152 if (retval) 137 - *retval = tmp; 153 + *retval = (u32)result & 0xFFFFFFFF; 138 154 139 - kfree(obj); 140 - 141 - if (tmp == ASUSWMI_UNSUPPORTED_METHOD) 142 - return -ENODEV; 143 155 return 0; 144 156 #else 145 157 return -EOPNOTSUPP; ··· 1109 1099 "TUF GAMING Z490-PLUS (WI-FI)", 1110 1100 }; 1111 1101 1102 + static const char * const asus_msi_boards[] = { 1103 + "EX-B660M-V5 PRO D4", 1104 + "PRIME B650-PLUS", 1105 + "PRIME B650M-A", 1106 + "PRIME B650M-A AX", 1107 + "PRIME B650M-A II", 1108 + "PRIME B650M-A WIFI", 1109 + "PRIME B650M-A WIFI II", 1110 + "PRIME B660M-A D4", 1111 + "PRIME B660M-A WIFI D4", 1112 + "PRIME X670-P", 1113 + "PRIME X670-P WIFI", 1114 + "PRIME X670E-PRO WIFI", 1115 + "Pro B660M-C-D4", 1116 + "ProArt B660-CREATOR D4", 1117 + "ProArt X670E-CREATOR WIFI", 1118 + "ROG CROSSHAIR X670E EXTREME", 1119 + "ROG CROSSHAIR X670E GENE", 1120 + "ROG CROSSHAIR X670E HERO", 1121 + "ROG MAXIMUS XIII EXTREME GLACIAL", 1122 + "ROG MAXIMUS Z690 EXTREME", 1123 + "ROG MAXIMUS Z690 EXTREME GLACIAL", 1124 + "ROG STRIX B650-A GAMING WIFI", 1125 + "ROG STRIX B650E-E GAMING WIFI", 1126 + "ROG STRIX B650E-F GAMING WIFI", 1127 + "ROG STRIX B650E-I GAMING WIFI", 1128 + "ROG STRIX B660-A GAMING WIFI D4", 1129 + "ROG STRIX B660-F GAMING WIFI", 1130 + "ROG STRIX B660-G GAMING WIFI", 1131 + "ROG STRIX B660-I GAMING WIFI", 1132 + "ROG STRIX X670E-A GAMING WIFI", 1133 + "ROG STRIX X670E-E GAMING WIFI", 1134 + "ROG STRIX X670E-F GAMING WIFI", 1135 + "ROG STRIX X670E-I GAMING WIFI", 1136 + "ROG STRIX Z590-A GAMING WIFI II", 1137 + "ROG STRIX Z690-A GAMING WIFI D4", 1138 + "TUF GAMING B650-PLUS", 1139 + "TUF GAMING B650-PLUS WIFI", 1140 + "TUF GAMING B650M-PLUS", 1141 + "TUF GAMING B650M-PLUS WIFI", 1142 + "TUF GAMING B660M-PLUS WIFI", 1143 + "TUF GAMING X670E-PLUS", 1144 + "TUF GAMING X670E-PLUS WIFI", 1145 + "TUF GAMING Z590-PLUS WIFI", 1146 + }; 1147 + 1148 + #if IS_ENABLED(CONFIG_ACPI) 1149 + /* 1150 + * Callback for acpi_bus_for_each_dev() to find the right device 1151 + * by _UID and _HID and return 1 to stop iteration. 1152 + */ 1153 + static int nct6775_asuswmi_device_match(struct device *dev, void *data) 1154 + { 1155 + struct acpi_device *adev = to_acpi_device(dev); 1156 + const char *uid = acpi_device_uid(adev); 1157 + const char *hid = acpi_device_hid(adev); 1158 + 1159 + if (hid && !strcmp(hid, ASUSWMI_DEVICE_HID) && uid && !strcmp(uid, data)) { 1160 + asus_acpi_dev = adev; 1161 + return 1; 1162 + } 1163 + 1164 + return 0; 1165 + } 1166 + #endif 1167 + 1168 + static enum sensor_access nct6775_determine_access(const char *device_uid) 1169 + { 1170 + #if IS_ENABLED(CONFIG_ACPI) 1171 + u8 tmp; 1172 + 1173 + acpi_bus_for_each_dev(nct6775_asuswmi_device_match, (void *)device_uid); 1174 + if (!asus_acpi_dev) 1175 + return access_direct; 1176 + 1177 + /* if reading chip id via ACPI succeeds, use WMI "WMBD" method for access */ 1178 + if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) { 1179 + pr_debug("Using Asus WMBD method of %s to access %#x chip.\n", device_uid, tmp); 1180 + return access_asuswmi; 1181 + } 1182 + #endif 1183 + 1184 + return access_direct; 1185 + } 1186 + 1112 1187 static int __init sensors_nct6775_platform_init(void) 1113 1188 { 1114 1189 int i, err; ··· 1204 1109 int sioaddr[2] = { 0x2e, 0x4e }; 1205 1110 enum sensor_access access = access_direct; 1206 1111 const char *board_vendor, *board_name; 1207 - u8 tmp; 1208 1112 1209 1113 err = platform_driver_register(&nct6775_driver); 1210 1114 if (err) ··· 1216 1122 !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) { 1217 1123 err = match_string(asus_wmi_boards, ARRAY_SIZE(asus_wmi_boards), 1218 1124 board_name); 1219 - if (err >= 0) { 1220 - /* if reading chip id via WMI succeeds, use WMI */ 1221 - if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) { 1222 - pr_info("Using Asus WMI to access %#x chip.\n", tmp); 1223 - access = access_asuswmi; 1224 - } else { 1225 - pr_err("Can't read ChipID by Asus WMI.\n"); 1226 - } 1227 - } 1125 + if (err >= 0) 1126 + access = nct6775_determine_access(ASUSWMI_DEVICE_UID); 1127 + 1128 + err = match_string(asus_msi_boards, ARRAY_SIZE(asus_msi_boards), 1129 + board_name); 1130 + if (err >= 0) 1131 + access = nct6775_determine_access(ASUSMSI_DEVICE_UID); 1228 1132 } 1229 1133 1230 1134 /*
+1
drivers/hwmon/nzxt-smart2.c
··· 791 791 { HID_USB_DEVICE(0x1e71, 0x2009) }, /* NZXT RGB & Fan Controller */ 792 792 { HID_USB_DEVICE(0x1e71, 0x200e) }, /* NZXT RGB & Fan Controller */ 793 793 { HID_USB_DEVICE(0x1e71, 0x2010) }, /* NZXT RGB & Fan Controller */ 794 + { HID_USB_DEVICE(0x1e71, 0x2019) }, /* NZXT RGB & Fan Controller */ 794 795 {}, 795 796 }; 796 797
+43 -9
drivers/hwmon/oxp-sensors.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0+ 2 2 /* 3 - * Platform driver for OXP Handhelds that expose fan reading and control 4 - * via hwmon sysfs. 3 + * Platform driver for OneXPlayer, AOK ZOE, and Aya Neo Handhelds that expose 4 + * fan reading and control via hwmon sysfs. 5 5 * 6 - * Old boards have the same DMI strings and they are told appart by the 7 - * boot cpu vendor (Intel/AMD). Currently only AMD boards are supported 8 - * but the code is made to be simple to add other handheld boards in the 9 - * future. 6 + * Old OXP boards have the same DMI strings and they are told apart by 7 + * the boot cpu vendor (Intel/AMD). Currently only AMD boards are 8 + * supported but the code is made to be simple to add other handheld 9 + * boards in the future. 10 10 * Fan control is provided via pwm interface in the range [0-255]. 11 11 * Old AMD boards use [0-100] as range in the EC, the written value is 12 12 * scaled to accommodate for that. Newer boards like the mini PRO and ··· 42 42 43 43 enum oxp_board { 44 44 aok_zoe_a1 = 1, 45 + aya_neo_air, 46 + aya_neo_air_pro, 45 47 oxp_mini_amd, 46 48 oxp_mini_amd_pro, 47 49 }; ··· 61 59 DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A1 AR07"), 62 60 }, 63 61 .driver_data = (void *) &(enum oxp_board) {aok_zoe_a1}, 62 + }, 63 + { 64 + .matches = { 65 + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), 66 + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR"), 67 + }, 68 + .driver_data = (void *) &(enum oxp_board) {aya_neo_air}, 69 + }, 70 + { 71 + .matches = { 72 + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), 73 + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR Pro"), 74 + }, 75 + .driver_data = (void *) &(enum oxp_board) {aya_neo_air_pro}, 64 76 }, 65 77 { 66 78 .matches = { ··· 177 161 ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val); 178 162 if (ret) 179 163 return ret; 180 - if (board == oxp_mini_amd) 164 + switch (board) { 165 + case aya_neo_air: 166 + case aya_neo_air_pro: 167 + case oxp_mini_amd: 181 168 *val = (*val * 255) / 100; 169 + break; 170 + case oxp_mini_amd_pro: 171 + case aok_zoe_a1: 172 + default: 173 + break; 174 + } 182 175 return 0; 183 176 case hwmon_pwm_enable: 184 177 return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val); ··· 216 191 case hwmon_pwm_input: 217 192 if (val < 0 || val > 255) 218 193 return -EINVAL; 219 - if (board == oxp_mini_amd) 194 + switch (board) { 195 + case aya_neo_air: 196 + case aya_neo_air_pro: 197 + case oxp_mini_amd: 220 198 val = (val * 100) / 255; 199 + break; 200 + case aok_zoe_a1: 201 + case oxp_mini_amd_pro: 202 + default: 203 + break; 204 + } 221 205 return write_to_ec(dev, OXP_SENSOR_PWM_REG, val); 222 206 default: 223 207 break; ··· 267 233 268 234 /* 269 235 * Have to check for AMD processor here because DMI strings are the 270 - * same between Intel and AMD boards, the only way to tell them appart 236 + * same between Intel and AMD boards, the only way to tell them apart 271 237 * is the CPU. 272 238 * Intel boards seem to have different EC registers and values to 273 239 * read/write.
+1 -1
drivers/hwmon/peci/cputemp.c
··· 402 402 unsigned long core_max = find_last_bit(priv->core_mask, CORE_NUMS_MAX); 403 403 int i; 404 404 405 - priv->coretemp_label = devm_kzalloc(priv->dev, core_max * sizeof(char *), GFP_KERNEL); 405 + priv->coretemp_label = devm_kzalloc(priv->dev, (core_max + 1) * sizeof(char *), GFP_KERNEL); 406 406 if (!priv->coretemp_label) 407 407 return -ENOMEM; 408 408
+34 -2
drivers/hwmon/pmbus/Kconfig
··· 237 237 be called max16064. 238 238 239 239 config SENSORS_MAX16601 240 - tristate "Maxim MAX16508, MAX16601, MAX16602" 240 + tristate "Maxim MAX16508, MAX16600, MAX16601, and MAX16602" 241 241 help 242 242 If you say yes here you get hardware monitoring support for Maxim 243 - MAX16508, MAX16601 and MAX16602. 243 + MAX16508, MAX16600, MAX16601, and MAX16602. 244 244 245 245 This driver can also be built as a module. If so, the module will 246 246 be called max16601. ··· 317 317 This driver can also be built as a module. If so, the module will 318 318 be called mp5023. 319 319 320 + config SENSORS_MPQ7932_REGULATOR 321 + bool "Regulator support for MPQ7932" 322 + depends on SENSORS_MPQ7932 && REGULATOR 323 + help 324 + If you say yes here you get six integrated buck converter regulator 325 + support for power management IC MPS MPQ7932. 326 + 327 + config SENSORS_MPQ7932 328 + tristate "MPS MPQ7932" 329 + help 330 + If you say yes here you get hardware monitoring functionality support 331 + for power management IC MPS MPQ7932. 332 + 333 + This driver can also be built as a module. If so, the module will 334 + be called mpq7932. 335 + 320 336 config SENSORS_PIM4328 321 337 tristate "Flex PIM4328 and compatibles" 322 338 help ··· 394 378 395 379 This driver can also be built as a module. If so, the module will 396 380 be called stpddc60. 381 + 382 + config SENSORS_TDA38640 383 + tristate "Infineon TDA38640" 384 + help 385 + If you say yes here you get hardware monitoring support for Infineon 386 + TDA38640. 387 + 388 + This driver can also be built as a module. If so, the module will 389 + be called tda38640. 390 + 391 + config SENSORS_TDA38640_REGULATOR 392 + bool "Regulator support for TDA38640 and compatibles" 393 + depends on SENSORS_TDA38640 && REGULATOR 394 + help 395 + If you say yes here you get regulator support for Infineon 396 + TDA38640 as regulator. 397 397 398 398 config SENSORS_TPS40422 399 399 tristate "TI TPS40422"
+2
drivers/hwmon/pmbus/Makefile
··· 34 34 obj-$(CONFIG_SENSORS_MP2888) += mp2888.o 35 35 obj-$(CONFIG_SENSORS_MP2975) += mp2975.o 36 36 obj-$(CONFIG_SENSORS_MP5023) += mp5023.o 37 + obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o 37 38 obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o 38 39 obj-$(CONFIG_SENSORS_PM6764TR) += pm6764tr.o 39 40 obj-$(CONFIG_SENSORS_PXE1610) += pxe1610.o 40 41 obj-$(CONFIG_SENSORS_Q54SJ108A2) += q54sj108a2.o 41 42 obj-$(CONFIG_SENSORS_STPDDC60) += stpddc60.o 43 + obj-$(CONFIG_SENSORS_TDA38640) += tda38640.o 42 44 obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o 43 45 obj-$(CONFIG_SENSORS_TPS53679) += tps53679.o 44 46 obj-$(CONFIG_SENSORS_TPS546D24) += tps546d24.o
+8 -8
drivers/hwmon/pmbus/ltc2978.c
··· 570 570 #define LTC2978_N_VOLTAGES ((LTC2978_MAX_UV / LTC2978_UV_STEP) + 1) 571 571 572 572 static const struct regulator_desc ltc2978_reg_desc[] = { 573 - PMBUS_REGULATOR_STEP("vout", 0, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 574 - PMBUS_REGULATOR_STEP("vout", 1, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 575 - PMBUS_REGULATOR_STEP("vout", 2, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 576 - PMBUS_REGULATOR_STEP("vout", 3, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 577 - PMBUS_REGULATOR_STEP("vout", 4, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 578 - PMBUS_REGULATOR_STEP("vout", 5, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 579 - PMBUS_REGULATOR_STEP("vout", 6, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 580 - PMBUS_REGULATOR_STEP("vout", 7, LTC2978_N_VOLTAGES, LTC2978_UV_STEP), 573 + PMBUS_REGULATOR_STEP("vout", 0, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 574 + PMBUS_REGULATOR_STEP("vout", 1, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 575 + PMBUS_REGULATOR_STEP("vout", 2, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 576 + PMBUS_REGULATOR_STEP("vout", 3, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 577 + PMBUS_REGULATOR_STEP("vout", 4, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 578 + PMBUS_REGULATOR_STEP("vout", 5, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 579 + PMBUS_REGULATOR_STEP("vout", 6, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 580 + PMBUS_REGULATOR_STEP("vout", 7, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0), 581 581 }; 582 582 583 583 static const struct regulator_desc ltc2978_reg_desc_default[] = {
+9 -5
drivers/hwmon/pmbus/max16601.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Hardware monitoring driver for Maxim MAX16508, MAX16601 and MAX16602. 3 + * Hardware monitoring driver for Maxim MAX16508, MAX16600, MAX16601, 4 + * and MAX16602. 4 5 * 5 6 * Implementation notes: 6 7 * ··· 32 31 33 32 #include "pmbus.h" 34 33 35 - enum chips { max16508, max16601, max16602 }; 34 + enum chips { max16508, max16600, max16601, max16602 }; 36 35 37 36 #define REG_DEFAULT_NUM_POP 0xc4 38 37 #define REG_SETPT_DVID 0xd1 ··· 203 202 else 204 203 info->vrm_version[0] = vr12; 205 204 206 - if (data->id != max16601 && data->id != max16602) 205 + if (data->id != max16600 && data->id != max16601 && data->id != max16602) 207 206 return 0; 208 207 209 208 reg = i2c_smbus_read_byte_data(client, REG_DEFAULT_NUM_POP); ··· 264 263 265 264 static const struct i2c_device_id max16601_id[] = { 266 265 {"max16508", max16508}, 266 + {"max16600", max16600}, 267 267 {"max16601", max16601}, 268 268 {"max16602", max16602}, 269 269 {} ··· 283 281 return -ENODEV; 284 282 285 283 /* 286 - * PMBUS_IC_DEVICE_ID is expected to return "MAX16601y.xx" or 287 - * MAX16602y.xx or "MAX16500y.xx".cdxxcccccccccc 284 + * PMBUS_IC_DEVICE_ID is expected to return MAX1660[012]y.xx" or 285 + * "MAX16500y.xx".cdxxcccccccccc 288 286 */ 289 287 if (!strncmp(buf, "MAX16500", 8)) { 290 288 id = max16508; 289 + } else if (!strncmp(buf, "MAX16600", 8)) { 290 + id = max16600; 291 291 } else if (!strncmp(buf, "MAX16601", 8)) { 292 292 id = max16601; 293 293 } else if (!strncmp(buf, "MAX16602", 8)) {
+156
drivers/hwmon/pmbus/mpq7932.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * mpq7932.c - hwmon with optional regulator driver for mps mpq7932 4 + * Copyright 2022 Monolithic Power Systems, Inc 5 + * 6 + * Author: Saravanan Sekar <saravanan@linumiz.com> 7 + */ 8 + 9 + #include <linux/bits.h> 10 + #include <linux/err.h> 11 + #include <linux/i2c.h> 12 + #include <linux/init.h> 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/of_device.h> 16 + #include <linux/pmbus.h> 17 + #include "pmbus.h" 18 + 19 + #define MPQ7932_BUCK_UV_MIN 206250 20 + #define MPQ7932_UV_STEP 6250 21 + #define MPQ7932_N_VOLTAGES 256 22 + #define MPQ7932_VOUT_MAX 0xFF 23 + #define MPQ7932_NUM_PAGES 6 24 + 25 + #define MPQ7932_TON_DELAY 0x60 26 + #define MPQ7932_VOUT_STARTUP_SLEW 0xA3 27 + #define MPQ7932_VOUT_SHUTDOWN_SLEW 0xA5 28 + #define MPQ7932_VOUT_SLEW_MASK GENMASK(1, 0) 29 + #define MPQ7932_TON_DELAY_MASK GENMASK(4, 0) 30 + 31 + struct mpq7932_data { 32 + struct pmbus_driver_info info; 33 + struct pmbus_platform_data pdata; 34 + }; 35 + 36 + #if IS_ENABLED(CONFIG_SENSORS_MPQ7932_REGULATOR) 37 + static struct regulator_desc mpq7932_regulators_desc[] = { 38 + PMBUS_REGULATOR_STEP("buck", 0, MPQ7932_N_VOLTAGES, 39 + MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN), 40 + PMBUS_REGULATOR_STEP("buck", 1, MPQ7932_N_VOLTAGES, 41 + MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN), 42 + PMBUS_REGULATOR_STEP("buck", 2, MPQ7932_N_VOLTAGES, 43 + MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN), 44 + PMBUS_REGULATOR_STEP("buck", 3, MPQ7932_N_VOLTAGES, 45 + MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN), 46 + PMBUS_REGULATOR_STEP("buck", 4, MPQ7932_N_VOLTAGES, 47 + MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN), 48 + PMBUS_REGULATOR_STEP("buck", 5, MPQ7932_N_VOLTAGES, 49 + MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN), 50 + }; 51 + #endif 52 + 53 + static int mpq7932_write_word_data(struct i2c_client *client, int page, int reg, 54 + u16 word) 55 + { 56 + switch (reg) { 57 + /* 58 + * chip supports only byte access for VOUT_COMMAND otherwise 59 + * access results -EREMOTEIO 60 + */ 61 + case PMBUS_VOUT_COMMAND: 62 + return pmbus_write_byte_data(client, page, reg, word & 0xFF); 63 + 64 + default: 65 + return -ENODATA; 66 + } 67 + } 68 + 69 + static int mpq7932_read_word_data(struct i2c_client *client, int page, 70 + int phase, int reg) 71 + { 72 + switch (reg) { 73 + /* 74 + * chip supports neither (PMBUS_VOUT_MARGIN_HIGH, PMBUS_VOUT_MARGIN_LOW) 75 + * nor (PMBUS_MFR_VOUT_MIN, PMBUS_MFR_VOUT_MAX). As a result set voltage 76 + * fails due to error in pmbus_regulator_get_low_margin, so faked. 77 + */ 78 + case PMBUS_MFR_VOUT_MIN: 79 + return 0; 80 + 81 + case PMBUS_MFR_VOUT_MAX: 82 + return MPQ7932_VOUT_MAX; 83 + 84 + /* 85 + * chip supports only byte access for VOUT_COMMAND otherwise 86 + * access results in -EREMOTEIO 87 + */ 88 + case PMBUS_READ_VOUT: 89 + return pmbus_read_byte_data(client, page, PMBUS_VOUT_COMMAND); 90 + 91 + default: 92 + return -ENODATA; 93 + } 94 + } 95 + 96 + static int mpq7932_probe(struct i2c_client *client) 97 + { 98 + struct mpq7932_data *data; 99 + struct pmbus_driver_info *info; 100 + struct device *dev = &client->dev; 101 + int i; 102 + 103 + data = devm_kzalloc(dev, sizeof(struct mpq7932_data), GFP_KERNEL); 104 + if (!data) 105 + return -ENOMEM; 106 + 107 + info = &data->info; 108 + info->pages = MPQ7932_NUM_PAGES; 109 + info->format[PSC_VOLTAGE_OUT] = direct; 110 + info->m[PSC_VOLTAGE_OUT] = 160; 111 + info->b[PSC_VOLTAGE_OUT] = -33; 112 + for (i = 0; i < info->pages; i++) { 113 + info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 114 + | PMBUS_HAVE_STATUS_TEMP; 115 + } 116 + 117 + #if IS_ENABLED(CONFIG_SENSORS_MPQ7932_REGULATOR) 118 + info->num_regulators = ARRAY_SIZE(mpq7932_regulators_desc); 119 + info->reg_desc = mpq7932_regulators_desc; 120 + #endif 121 + 122 + info->read_word_data = mpq7932_read_word_data; 123 + info->write_word_data = mpq7932_write_word_data; 124 + 125 + data->pdata.flags = PMBUS_NO_CAPABILITY; 126 + dev->platform_data = &data->pdata; 127 + 128 + return pmbus_do_probe(client, info); 129 + } 130 + 131 + static const struct of_device_id mpq7932_of_match[] = { 132 + { .compatible = "mps,mpq7932"}, 133 + {}, 134 + }; 135 + MODULE_DEVICE_TABLE(of, mpq7932_of_match); 136 + 137 + static const struct i2c_device_id mpq7932_id[] = { 138 + { "mpq7932", }, 139 + { }, 140 + }; 141 + MODULE_DEVICE_TABLE(i2c, mpq7932_id); 142 + 143 + static struct i2c_driver mpq7932_regulator_driver = { 144 + .driver = { 145 + .name = "mpq7932", 146 + .of_match_table = mpq7932_of_match, 147 + }, 148 + .probe_new = mpq7932_probe, 149 + .id_table = mpq7932_id, 150 + }; 151 + module_i2c_driver(mpq7932_regulator_driver); 152 + 153 + MODULE_AUTHOR("Saravanan Sekar <saravanan@linumiz.com>"); 154 + MODULE_DESCRIPTION("MPQ7932 PMIC regulator driver"); 155 + MODULE_LICENSE("GPL"); 156 + MODULE_IMPORT_NS(PMBUS);
+3 -2
drivers/hwmon/pmbus/pmbus.h
··· 464 464 extern const struct regulator_ops pmbus_regulator_ops; 465 465 466 466 /* Macros for filling in array of struct regulator_desc */ 467 - #define PMBUS_REGULATOR_STEP(_name, _id, _voltages, _step) \ 467 + #define PMBUS_REGULATOR_STEP(_name, _id, _voltages, _step, _min_uV) \ 468 468 [_id] = { \ 469 469 .name = (_name # _id), \ 470 470 .id = (_id), \ ··· 475 475 .owner = THIS_MODULE, \ 476 476 .n_voltages = _voltages, \ 477 477 .uV_step = _step, \ 478 + .min_uV = _min_uV, \ 478 479 } 479 480 480 - #define PMBUS_REGULATOR(_name, _id) PMBUS_REGULATOR_STEP(_name, _id, 0, 0) 481 + #define PMBUS_REGULATOR(_name, _id) PMBUS_REGULATOR_STEP(_name, _id, 0, 0, 0) 481 482 482 483 /* Function declarations */ 483 484
+74
drivers/hwmon/pmbus/tda38640.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Hardware monitoring driver for Infineon TDA38640 4 + * 5 + * Copyright (c) 2023 9elements GmbH 6 + * 7 + */ 8 + 9 + #include <linux/err.h> 10 + #include <linux/i2c.h> 11 + #include <linux/init.h> 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/regulator/driver.h> 15 + #include "pmbus.h" 16 + 17 + static const struct regulator_desc __maybe_unused tda38640_reg_desc[] = { 18 + PMBUS_REGULATOR("vout", 0), 19 + }; 20 + 21 + static struct pmbus_driver_info tda38640_info = { 22 + .pages = 1, 23 + .format[PSC_VOLTAGE_IN] = linear, 24 + .format[PSC_VOLTAGE_OUT] = linear, 25 + .format[PSC_CURRENT_OUT] = linear, 26 + .format[PSC_CURRENT_IN] = linear, 27 + .format[PSC_POWER] = linear, 28 + .format[PSC_TEMPERATURE] = linear, 29 + 30 + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT 31 + | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP 32 + | PMBUS_HAVE_IIN 33 + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 34 + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 35 + | PMBUS_HAVE_POUT | PMBUS_HAVE_PIN, 36 + #if IS_ENABLED(CONFIG_SENSORS_TDA38640_REGULATOR) 37 + .num_regulators = 1, 38 + .reg_desc = tda38640_reg_desc, 39 + #endif 40 + }; 41 + 42 + static int tda38640_probe(struct i2c_client *client) 43 + { 44 + return pmbus_do_probe(client, &tda38640_info); 45 + } 46 + 47 + static const struct i2c_device_id tda38640_id[] = { 48 + {"tda38640", 0}, 49 + {} 50 + }; 51 + MODULE_DEVICE_TABLE(i2c, tda38640_id); 52 + 53 + static const struct of_device_id __maybe_unused tda38640_of_match[] = { 54 + { .compatible = "infineon,tda38640"}, 55 + { }, 56 + }; 57 + MODULE_DEVICE_TABLE(of, tda38640_of_match); 58 + 59 + /* This is the driver that will be inserted */ 60 + static struct i2c_driver tda38640_driver = { 61 + .driver = { 62 + .name = "tda38640", 63 + .of_match_table = of_match_ptr(tda38640_of_match), 64 + }, 65 + .probe_new = tda38640_probe, 66 + .id_table = tda38640_id, 67 + }; 68 + 69 + module_i2c_driver(tda38640_driver); 70 + 71 + MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>"); 72 + MODULE_DESCRIPTION("PMBus driver for Infineon TDA38640"); 73 + MODULE_LICENSE("GPL"); 74 + MODULE_IMPORT_NS(PMBUS);
+4 -4
drivers/hwmon/sht15.c
··· 668 668 } 669 669 670 670 /** 671 - * sht15_show_status() - show status information in sysfs 671 + * sht15_status_show() - show status information in sysfs 672 672 * @dev: device. 673 673 * @attr: device attribute. 674 674 * @buf: sysfs buffer where information is written to. ··· 690 690 } 691 691 692 692 /** 693 - * sht15_store_heater() - change heater state via sysfs 693 + * sht15_status_store() - change heater state via sysfs 694 694 * @dev: device. 695 695 * @attr: device attribute. 696 696 * @buf: sysfs buffer to read the new heater state from. ··· 725 725 } 726 726 727 727 /** 728 - * sht15_show_temp() - show temperature measurement value in sysfs 728 + * sht15_temp_show() - show temperature measurement value in sysfs 729 729 * @dev: device. 730 730 * @attr: device attribute. 731 731 * @buf: sysfs buffer where measurement values are written to. ··· 747 747 } 748 748 749 749 /** 750 - * sht15_show_humidity() - show humidity measurement value in sysfs 750 + * sht15_humidity_show() - show humidity measurement value in sysfs 751 751 * @dev: device. 752 752 * @attr: device attribute. 753 753 * @buf: sysfs buffer where measurement values are written to.
+2 -2
drivers/hwmon/sht21.c
··· 114 114 } 115 115 116 116 /** 117 - * sht21_show_temperature() - show temperature measurement value in sysfs 117 + * sht21_temperature_show() - show temperature measurement value in sysfs 118 118 * @dev: device 119 119 * @attr: device attribute 120 120 * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to ··· 136 136 } 137 137 138 138 /** 139 - * sht21_show_humidity() - show humidity measurement value in sysfs 139 + * sht21_humidity_show() - show humidity measurement value in sysfs 140 140 * @dev: device 141 141 * @attr: device attribute 142 142 * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to
+4
include/linux/hwmon.h
··· 436 436 /* hwmon_device_register() is deprecated */ 437 437 struct device *hwmon_device_register(struct device *dev); 438 438 439 + /* 440 + * hwmon_device_register_with_groups() and 441 + * devm_hwmon_device_register_with_groups() are deprecated. 442 + */ 439 443 struct device * 440 444 hwmon_device_register_with_groups(struct device *dev, const char *name, 441 445 void *drvdata,