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

Configure Feed

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

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

Pull hwmon updates from Guenter Roeck:
"New drivers:
- pmbus: Support for MPS Multi-phase mp2856/mp2857 controller
- pmbus: Support for MPS Multi-phase mp5990
- Driver for Gigabyte AORUS Waterforce AIO coolers

Added support to existing drivers:
- lm75: Support for AMS AS6200 temperature sensor
- k10temp: Support for AMD Family 19h Model 8h
- max31827: Support for max31828 and max31829
- sht3x: Support for sts3x
- Add support for WMI SMM interface, and various related improvements.
Add support for Optiplex 7000
- emc1403: Support for EMC1442
- npcm750-pwm-fan: Support for NPCM8xx
- nct6775: Add support for 2 additional fan controls

Minor improvements and bug fixes:
- gigabyte_waterforce: Mark status report as received under a spinlock
- aquacomputer_d5next: Remove unneeded CONFIG_DEBUG_FS #ifdef
- gpio-fan: Convert txt bindings to yaml
- smsc47m1: Various cleanups / improvements
- corsair-cpro: use NULL instead of 0
- hp-wmi-sensors: Fix failure to load on EliteDesk 800 G6
- tmp513: Various cleanups
- peci/dimmtemp: Bump timeout
- pc87360: Bounds check data->innr usage
- nct6775: Fix fan speed set failure in automatic mode
- ABI: sysfs-class-hwmon: document various missing attributes
- lm25066, max6650, nct6775: Use i2c_get_match_data()
- aspeed-pwm-tacho: Fix -Wstringop-overflow warning"

* tag 'hwmon-for-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (59 commits)
hwmon: (gigabyte_waterforce) Mark status report as received under a spinlock
hwmon: (lm75) Fix tmp112 default config
hwmon: (lm75) Add AMS AS6200 temperature sensor
dt-bindings: hwmon: (lm75) Add AMS AS6200 temperature sensor
hwmon: (lm75) remove now-unused include
hwmon: (pmbus) Add support for MPS Multi-phase mp2856/mp2857 controller
dt-bindings: Add MP2856/MP2857 voltage regulator device
hwmon: (aquacomputer_d5next) Remove unneeded CONFIG_DEBUG_FS #ifdef
dt-bindings: hwmon: gpio-fan: Convert txt bindings to yaml
hwmon: (k10temp) Add support for AMD Family 19h Model 8h
hwmon: Add driver for Gigabyte AORUS Waterforce AIO coolers
hwmon: (smsc47m1) Rename global platform device variable
hwmon: (smsc47m1) Simplify device registration
hwmon: (smsc47m1) Convert to platform remove callback returning void
hwmon: (smsc47m1) Mark driver struct with __refdata to prevent section mismatch
MAINTAINERS: Add maintainer for Baikal-T1 PVT hwmon driver
hwmon: (sht3x) add sts3x support
hwmon: (pmbus) Add ltc4286 driver
dt-bindings: hwmon: Add lltc ltc4286 driver bindings
hwmon: (max31827) Add custom attribute for resolution
...

+3066 -499
+100 -10
Documentation/ABI/testing/sysfs-class-hwmon
··· 381 381 382 382 RW 383 383 384 + What: /sys/class/hwmon/hwmonX/tempY_max_alarm 385 + Description: 386 + Maximum temperature alarm flag. 387 + 388 + - 0: OK 389 + - 1: temperature has reached tempY_max 390 + 391 + RO 392 + 384 393 What: /sys/class/hwmon/hwmonX/tempY_min 385 394 Description: 386 395 Temperature min value. ··· 397 388 Unit: millidegree Celsius 398 389 399 390 RW 391 + 392 + What: /sys/class/hwmon/hwmonX/tempY_min_alarm 393 + Description: 394 + Minimum temperature alarm flag. 395 + 396 + - 0: OK 397 + - 1: temperature has reached tempY_min 398 + 399 + RO 400 400 401 401 What: /sys/class/hwmon/hwmonX/tempY_max_hyst 402 402 Description: ··· 452 434 - 0: OK 453 435 - 1: temperature has reached tempY_crit 454 436 455 - RW 456 - 457 - Contrary to regular alarm flags which clear themselves 458 - automatically when read, this one sticks until cleared by 459 - the user. This is done by writing 0 to the file. Writing 460 - other values is unsupported. 437 + RO 461 438 462 439 What: /sys/class/hwmon/hwmonX/tempY_crit_hyst 463 440 Description: ··· 474 461 Unit: millidegree Celsius 475 462 476 463 RW 464 + 465 + What: /sys/class/hwmon/hwmonX/tempY_emergency_alarm 466 + Description: 467 + Emergency high temperature alarm flag. 468 + 469 + - 0: OK 470 + - 1: temperature has reached tempY_emergency 471 + 472 + RO 477 473 478 474 What: /sys/class/hwmon/hwmonX/tempY_emergency_hyst 479 475 Description: ··· 909 887 910 888 RW 911 889 912 - What: /sys/class/hwmon/hwmonX/humidityY_input 890 + What: /sys/class/hwmon/hwmonX/humidityY_alarm 913 891 Description: 914 - Humidity 892 + Humidity limit detection 915 893 916 - Unit: milli-percent (per cent mille, pcm) 894 + - 0: OK 895 + - 1: Humidity limit has been reached 917 896 918 897 RO 919 - 920 898 921 899 What: /sys/class/hwmon/hwmonX/humidityY_enable 922 900 Description: ··· 927 905 928 906 - 1: Enable 929 907 - 0: Disable 908 + 909 + RW 910 + 911 + What: /sys/class/hwmon/hwmonX/humidityY_fault 912 + Description: 913 + Reports a humidity sensor failure. 914 + 915 + - 1: Failed 916 + - 0: Ok 917 + 918 + RO 919 + 920 + What: /sys/class/hwmon/hwmonX/humidityY_input 921 + Description: 922 + Humidity 923 + 924 + Unit: milli-percent (per cent mille, pcm) 925 + 926 + RO 927 + 928 + What: /sys/class/hwmon/hwmonX/humidityY_label 929 + Description: 930 + Suggested humidity channel label. 931 + 932 + Text string 933 + 934 + Should only be created if the driver has hints about what 935 + this humidity channel is being used for, and user-space 936 + doesn't. In all other cases, the label is provided by 937 + user-space. 938 + 939 + RO 940 + 941 + What: /sys/class/hwmon/hwmonX/humidityY_max 942 + Description: 943 + Humidity max value. 944 + 945 + Unit: milli-percent (per cent mille, pcm) 946 + 947 + RW 948 + 949 + What: /sys/class/hwmon/hwmonX/humidityY_max_hyst 950 + Description: 951 + Humidity hysteresis value for max limit. 952 + 953 + Unit: milli-percent (per cent mille, pcm) 954 + 955 + Must be reported as an absolute humidity, NOT a delta 956 + from the max value. 957 + 958 + RW 959 + 960 + What: /sys/class/hwmon/hwmonX/humidityY_min 961 + Description: 962 + Humidity min value. 963 + 964 + Unit: milli-percent (per cent mille, pcm) 965 + 966 + RW 967 + 968 + What: /sys/class/hwmon/hwmonX/humidityY_min_hyst 969 + Description: 970 + Humidity hysteresis value for min limit. 971 + 972 + Unit: milli-percent (per cent mille, pcm) 973 + 974 + Must be reported as an absolute humidity, NOT a delta 975 + from the min value. 930 976 931 977 RW 932 978
-41
Documentation/devicetree/bindings/hwmon/gpio-fan.txt
··· 1 - Bindings for fan connected to GPIO lines 2 - 3 - Required properties: 4 - - compatible : "gpio-fan" 5 - 6 - Optional properties: 7 - - gpios: Specifies the pins that map to bits in the control value, 8 - ordered MSB-->LSB. 9 - - gpio-fan,speed-map: A mapping of possible fan RPM speeds and the 10 - control value that should be set to achieve them. This array 11 - must have the RPM values in ascending order. 12 - - alarm-gpios: This pin going active indicates something is wrong with 13 - the fan, and a udev event will be fired. 14 - - #cooling-cells: If used as a cooling device, must be <2> 15 - Also see: 16 - Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml 17 - min and max states are derived from the speed-map of the fan. 18 - 19 - Note: At least one the "gpios" or "alarm-gpios" properties must be set. 20 - 21 - Examples: 22 - 23 - gpio_fan { 24 - compatible = "gpio-fan"; 25 - gpios = <&gpio1 14 1 26 - &gpio1 13 1>; 27 - gpio-fan,speed-map = <0 0 28 - 3000 1 29 - 6000 2>; 30 - alarm-gpios = <&gpio1 15 1>; 31 - }; 32 - gpio_fan_cool: gpio_fan { 33 - compatible = "gpio-fan"; 34 - gpios = <&gpio2 14 1 35 - &gpio2 13 1>; 36 - gpio-fan,speed-map = <0 0>, 37 - <3000 1>, 38 - <6000 2>; 39 - alarm-gpios = <&gpio2 15 1>; 40 - #cooling-cells = <2>; /* min followed by max */ 41 - };
+60
Documentation/devicetree/bindings/hwmon/gpio-fan.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/hwmon/gpio-fan.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Fan connected to GPIO lines 8 + 9 + maintainers: 10 + - Rob Herring <robh@kernel.org> 11 + 12 + properties: 13 + compatible: 14 + const: gpio-fan 15 + 16 + gpios: 17 + description: | 18 + Specifies the pins that map to bits in the control value, 19 + ordered MSB-->LSB. 20 + minItems: 1 21 + maxItems: 7 22 + 23 + alarm-gpios: 24 + maxItems: 1 25 + 26 + gpio-fan,speed-map: 27 + $ref: /schemas/types.yaml#/definitions/uint32-matrix 28 + minItems: 2 29 + maxItems: 127 30 + items: 31 + items: 32 + - description: fan speed in RPMs 33 + - description: control value 34 + description: | 35 + A mapping of possible fan RPM speeds and the 36 + control value that should be set to achieve them. This array 37 + must have the RPM values in ascending order. 38 + 39 + '#cooling-cells': 40 + const: 2 41 + 42 + required: 43 + - compatible 44 + - gpios 45 + - gpio-fan,speed-map 46 + 47 + additionalProperties: false 48 + 49 + examples: 50 + - | 51 + gpio-fan { 52 + compatible = "gpio-fan"; 53 + gpios = <&gpio2 14 1 54 + &gpio2 13 1>; 55 + gpio-fan,speed-map = < 0 0>, 56 + <3000 1>, 57 + <6000 2>; 58 + alarm-gpios = <&gpio2 15 1>; 59 + #cooling-cells = <2>; /* min followed by max */ 60 + };
+1 -1
Documentation/devicetree/bindings/hwmon/iio-hwmon.yaml
··· 19 19 20 20 io-channels: 21 21 minItems: 1 22 - maxItems: 8 # Should be enough 22 + maxItems: 51 # Should be enough 23 23 description: > 24 24 List of phandles to ADC channels to read the monitoring values 25 25
+50
Documentation/devicetree/bindings/hwmon/lltc,ltc4286.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/lltc,ltc4286.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: LTC4286 power monitors 8 + 9 + maintainers: 10 + - Delphine CC Chiu <Delphine_CC_Chiu@Wiwynn.com> 11 + 12 + properties: 13 + compatible: 14 + enum: 15 + - lltc,ltc4286 16 + - lltc,ltc4287 17 + 18 + reg: 19 + maxItems: 1 20 + 21 + adi,vrange-low-enable: 22 + description: 23 + This property is a bool parameter to represent the 24 + voltage range is 25.6 volts or 102.4 volts for this chip. 25 + The default is 102.4 volts. 26 + type: boolean 27 + 28 + shunt-resistor-micro-ohms: 29 + description: 30 + Resistor value micro-ohms. 31 + 32 + required: 33 + - compatible 34 + - reg 35 + 36 + additionalProperties: false 37 + 38 + examples: 39 + - | 40 + i2c { 41 + #address-cells = <1>; 42 + #size-cells = <0>; 43 + 44 + power-monitor@40 { 45 + compatible = "lltc,ltc4286"; 46 + reg = <0x40>; 47 + adi,vrange-low-enable; 48 + shunt-resistor-micro-ohms = <300>; 49 + }; 50 + };
+33
Documentation/devicetree/bindings/hwmon/lm75.yaml
··· 14 14 compatible: 15 15 enum: 16 16 - adi,adt75 17 + - ams,as6200 17 18 - atmel,at30ts74 18 19 - dallas,ds1775 19 20 - dallas,ds75 ··· 49 48 vs-supply: 50 49 description: phandle to the regulator that provides the +VS supply 51 50 51 + interrupts: 52 + maxItems: 1 53 + 52 54 required: 53 55 - compatible 54 56 - reg 57 + 58 + allOf: 59 + - if: 60 + not: 61 + properties: 62 + compatible: 63 + contains: 64 + enum: 65 + - ams,as6200 66 + - ti,tmp100 67 + - ti,tmp101 68 + - ti,tmp112 69 + then: 70 + properties: 71 + interrupts: false 55 72 56 73 additionalProperties: false 57 74 ··· 83 64 compatible = "st,stlm75"; 84 65 reg = <0x48>; 85 66 vs-supply = <&vs>; 67 + }; 68 + }; 69 + - | 70 + #include <dt-bindings/interrupt-controller/irq.h> 71 + i2c { 72 + #address-cells = <1>; 73 + #size-cells = <0>; 74 + 75 + temperature-sensor@48 { 76 + compatible = "ams,as6200"; 77 + reg = <0x48>; 78 + vs-supply = <&vs>; 79 + interrupt-parent = <&gpio1>; 80 + interrupts = <17 IRQ_TYPE_EDGE_BOTH>; 86 81 }; 87 82 };
+6
Documentation/devicetree/bindings/trivial-devices.yaml
··· 117 117 - fsl,mpl3115 118 118 # MPR121: Proximity Capacitive Touch Sensor Controller 119 119 - fsl,mpr121 120 + # Monolithic Power Systems Inc. multi-phase controller mp2856 121 + - mps,mp2856 122 + # Monolithic Power Systems Inc. multi-phase controller mp2857 123 + - mps,mp2857 120 124 # Monolithic Power Systems Inc. multi-phase controller mp2888 121 125 - mps,mp2888 122 126 # Monolithic Power Systems Inc. multi-phase controller mp2971 ··· 129 125 - mps,mp2973 130 126 # Monolithic Power Systems Inc. multi-phase controller mp2975 131 127 - mps,mp2975 128 + # Monolithic Power Systems Inc. multi-phase hot-swap controller mp5990 129 + - mps,mp5990 132 130 # Honeywell Humidicon HIH-6130 humidity/temperature sensor 133 131 - honeywell,hi6130 134 132 # IBM Common Form Factor Power Supply Versions (all versions)
+35 -3
Documentation/hwmon/dell-smm-hwmon.rst
··· 186 186 The driver uses the SMM interface to send commands to the system BIOS. 187 187 This interface is normally used by Dell's 32-bit diagnostic program or 188 188 on newer notebook models by the buildin BIOS diagnostics. 189 - The SMM is triggered by writing to the special ioports ``0xb2`` and ``0x84``, 190 - and may cause short hangs when the BIOS code is taking too long to 189 + The SMM may cause short hangs when the BIOS code is taking too long to 191 190 execute. 192 191 193 192 The SMM handler inside the system BIOS looks at the contents of the ··· 209 210 210 211 - setting the lower sixteen bits of ``eax`` to ``0xffff`` 211 212 - not modifying ``eax`` at all 212 - - setting the carry flag 213 + - setting the carry flag (legacy SMM interface only) 214 + 215 + Legacy SMM Interface 216 + -------------------- 217 + 218 + When using the legacy SMM interface, a SMM is triggered by writing the least significant byte 219 + of the command code to the special ioports ``0xb2`` and ``0x84``. This interface is not 220 + described inside the ACPI tables and can thus only be detected by issuing a test SMM call. 221 + 222 + WMI SMM Interface 223 + ----------------- 224 + 225 + On modern Dell machines, the SMM calls are done over ACPI WMI: 226 + 227 + :: 228 + 229 + #pragma namespace("\\\\.\\root\\dcim\\sysman\\diagnostics") 230 + [WMI, Provider("Provider_DiagnosticsServices"), Dynamic, Locale("MS\\0x409"), 231 + Description("RunDellDiag"), guid("{F1DDEE52-063C-4784-A11E-8A06684B9B01}")] 232 + class LegacyDiags { 233 + [key, read] string InstanceName; 234 + [read] boolean Active; 235 + 236 + [WmiMethodId(1), Implemented, read, write, Description("Legacy Method ")] 237 + void Execute([in, out] uint32 EaxLen, [in, out, WmiSizeIs("EaxLen") : ToInstance] uint8 EaxVal[], 238 + [in, out] uint32 EbxLen, [in, out, WmiSizeIs("EbxLen") : ToInstance] uint8 EbxVal[], 239 + [in, out] uint32 EcxLen, [in, out, WmiSizeIs("EcxLen") : ToInstance] uint8 EcxVal[], 240 + [in, out] uint32 EdxLen, [in, out, WmiSizeIs("EdxLen") : ToInstance] uint8 EdxVal[]); 241 + }; 242 + 243 + Some machines support only the WMI SMM interface, while some machines support both interfaces. 244 + The driver automatically detects which interfaces are present and will use the WMI SMM interface 245 + if the legacy SMM interface is not present. The WMI SMM interface is usually slower than the 246 + legacy SMM interface since ACPI methods need to be called in order to trigger a SMM. 213 247 214 248 SMM command codes 215 249 -----------------
+47
Documentation/hwmon/gigabyte_waterforce.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver gigabyte_waterforce 4 + ================================= 5 + 6 + Supported devices: 7 + 8 + * Gigabyte AORUS WATERFORCE X240 9 + * Gigabyte AORUS WATERFORCE X280 10 + * Gigabyte AORUS WATERFORCE X360 11 + 12 + Author: Aleksa Savic 13 + 14 + Description 15 + ----------- 16 + 17 + This driver enables hardware monitoring support for the listed Gigabyte Waterforce 18 + all-in-one CPU liquid coolers. Available sensors are pump and fan speed in RPM, as 19 + well as coolant temperature. Also available through debugfs is the firmware version. 20 + 21 + Attaching a fan is optional and allows it to be controlled from the device. If 22 + it's not connected, the fan-related sensors will report zeroes. 23 + 24 + The addressable RGB LEDs and LCD screen are not supported in this driver and should 25 + be controlled through userspace tools. 26 + 27 + Usage notes 28 + ----------- 29 + 30 + As these are USB HIDs, the driver can be loaded automatically by the kernel and 31 + supports hot swapping. 32 + 33 + Sysfs entries 34 + ------------- 35 + 36 + =========== ============================================= 37 + fan1_input Fan speed (in rpm) 38 + fan2_input Pump speed (in rpm) 39 + temp1_input Coolant temperature (in millidegrees Celsius) 40 + =========== ============================================= 41 + 42 + Debugfs entries 43 + --------------- 44 + 45 + ================ ======================= 46 + firmware_version Device firmware version 47 + ================ =======================
+4
Documentation/hwmon/index.rst
··· 73 73 ftsteutates 74 74 g760a 75 75 g762 76 + gigabyte_waterforce 76 77 gsc-hwmon 77 78 gl518sm 78 79 gxp-fan-ctrl ··· 129 128 ltc4245 130 129 ltc4260 131 130 ltc4261 131 + ltc4286 132 132 max127 133 133 max15301 134 134 max16064 ··· 158 156 mcp3021 159 157 menf21bmc 160 158 mlxreg-fan 159 + mp2856 161 160 mp2888 162 161 mp2975 163 162 mp5023 163 + mp5990 164 164 nct6683 165 165 nct6775 166 166 nct7802
+10
Documentation/hwmon/lm75.rst
··· 133 133 134 134 https://www.nxp.com/docs/en/data-sheet/PCT2075.pdf 135 135 136 + * AMS OSRAM AS6200 137 + 138 + Prefix: 'as6200' 139 + 140 + Addresses scanned: none 141 + 142 + Datasheet: Publicly available at the AMS website 143 + 144 + https://ams.com/documents/20143/36005/AS6200_DS000449_4-00.pdf 145 + 136 146 Author: Frodo Looijaard <frodol@dds.nl> 137 147 138 148 Description
+95
Documentation/hwmon/ltc4286.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver ltc4286 4 + ===================== 5 + 6 + Supported chips: 7 + 8 + * Analog Devices LTC4286 9 + 10 + Prefix: 'ltc4286' 11 + 12 + Addresses scanned: - 13 + 14 + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc4286.pdf 15 + 16 + * Analog Devices LTC4287 17 + 18 + Prefix: 'ltc4287' 19 + 20 + Addresses scanned: - 21 + 22 + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc4287.pdf 23 + 24 + Author: Delphine CC Chiu <Delphine_CC_Chiu@Wiwynn.com> 25 + 26 + 27 + Description 28 + ----------- 29 + 30 + This driver supports hardware monitoring for Analog Devices LTC4286 31 + and LTC4287 Hot-Swap Controller and Digital Power Monitors. 32 + 33 + LTC4286 and LTC4287 are hot-swap controllers that allow a circuit board 34 + to be removed from or inserted into a live backplane. They also feature 35 + current and voltage readback via an integrated 12 bit analog-to-digital 36 + converter (ADC), accessed using a PMBus interface. 37 + 38 + The driver is a client driver to the core PMBus driver. Please see 39 + Documentation/hwmon/pmbus.rst for details on PMBus client drivers. 40 + 41 + 42 + Usage Notes 43 + ----------- 44 + 45 + This driver does not auto-detect devices. You will have to instantiate the 46 + devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for 47 + details. 48 + 49 + The shunt value in micro-ohms can be set via device tree at compile-time. Please 50 + refer to the Documentation/devicetree/bindings/hwmon/lltc,ltc4286.yaml for bindings 51 + if the device tree is used. 52 + 53 + 54 + Platform data support 55 + --------------------- 56 + 57 + The driver supports standard PMBus driver platform data. Please see 58 + Documentation/hwmon/pmbus.rst for details. 59 + 60 + 61 + Sysfs entries 62 + ------------- 63 + 64 + The following attributes are supported. Limits are read-write, history reset 65 + attributes are write-only, all other attributes are read-only. 66 + 67 + ======================= ======================================================= 68 + in1_label "vin" 69 + in1_input Measured voltage. 70 + in1_alarm Input voltage alarm. 71 + in1_min Minimum input voltage. 72 + in1_max Maximum input voltage. 73 + 74 + in2_label "vout1" 75 + in2_input Measured voltage. 76 + in2_alarm Output voltage alarm. 77 + in2_min Minimum output voltage. 78 + in2_max Maximum output voltage. 79 + 80 + curr1_label "iout1" 81 + curr1_input Measured current. 82 + curr1_alarm Output current alarm. 83 + curr1_max Maximum current. 84 + 85 + power1_label "pin" 86 + power1_input Input power. 87 + power1_alarm Input power alarm. 88 + power1_max Maximum poewr. 89 + 90 + temp1_input Chip temperature. 91 + temp1_min Minimum chip temperature. 92 + temp1_max Maximum chip temperature. 93 + temp1_crit Critical chip temperature. 94 + temp1_alarm Chip temperature alarm. 95 + ======================= =======================================================
+61 -14
Documentation/hwmon/max31827.rst
··· 52 52 hysteresis value: -40 and -30 degrees for under temperature alarm and +100 and 53 53 +90 degrees for over temperature alarm. 54 54 55 - The alarm can be configured in comparator and interrupt mode. Currently only 56 - comparator mode is implemented. In Comparator mode, the OT/UT status bits have a 57 - value of 1 when the temperature rises above the TH value or falls below TL, 58 - which is also subject to the Fault Queue selection. OT status returns to 0 when 59 - the temperature drops below the TH_HYST value or when shutdown mode is entered. 60 - Similarly, UT status returns to 0 when the temperature rises above TL_HYST value 61 - or when shutdown mode is entered. 55 + The alarm can be configured in comparator and interrupt mode from the 56 + devicetree. In Comparator mode, the OT/UT status bits have a value of 1 when the 57 + temperature rises above the TH value or falls below TL, which is also subject to 58 + the Fault Queue selection. OT status returns to 0 when the temperature drops 59 + below the TH_HYST value or when shutdown mode is entered. Similarly, UT status 60 + returns to 0 when the temperature rises above TL_HYST value or when shutdown 61 + mode is entered. 62 + 63 + In interrupt mode exceeding TH also sets OT status to 1, which remains set until 64 + a read operation is performed on the configuration/status register (max or min 65 + attribute); at this point, it returns to 0. Once OT status is set to 1 from 66 + exceeding TH and reset, it is set to 1 again only when the temperature drops 67 + below TH_HYST. The output remains asserted until it is reset by a read. It is 68 + set again if the temperature rises above TH, and so on. The same logic applies 69 + to the operation of the UT status bit. 62 70 63 71 Putting the MAX31827 into shutdown mode also resets the OT/UT status bits. Note 64 72 that if the mode is changed while OT/UT status bits are set, an OT/UT status ··· 76 68 77 69 The conversions can be manual with the one-shot functionality and automatic with 78 70 a set frequency. When powered on, the chip measures temperatures with 1 conv/s. 71 + The conversion rate can be modified with update_interval attribute of the chip. 72 + Conversion/second = 1/update_interval. Thus, the available options according to 73 + the data sheet are: 74 + 75 + - 64000 (ms) = 1 conv/64 sec 76 + - 32000 (ms) = 1 conv/32 sec 77 + - 16000 (ms) = 1 conv/16 sec 78 + - 4000 (ms) = 1 conv/4 sec 79 + - 1000 (ms) = 1 conv/sec (default) 80 + - 250 (ms) = 4 conv/sec 81 + - 125 (ms) = 8 conv/sec 82 + 79 83 Enabling the device when it is already enabled has the side effect of setting 80 84 the conversion frequency to 1 conv/s. The conversion time varies depending on 81 - the resolution. The conversion time doubles with every bit of increased 82 - resolution. For 10 bit resolution 35ms are needed, while for 12 bit resolution 83 - (default) 140ms. When chip is in shutdown mode and a read operation is 84 - requested, one-shot is triggered, the device waits for 140 (conversion time) ms, 85 - and only after that is the temperature value register read. 85 + the resolution. 86 + 87 + The conversion time doubles with every bit of increased resolution. The 88 + available resolutions are: 89 + 90 + - 8 bit -> 8.75 ms conversion time 91 + - 9 bit -> 17.5 ms conversion time 92 + - 10 bit -> 35 ms conversion time 93 + - 12 bit (default) -> 140 ms conversion time 94 + 95 + There is a temp1_resolution attribute which indicates the unit change in the 96 + input temperature in milli-degrees C. 97 + 98 + - 1000 mC -> 8 bit 99 + - 500 mC -> 9 bit 100 + - 250 mC -> 10 bit 101 + - 62 mC -> 12 bit (default) - actually this is 62.5, but the fil returns 62 102 + 103 + When chip is in shutdown mode and a read operation is requested, one-shot is 104 + triggered, the device waits for <conversion time> ms, and only after that is 105 + the temperature value register read. Note that the conversion times are rounded 106 + up to the nearest possible integer. 86 107 87 108 The LSB of the temperature values is 0.0625 degrees Celsius, but the values of 88 109 the temperatures are displayed in milli-degrees. This means, that some data is ··· 120 83 will always be rounded down to the nearest possible value, for negative numbers 121 84 the user-input will always be rounded up to the nearest possible value. 122 85 86 + Bus timeout resets the I2C-compatible interface when SCL is low for more than 87 + 30ms (nominal). 88 + 89 + Alarm polarity determines if the active state of the alarm is low or high. The 90 + behavior for both settings is dependent on the Fault Queue setting. The ALARM 91 + pin is an open-drain output and requires a pullup resistor to operate. 92 + 93 + The Fault Queue bits select how many consecutive temperature faults must occur 94 + before overtemperature or undertemperature faults are indicated in the 95 + corresponding status bits. 96 + 123 97 Notes 124 98 ----- 125 99 126 - Currently fault queue, alarm polarity and resolution cannot be modified. 127 - PEC is not implemented either. 100 + PEC is not implemented.
+98
Documentation/hwmon/mp2856.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + Kernel driver mp2856 4 + ==================== 5 + 6 + Supported chips: 7 + 8 + * MPS MP2856 9 + 10 + Prefix: 'mp2856' 11 + 12 + * MPS MP2857 13 + 14 + Prefix: 'mp2857' 15 + 16 + Author: 17 + 18 + Peter Yin <peter.yin@quantatw.com> 19 + 20 + Description 21 + ----------- 22 + 23 + This driver implements support for Monolithic Power Systems, Inc. (MPS) 24 + vendor dual-loop, digital, multi-phase controller MP2856/MP2857 25 + 26 + This device: 27 + 28 + - Supports up to two power rail. 29 + - Supports two pages 0 and 1 for and also pages 2 for configuration. 30 + - Can configured VOUT readout in direct or VID format and allows 31 + setting of different formats on rails 1 and 2. For VID the following 32 + protocols are available: AMD SVI3 mode with 5-mV/LSB. 33 + 34 + Device supports: 35 + 36 + - SVID interface. 37 + - AVSBus interface. 38 + 39 + Device compliant with: 40 + 41 + - PMBus rev 1.3 interface. 42 + 43 + Device supports direct format for reading output current, output voltage, 44 + input and output power and temperature. 45 + Device supports linear format for reading input voltage and input power. 46 + Device supports VID and direct formats for reading output voltage. 47 + The below VID modes are supported: AMD SVI3. 48 + 49 + The driver provides the following sysfs attributes for current measurements: 50 + 51 + - indexes 1 for "iin"; 52 + - indexes 2, 3 for "iout"; 53 + 54 + **curr[1-3]_alarm** 55 + 56 + **curr[1-3]_input** 57 + 58 + **curr[1-3]_label** 59 + 60 + The driver provides the following sysfs attributes for voltage measurements. 61 + 62 + - indexes 1 for "vin"; 63 + - indexes 2, 3 for "vout"; 64 + 65 + **in[1-3]_crit** 66 + 67 + **in[1-3]_crit_alarm** 68 + 69 + **in[1-3]_input** 70 + 71 + **in[1-3]_label** 72 + 73 + **in[1-3]_lcrit** 74 + 75 + **in[1-3]_lcrit_alarm** 76 + 77 + The driver provides the following sysfs attributes for power measurements. 78 + 79 + - indexes 1 for "pin"; 80 + - indexes 2, 3 for "pout"; 81 + 82 + **power[1-3]_alarm** 83 + 84 + **power[1-3]_input** 85 + 86 + **power[1-3]_label** 87 + 88 + The driver provides the following sysfs attributes for temperature measurements. 89 + 90 + **temp[1-2]_crit** 91 + 92 + **temp[1-2]_crit_alarm** 93 + 94 + **temp[1-2]_input** 95 + 96 + **temp[1-2]_max** 97 + 98 + **temp[1-2]_max_alarm**
+84
Documentation/hwmon/mp5990.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + Kernel driver mp5990 4 + ==================== 5 + 6 + Supported chips: 7 + 8 + * MPS MP5990 9 + 10 + Prefix: 'mp5990' 11 + 12 + * Datasheet 13 + 14 + Publicly available at the MPS website : https://www.monolithicpower.com/en/mp5990.html 15 + 16 + Author: 17 + 18 + Peter Yin <peteryin.openbmc@gmail.com> 19 + 20 + Description 21 + ----------- 22 + 23 + This driver implements support for Monolithic Power Systems, Inc. (MPS) 24 + MP5990 Hot-Swap Controller. 25 + 26 + Device compliant with: 27 + 28 + - PMBus rev 1.3 interface. 29 + 30 + Device supports direct and linear format for reading input voltage, 31 + output voltage, output current, input power and temperature. 32 + 33 + The driver exports the following attributes via the 'sysfs' files 34 + for input voltage: 35 + 36 + **in1_input** 37 + 38 + **in1_label** 39 + 40 + **in1_max** 41 + 42 + **in1_max_alarm** 43 + 44 + **in1_min** 45 + 46 + **in1_min_alarm** 47 + 48 + The driver provides the following attributes for output voltage: 49 + 50 + **in2_input** 51 + 52 + **in2_label** 53 + 54 + **in2_alarm** 55 + 56 + The driver provides the following attributes for output current: 57 + 58 + **curr1_input** 59 + 60 + **curr1_label** 61 + 62 + **curr1_alarm** 63 + 64 + **curr1_max** 65 + 66 + The driver provides the following attributes for input power: 67 + 68 + **power1_input** 69 + 70 + **power1_label** 71 + 72 + **power1_alarm** 73 + 74 + The driver provides the following attributes for temperature: 75 + 76 + **temp1_input** 77 + 78 + **temp1_max** 79 + 80 + **temp1_max_alarm** 81 + 82 + **temp1_crit** 83 + 84 + **temp1_crit_alarm**
+21 -8
Documentation/hwmon/sht3x.rst
··· 9 9 10 10 Addresses scanned: none 11 11 12 - Datasheet: https://www.sensirion.com/file/datasheet_sht3x_digital 12 + Datasheets: 13 + - https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf 14 + - https://sensirion.com/media/documents/051DF50B/639C8101/Sensirion_Humidity_and_Temperature_Sensors_Datasheet_SHT33.pdf 15 + 16 + * Sensirion STS3x-DIS 17 + 18 + Prefix: 'sts3x' 19 + 20 + Addresses scanned: none 21 + 22 + Datasheets: 23 + - https://sensirion.com/media/documents/1DA31AFD/61641F76/Sensirion_Temperature_Sensors_STS3x_Datasheet.pdf 24 + - https://sensirion.com/media/documents/292A335C/65537BAF/Sensirion_Datasheet_STS32_STS33.pdf 13 25 14 26 Author: 15 27 ··· 31 19 Description 32 20 ----------- 33 21 34 - This driver implements support for the Sensirion SHT3x-DIS chip, a humidity 35 - and temperature sensor. Temperature is measured in degrees celsius, relative 36 - humidity is expressed as a percentage. In the sysfs interface, all values are 37 - scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500. 22 + This driver implements support for the Sensirion SHT3x-DIS and STS3x-DIS 23 + series of humidity and temperature sensors. Temperature is measured in degrees 24 + celsius, relative humidity is expressed as a percentage. In the sysfs interface, 25 + all values are scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500. 38 26 39 27 The device communicates with the I2C protocol. Sensors can have the I2C 40 - addresses 0x44 or 0x45, depending on the wiring. See 41 - Documentation/i2c/instantiating-devices.rst for methods to instantiate the device. 28 + addresses 0x44 or 0x45 (0x4a or 0x4b for sts3x), depending on the wiring. See 29 + Documentation/i2c/instantiating-devices.rst for methods to instantiate the 30 + device. 42 31 43 - Even if sht3x sensor supports clock-strech(blocking mode) and non-strench 32 + Even if sht3x sensor supports clock-stretch (blocking mode) and non-stretch 44 33 (non-blocking mode) in single-shot mode, this driver only supports the latter. 45 34 46 35 The sht3x sensor supports a single shot mode as well as 5 periodic measure
+25
MAINTAINERS
··· 3451 3451 F: include/linux/backlight.h 3452 3452 F: include/linux/pwm_backlight.h 3453 3453 3454 + BAIKAL-T1 PVT HARDWARE MONITOR DRIVER 3455 + M: Serge Semin <fancer.lancer@gmail.com> 3456 + L: linux-hwmon@vger.kernel.org 3457 + S: Supported 3458 + F: Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml 3459 + F: Documentation/hwmon/bt1-pvt.rst 3460 + F: drivers/hwmon/bt1-pvt.[ch] 3461 + 3454 3462 BARCO P50 GPIO DRIVER 3455 3463 M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> 3456 3464 M: Peter Korsgaard <peter.korsgaard@barco.com> ··· 8956 8948 F: fs/gfs2/ 8957 8949 F: include/uapi/linux/gfs2_ondisk.h 8958 8950 8951 + GIGABYTE WATERFORCE SENSOR DRIVER 8952 + M: Aleksa Savic <savicaleksa83@gmail.com> 8953 + L: linux-hwmon@vger.kernel.org 8954 + S: Maintained 8955 + F: Documentation/hwmon/gigabyte_waterforce.rst 8956 + F: drivers/hwmon/gigabyte_waterforce.c 8957 + 8959 8958 GIGABYTE WMI DRIVER 8960 8959 M: Thomas Weißschuh <thomas@weissschuh.net> 8961 8960 L: platform-driver-x86@vger.kernel.org ··· 12700 12685 S: Maintained 12701 12686 F: Documentation/hwmon/ltc4261.rst 12702 12687 F: drivers/hwmon/ltc4261.c 12688 + 12689 + LTC4286 HARDWARE MONITOR DRIVER 12690 + M: Delphine CC Chiu <Delphine_CC_Chiu@Wiwynn.com> 12691 + L: linux-i2c@vger.kernel.org 12692 + S: Maintained 12693 + F: Documentation/devicetree/bindings/hwmon/lltc,ltc4286.yaml 12694 + F: Documentation/hwmon/ltc4286.rst 12695 + F: drivers/hwmon/pmbus/Kconfig 12696 + F: drivers/hwmon/pmbus/Makefile 12697 + F: drivers/hwmon/pmbus/ltc4286.c 12703 12698 12704 12699 LTC4306 I2C MULTIPLEXER DRIVER 12705 12700 M: Michael Hennerich <michael.hennerich@analog.com>
+11
drivers/hwmon/Kconfig
··· 512 512 513 513 config SENSORS_DELL_SMM 514 514 tristate "Dell laptop SMM BIOS hwmon driver" 515 + depends on ACPI_WMI 515 516 depends on X86 516 517 imply THERMAL 517 518 help ··· 663 662 664 663 This driver can also be built as a module. If so, the module 665 664 will be called ftsteutates. 665 + 666 + config SENSORS_GIGABYTE_WATERFORCE 667 + tristate "Gigabyte Waterforce X240/X280/X360 AIO CPU coolers" 668 + depends on USB_HID 669 + help 670 + If you say yes here you get support for hardware monitoring for the 671 + Gigabyte Waterforce X240/X280/X360 all-in-one CPU liquid coolers. 672 + 673 + This driver can also be built as a module. If so, the module 674 + will be called gigabyte_waterforce. 666 675 667 676 config SENSORS_GL518SM 668 677 tristate "Genesys Logic GL518SM"
+1
drivers/hwmon/Makefile
··· 80 80 obj-$(CONFIG_SENSORS_FTSTEUTATES) += ftsteutates.o 81 81 obj-$(CONFIG_SENSORS_G760A) += g760a.o 82 82 obj-$(CONFIG_SENSORS_G762) += g762.o 83 + obj-$(CONFIG_SENSORS_GIGABYTE_WATERFORCE) += gigabyte_waterforce.o 83 84 obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o 84 85 obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o 85 86 obj-$(CONFIG_SENSORS_GSC) += gsc-hwmon.o
-10
drivers/hwmon/aquacomputer_d5next.c
··· 1476 1476 return 0; 1477 1477 } 1478 1478 1479 - #ifdef CONFIG_DEBUG_FS 1480 - 1481 1479 static int serial_number_show(struct seq_file *seqf, void *unused) 1482 1480 { 1483 1481 struct aqc_data *priv = seqf->private; ··· 1524 1526 if (priv->power_cycle_count_offset != 0) 1525 1527 debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops); 1526 1528 } 1527 - 1528 - #else 1529 - 1530 - static void aqc_debugfs_init(struct aqc_data *priv) 1531 - { 1532 - } 1533 - 1534 - #endif 1535 1529 1536 1530 static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) 1537 1531 {
+19 -7
drivers/hwmon/aspeed-pwm-tacho.c
··· 166 166 167 167 #define MAX_CDEV_NAME_LEN 16 168 168 169 + #define MAX_ASPEED_FAN_TACH_CHANNELS 16 170 + 169 171 struct aspeed_cooling_device { 170 172 char name[16]; 171 173 struct aspeed_pwm_tacho_data *priv; ··· 183 181 struct reset_control *rst; 184 182 unsigned long clk_freq; 185 183 bool pwm_present[8]; 186 - bool fan_tach_present[16]; 184 + bool fan_tach_present[MAX_ASPEED_FAN_TACH_CHANNELS]; 187 185 u8 type_pwm_clock_unit[3]; 188 186 u8 type_pwm_clock_division_h[3]; 189 187 u8 type_pwm_clock_division_l[3]; ··· 192 190 u16 type_fan_tach_unit[3]; 193 191 u8 pwm_port_type[8]; 194 192 u8 pwm_port_fan_ctrl[8]; 195 - u8 fan_tach_ch_source[16]; 193 + u8 fan_tach_ch_source[MAX_ASPEED_FAN_TACH_CHANNELS]; 196 194 struct aspeed_cooling_device *cdev[8]; 197 195 const struct attribute_group *groups[3]; 198 196 }; ··· 739 737 aspeed_set_pwm_port_fan_ctrl(priv, pwm_port, INIT_FAN_CTRL); 740 738 } 741 739 742 - static void aspeed_create_fan_tach_channel(struct aspeed_pwm_tacho_data *priv, 743 - u8 *fan_tach_ch, 744 - int count, 745 - u8 pwm_source) 740 + static int aspeed_create_fan_tach_channel(struct device *dev, 741 + struct aspeed_pwm_tacho_data *priv, 742 + u8 *fan_tach_ch, 743 + int count, 744 + u8 pwm_source) 746 745 { 747 746 u8 val, index; 748 747 749 748 for (val = 0; val < count; val++) { 750 749 index = fan_tach_ch[val]; 750 + if (index >= MAX_ASPEED_FAN_TACH_CHANNELS) { 751 + dev_err(dev, "Invalid Fan Tach input channel %u\n.", index); 752 + return -EINVAL; 753 + } 751 754 aspeed_set_fan_tach_ch_enable(priv->regmap, index, true); 752 755 priv->fan_tach_present[index] = true; 753 756 priv->fan_tach_ch_source[index] = pwm_source; 754 757 aspeed_set_fan_tach_ch_source(priv->regmap, index, pwm_source); 755 758 } 759 + 760 + return 0; 756 761 } 757 762 758 763 static int ··· 883 874 fan_tach_ch, count); 884 875 if (ret) 885 876 return ret; 886 - aspeed_create_fan_tach_channel(priv, fan_tach_ch, count, pwm_port); 877 + 878 + ret = aspeed_create_fan_tach_channel(dev, priv, fan_tach_ch, count, pwm_port); 879 + if (ret) 880 + return ret; 887 881 888 882 return 0; 889 883 }
+1 -1
drivers/hwmon/corsair-cpro.c
··· 524 524 if (ret) 525 525 goto out_hw_close; 526 526 ccp->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "corsaircpro", 527 - ccp, &ccp_chip_info, 0); 527 + ccp, &ccp_chip_info, NULL); 528 528 if (IS_ERR(ccp->hwmon_dev)) { 529 529 ret = PTR_ERR(ccp->hwmon_dev); 530 530 goto out_hw_close;
+419 -189
drivers/hwmon/dell-smm-hwmon.c
··· 12 12 13 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 14 15 + #include <linux/acpi.h> 15 16 #include <linux/capability.h> 16 17 #include <linux/cpu.h> 17 18 #include <linux/ctype.h> ··· 35 34 #include <linux/thermal.h> 36 35 #include <linux/types.h> 37 36 #include <linux/uaccess.h> 37 + #include <linux/wmi.h> 38 38 39 39 #include <linux/i8k.h> 40 + #include <asm/unaligned.h> 40 41 41 42 #define I8K_SMM_FN_STATUS 0x0025 42 43 #define I8K_SMM_POWER_STATUS 0x0069 ··· 69 66 #define I8K_POWER_AC 0x05 70 67 #define I8K_POWER_BATTERY 0x01 71 68 69 + #define DELL_SMM_WMI_GUID "F1DDEE52-063C-4784-A11E-8A06684B9B01" 70 + #define DELL_SMM_LEGACY_EXECUTE 0x1 71 + 72 72 #define DELL_SMM_NO_TEMP 10 73 73 #define DELL_SMM_NO_FANS 3 74 + 75 + struct smm_regs { 76 + unsigned int eax; 77 + unsigned int ebx; 78 + unsigned int ecx; 79 + unsigned int edx; 80 + unsigned int esi; 81 + unsigned int edi; 82 + }; 83 + 84 + struct dell_smm_ops { 85 + struct device *smm_dev; 86 + int (*smm_call)(struct device *smm_dev, struct smm_regs *regs); 87 + }; 74 88 75 89 struct dell_smm_data { 76 90 struct mutex i8k_mutex; /* lock for sensors writes */ ··· 96 76 uint i8k_fan_mult; 97 77 uint i8k_pwm_mult; 98 78 uint i8k_fan_max; 99 - bool disallow_fan_type_call; 100 - bool disallow_fan_support; 101 - unsigned int manual_fan; 102 - unsigned int auto_fan; 103 79 int temp_type[DELL_SMM_NO_TEMP]; 104 80 bool fan[DELL_SMM_NO_FANS]; 105 81 int fan_type[DELL_SMM_NO_FANS]; 106 82 int *fan_nominal_speed[DELL_SMM_NO_FANS]; 83 + const struct dell_smm_ops *ops; 107 84 }; 108 85 109 86 struct dell_smm_cooling_data { ··· 140 123 module_param(fan_max, uint, 0); 141 124 MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)"); 142 125 143 - struct smm_regs { 144 - unsigned int eax; 145 - unsigned int ebx; 146 - unsigned int ecx; 147 - unsigned int edx; 148 - unsigned int esi; 149 - unsigned int edi; 150 - }; 126 + static bool disallow_fan_type_call, disallow_fan_support; 127 + 128 + static unsigned int manual_fan, auto_fan; 151 129 152 130 static const char * const temp_labels[] = { 153 131 "CPU", ··· 183 171 */ 184 172 static int i8k_smm_func(void *par) 185 173 { 186 - ktime_t calltime = ktime_get(); 187 174 struct smm_regs *regs = par; 188 - int eax = regs->eax; 189 - int ebx = regs->ebx; 190 175 unsigned char carry; 191 - long long duration; 192 176 193 177 /* SMM requires CPU 0 */ 194 178 if (smp_processor_id() != 0) ··· 201 193 "+S" (regs->esi), 202 194 "+D" (regs->edi)); 203 195 204 - duration = ktime_us_delta(ktime_get(), calltime); 205 - pr_debug("smm(0x%.4x 0x%.4x) = 0x%.4x carry: %d (took %7lld usecs)\n", 206 - eax, ebx, regs->eax & 0xffff, carry, duration); 207 - 208 - if (duration > DELL_SMM_MAX_DURATION) 209 - pr_warn_once("SMM call took %lld usecs!\n", duration); 210 - 211 - if (carry || (regs->eax & 0xffff) == 0xffff || regs->eax == eax) 196 + if (carry) 212 197 return -EINVAL; 213 198 214 199 return 0; ··· 210 209 /* 211 210 * Call the System Management Mode BIOS. 212 211 */ 213 - static int i8k_smm(struct smm_regs *regs) 212 + static int i8k_smm_call(struct device *dummy, struct smm_regs *regs) 214 213 { 215 214 int ret; 216 215 ··· 219 218 cpus_read_unlock(); 220 219 221 220 return ret; 221 + } 222 + 223 + static const struct dell_smm_ops i8k_smm_ops = { 224 + .smm_call = i8k_smm_call, 225 + }; 226 + 227 + /* 228 + * Call the System Management Mode BIOS over WMI. 229 + */ 230 + static ssize_t wmi_parse_register(u8 *buffer, u32 length, unsigned int *reg) 231 + { 232 + __le32 value; 233 + u32 reg_size; 234 + 235 + if (length <= sizeof(reg_size)) 236 + return -ENODATA; 237 + 238 + reg_size = get_unaligned_le32(buffer); 239 + if (!reg_size || reg_size > sizeof(value)) 240 + return -ENOMSG; 241 + 242 + if (length < sizeof(reg_size) + reg_size) 243 + return -ENODATA; 244 + 245 + memcpy_and_pad(&value, sizeof(value), buffer + sizeof(reg_size), reg_size, 0); 246 + *reg = le32_to_cpu(value); 247 + 248 + return reg_size + sizeof(reg_size); 249 + } 250 + 251 + static int wmi_parse_response(u8 *buffer, u32 length, struct smm_regs *regs) 252 + { 253 + unsigned int *registers[] = { 254 + &regs->eax, 255 + &regs->ebx, 256 + &regs->ecx, 257 + &regs->edx 258 + }; 259 + u32 offset = 0; 260 + ssize_t ret; 261 + int i; 262 + 263 + for (i = 0; i < ARRAY_SIZE(registers); i++) { 264 + if (offset >= length) 265 + return -ENODATA; 266 + 267 + ret = wmi_parse_register(buffer + offset, length - offset, registers[i]); 268 + if (ret < 0) 269 + return ret; 270 + 271 + offset += ret; 272 + } 273 + 274 + if (offset != length) 275 + return -ENOMSG; 276 + 277 + return 0; 278 + } 279 + 280 + static int wmi_smm_call(struct device *dev, struct smm_regs *regs) 281 + { 282 + struct wmi_device *wdev = container_of(dev, struct wmi_device, dev); 283 + struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 284 + u32 wmi_payload[] = { 285 + sizeof(regs->eax), 286 + regs->eax, 287 + sizeof(regs->ebx), 288 + regs->ebx, 289 + sizeof(regs->ecx), 290 + regs->ecx, 291 + sizeof(regs->edx), 292 + regs->edx 293 + }; 294 + const struct acpi_buffer in = { 295 + .length = sizeof(wmi_payload), 296 + .pointer = &wmi_payload, 297 + }; 298 + union acpi_object *obj; 299 + acpi_status status; 300 + int ret; 301 + 302 + status = wmidev_evaluate_method(wdev, 0x0, DELL_SMM_LEGACY_EXECUTE, &in, &out); 303 + if (ACPI_FAILURE(status)) 304 + return -EIO; 305 + 306 + obj = out.pointer; 307 + if (!obj) 308 + return -ENODATA; 309 + 310 + if (obj->type != ACPI_TYPE_BUFFER) { 311 + ret = -ENOMSG; 312 + 313 + goto err_free; 314 + } 315 + 316 + ret = wmi_parse_response(obj->buffer.pointer, obj->buffer.length, regs); 317 + 318 + err_free: 319 + kfree(obj); 320 + 321 + return ret; 322 + } 323 + 324 + static int dell_smm_call(const struct dell_smm_ops *ops, struct smm_regs *regs) 325 + { 326 + unsigned int eax = regs->eax; 327 + unsigned int ebx = regs->ebx; 328 + long long duration; 329 + ktime_t calltime; 330 + int ret; 331 + 332 + calltime = ktime_get(); 333 + ret = ops->smm_call(ops->smm_dev, regs); 334 + duration = ktime_us_delta(ktime_get(), calltime); 335 + 336 + pr_debug("SMM(0x%.4x 0x%.4x) = 0x%.4x status: %d (took %7lld usecs)\n", 337 + eax, ebx, regs->eax & 0xffff, ret, duration); 338 + 339 + if (duration > DELL_SMM_MAX_DURATION) 340 + pr_warn_once("SMM call took %lld usecs!\n", duration); 341 + 342 + if (ret < 0) 343 + return ret; 344 + 345 + if ((regs->eax & 0xffff) == 0xffff || regs->eax == eax) 346 + return -EINVAL; 347 + 348 + return 0; 222 349 } 223 350 224 351 /* ··· 359 230 .ebx = fan, 360 231 }; 361 232 362 - if (data->disallow_fan_support) 233 + if (disallow_fan_support) 363 234 return -EINVAL; 364 235 365 - return i8k_smm(&regs) ? : regs.eax & 0xff; 236 + return dell_smm_call(data->ops, &regs) ? : regs.eax & 0xff; 366 237 } 367 238 368 239 /* ··· 375 246 .ebx = fan, 376 247 }; 377 248 378 - if (data->disallow_fan_support) 249 + if (disallow_fan_support) 379 250 return -EINVAL; 380 251 381 - return i8k_smm(&regs) ? : (regs.eax & 0xffff) * data->i8k_fan_mult; 252 + return dell_smm_call(data->ops, &regs) ? : (regs.eax & 0xffff) * data->i8k_fan_mult; 382 253 } 383 254 384 255 /* ··· 391 262 .ebx = fan, 392 263 }; 393 264 394 - if (data->disallow_fan_support || data->disallow_fan_type_call) 265 + if (disallow_fan_support || disallow_fan_type_call) 395 266 return -EINVAL; 396 267 397 - return i8k_smm(&regs) ? : regs.eax & 0xff; 268 + return dell_smm_call(data->ops, &regs) ? : regs.eax & 0xff; 398 269 } 399 270 400 271 static int i8k_get_fan_type(struct dell_smm_data *data, u8 fan) ··· 409 280 /* 410 281 * Read the fan nominal rpm for specific fan speed. 411 282 */ 412 - static int __init i8k_get_fan_nominal_speed(const struct dell_smm_data *data, u8 fan, int speed) 283 + static int i8k_get_fan_nominal_speed(const struct dell_smm_data *data, u8 fan, int speed) 413 284 { 414 285 struct smm_regs regs = { 415 286 .eax = I8K_SMM_GET_NOM_SPEED, 416 287 .ebx = fan | (speed << 8), 417 288 }; 418 289 419 - if (data->disallow_fan_support) 290 + if (disallow_fan_support) 420 291 return -EINVAL; 421 292 422 - return i8k_smm(&regs) ? : (regs.eax & 0xffff); 293 + return dell_smm_call(data->ops, &regs) ? : (regs.eax & 0xffff); 423 294 } 424 295 425 296 /* ··· 429 300 { 430 301 struct smm_regs regs = { }; 431 302 432 - if (data->disallow_fan_support) 303 + if (disallow_fan_support) 433 304 return -EINVAL; 434 305 435 - regs.eax = enable ? data->auto_fan : data->manual_fan; 436 - return i8k_smm(&regs); 306 + regs.eax = enable ? auto_fan : manual_fan; 307 + return dell_smm_call(data->ops, &regs); 437 308 } 438 309 439 310 /* ··· 443 314 { 444 315 struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, }; 445 316 446 - if (data->disallow_fan_support) 317 + if (disallow_fan_support) 447 318 return -EINVAL; 448 319 449 320 speed = (speed < 0) ? 0 : ((speed > data->i8k_fan_max) ? data->i8k_fan_max : speed); 450 321 regs.ebx = fan | (speed << 8); 451 322 452 - return i8k_smm(&regs); 323 + return dell_smm_call(data->ops, &regs); 453 324 } 454 325 455 - static int __init i8k_get_temp_type(u8 sensor) 326 + static int i8k_get_temp_type(const struct dell_smm_data *data, u8 sensor) 456 327 { 457 328 struct smm_regs regs = { 458 329 .eax = I8K_SMM_GET_TEMP_TYPE, 459 330 .ebx = sensor, 460 331 }; 461 332 462 - return i8k_smm(&regs) ? : regs.eax & 0xff; 333 + return dell_smm_call(data->ops, &regs) ? : regs.eax & 0xff; 463 334 } 464 335 465 336 /* 466 337 * Read the cpu temperature. 467 338 */ 468 - static int _i8k_get_temp(u8 sensor) 339 + static int _i8k_get_temp(const struct dell_smm_data *data, u8 sensor) 469 340 { 470 341 struct smm_regs regs = { 471 342 .eax = I8K_SMM_GET_TEMP, 472 343 .ebx = sensor, 473 344 }; 474 345 475 - return i8k_smm(&regs) ? : regs.eax & 0xff; 346 + return dell_smm_call(data->ops, &regs) ? : regs.eax & 0xff; 476 347 } 477 348 478 - static int i8k_get_temp(u8 sensor) 349 + static int i8k_get_temp(const struct dell_smm_data *data, u8 sensor) 479 350 { 480 - int temp = _i8k_get_temp(sensor); 351 + int temp = _i8k_get_temp(data, sensor); 481 352 482 353 /* 483 354 * Sometimes the temperature sensor returns 0x99, which is out of range. ··· 488 359 */ 489 360 if (temp == 0x99) { 490 361 msleep(100); 491 - temp = _i8k_get_temp(sensor); 362 + temp = _i8k_get_temp(data, sensor); 492 363 } 493 364 /* 494 365 * Return -ENODATA for all invalid temperatures. ··· 504 375 return temp; 505 376 } 506 377 507 - static int __init i8k_get_dell_signature(int req_fn) 378 + static int dell_smm_get_signature(const struct dell_smm_ops *ops, int req_fn) 508 379 { 509 380 struct smm_regs regs = { .eax = req_fn, }; 510 381 int rc; 511 382 512 - rc = i8k_smm(&regs); 383 + rc = dell_smm_call(ops, &regs); 513 384 if (rc < 0) 514 385 return rc; 515 386 ··· 521 392 /* 522 393 * Read the Fn key status. 523 394 */ 524 - static int i8k_get_fn_status(void) 395 + static int i8k_get_fn_status(const struct dell_smm_data *data) 525 396 { 526 397 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, }; 527 398 int rc; 528 399 529 - rc = i8k_smm(&regs); 400 + rc = dell_smm_call(data->ops, &regs); 530 401 if (rc < 0) 531 402 return rc; 532 403 ··· 545 416 /* 546 417 * Read the power status. 547 418 */ 548 - static int i8k_get_power_status(void) 419 + static int i8k_get_power_status(const struct dell_smm_data *data) 549 420 { 550 421 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, }; 551 422 int rc; 552 423 553 - rc = i8k_smm(&regs); 424 + rc = dell_smm_call(data->ops, &regs); 554 425 if (rc < 0) 555 426 return rc; 556 427 ··· 593 464 594 465 return 0; 595 466 case I8K_FN_STATUS: 596 - val = i8k_get_fn_status(); 467 + val = i8k_get_fn_status(data); 597 468 break; 598 469 599 470 case I8K_POWER_STATUS: 600 - val = i8k_get_power_status(); 471 + val = i8k_get_power_status(data); 601 472 break; 602 473 603 474 case I8K_GET_TEMP: 604 - val = i8k_get_temp(0); 475 + val = i8k_get_temp(data, 0); 605 476 break; 606 477 607 478 case I8K_GET_SPEED: ··· 668 539 int fn_key, cpu_temp, ac_power; 669 540 int left_fan, right_fan, left_speed, right_speed; 670 541 671 - cpu_temp = i8k_get_temp(0); /* 11100 µs */ 542 + cpu_temp = i8k_get_temp(data, 0); /* 11100 µs */ 672 543 left_fan = i8k_get_fan_status(data, I8K_FAN_LEFT); /* 580 µs */ 673 544 right_fan = i8k_get_fan_status(data, I8K_FAN_RIGHT); /* 580 µs */ 674 545 left_speed = i8k_get_fan_speed(data, I8K_FAN_LEFT); /* 580 µs */ 675 546 right_speed = i8k_get_fan_speed(data, I8K_FAN_RIGHT); /* 580 µs */ 676 - fn_key = i8k_get_fn_status(); /* 750 µs */ 547 + fn_key = i8k_get_fn_status(data); /* 750 µs */ 677 548 if (power_status) 678 - ac_power = i8k_get_power_status(); /* 14700 µs */ 549 + ac_power = i8k_get_power_status(data); /* 14700 µs */ 679 550 else 680 551 ac_power = -1; 681 552 ··· 725 596 static void __init i8k_init_procfs(struct device *dev) 726 597 { 727 598 struct dell_smm_data *data = dev_get_drvdata(dev); 599 + 600 + strscpy(data->bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), 601 + sizeof(data->bios_version)); 602 + strscpy(data->bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), 603 + sizeof(data->bios_machineid)); 728 604 729 605 /* Only register exit function if creation was successful */ 730 606 if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data)) ··· 799 665 switch (attr) { 800 666 case hwmon_temp_input: 801 667 /* _i8k_get_temp() is fine since we do not care about the actual value */ 802 - if (data->temp_type[channel] >= 0 || _i8k_get_temp(channel) >= 0) 668 + if (data->temp_type[channel] >= 0 || _i8k_get_temp(data, channel) >= 0) 803 669 return 0444; 804 670 805 671 break; ··· 813 679 } 814 680 break; 815 681 case hwmon_fan: 816 - if (data->disallow_fan_support) 682 + if (disallow_fan_support) 817 683 break; 818 684 819 685 switch (attr) { ··· 823 689 824 690 break; 825 691 case hwmon_fan_label: 826 - if (data->fan[channel] && !data->disallow_fan_type_call) 692 + if (data->fan[channel] && !disallow_fan_type_call) 827 693 return 0444; 828 694 829 695 break; ··· 839 705 } 840 706 break; 841 707 case hwmon_pwm: 842 - if (data->disallow_fan_support) 708 + if (disallow_fan_support) 843 709 break; 844 710 845 711 switch (attr) { ··· 849 715 850 716 break; 851 717 case hwmon_pwm_enable: 852 - if (data->auto_fan) 718 + if (auto_fan) 853 719 /* 854 720 * There is no command for retrieve the current status 855 721 * from BIOS, and userspace/firmware itself can change ··· 881 747 case hwmon_temp: 882 748 switch (attr) { 883 749 case hwmon_temp_input: 884 - ret = i8k_get_temp(channel); 750 + ret = i8k_get_temp(data, channel); 885 751 if (ret < 0) 886 752 return ret; 887 753 ··· 1089 955 .info = dell_smm_info, 1090 956 }; 1091 957 1092 - static int __init dell_smm_init_cdev(struct device *dev, u8 fan_num) 958 + static int dell_smm_init_cdev(struct device *dev, u8 fan_num) 1093 959 { 1094 960 struct dell_smm_data *data = dev_get_drvdata(dev); 1095 961 struct thermal_cooling_device *cdev; ··· 1120 986 return ret; 1121 987 } 1122 988 1123 - static int __init dell_smm_init_hwmon(struct device *dev) 989 + static int dell_smm_init_hwmon(struct device *dev) 1124 990 { 1125 991 struct dell_smm_data *data = dev_get_drvdata(dev); 1126 992 struct device *dell_smm_hwmon_dev; ··· 1128 994 u8 i; 1129 995 1130 996 for (i = 0; i < DELL_SMM_NO_TEMP; i++) { 1131 - data->temp_type[i] = i8k_get_temp_type(i); 997 + data->temp_type[i] = i8k_get_temp_type(data, i); 1132 998 if (data->temp_type[i] < 0) 1133 999 continue; 1134 1000 ··· 1186 1052 return PTR_ERR_OR_ZERO(dell_smm_hwmon_dev); 1187 1053 } 1188 1054 1189 - struct i8k_config_data { 1190 - uint fan_mult; 1191 - uint fan_max; 1192 - }; 1055 + static int dell_smm_init_data(struct device *dev, const struct dell_smm_ops *ops) 1056 + { 1057 + struct dell_smm_data *data; 1193 1058 1194 - enum i8k_configs { 1195 - DELL_LATITUDE_D520, 1196 - DELL_PRECISION_490, 1197 - DELL_STUDIO, 1198 - DELL_XPS, 1199 - }; 1059 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 1060 + if (!data) 1061 + return -ENOMEM; 1200 1062 1201 - /* 1202 - * Only use for machines which need some special configuration 1203 - * in order to work correctly (e.g. if autoconfig fails on this machines). 1204 - */ 1063 + mutex_init(&data->i8k_mutex); 1064 + dev_set_drvdata(dev, data); 1205 1065 1206 - static const struct i8k_config_data i8k_config_data[] __initconst = { 1207 - [DELL_LATITUDE_D520] = { 1208 - .fan_mult = 1, 1209 - .fan_max = I8K_FAN_TURBO, 1210 - }, 1211 - [DELL_PRECISION_490] = { 1212 - .fan_mult = 1, 1213 - .fan_max = I8K_FAN_TURBO, 1214 - }, 1215 - [DELL_STUDIO] = { 1216 - .fan_mult = 1, 1217 - .fan_max = I8K_FAN_HIGH, 1218 - }, 1219 - [DELL_XPS] = { 1220 - .fan_mult = 1, 1221 - .fan_max = I8K_FAN_HIGH, 1222 - }, 1223 - }; 1066 + data->ops = ops; 1067 + /* All options must not be 0 */ 1068 + data->i8k_fan_mult = fan_mult ? : I8K_FAN_MULT; 1069 + data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH; 1070 + data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max); 1071 + 1072 + return 0; 1073 + } 1224 1074 1225 1075 static const struct dmi_system_id i8k_dmi_table[] __initconst = { 1226 1076 { ··· 1236 1118 }, 1237 1119 }, 1238 1120 { 1239 - .ident = "Dell Latitude D520", 1240 - .matches = { 1241 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1242 - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"), 1243 - }, 1244 - .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520], 1245 - }, 1246 - { 1247 1121 .ident = "Dell Latitude 2", 1248 1122 .matches = { 1249 1123 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ··· 1257 1147 }, 1258 1148 }, 1259 1149 { 1260 - .ident = "Dell Precision 490", 1261 - .matches = { 1262 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1263 - DMI_MATCH(DMI_PRODUCT_NAME, 1264 - "Precision WorkStation 490"), 1265 - }, 1266 - .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490], 1267 - }, 1268 - { 1269 1150 .ident = "Dell Precision", 1270 1151 .matches = { 1271 1152 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ··· 1276 1175 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1277 1176 DMI_MATCH(DMI_PRODUCT_NAME, "Studio"), 1278 1177 }, 1279 - .driver_data = (void *)&i8k_config_data[DELL_STUDIO], 1280 1178 }, 1281 1179 { 1282 1180 .ident = "Dell XPS M140", ··· 1283 1183 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1284 1184 DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"), 1285 1185 }, 1286 - .driver_data = (void *)&i8k_config_data[DELL_XPS], 1287 1186 }, 1288 1187 { 1289 1188 .ident = "Dell XPS", ··· 1295 1196 }; 1296 1197 1297 1198 MODULE_DEVICE_TABLE(dmi, i8k_dmi_table); 1199 + 1200 + /* 1201 + * Only use for machines which need some special configuration 1202 + * in order to work correctly (e.g. if autoconfig fails on this machines). 1203 + */ 1204 + struct i8k_config_data { 1205 + uint fan_mult; 1206 + uint fan_max; 1207 + }; 1208 + 1209 + enum i8k_configs { 1210 + DELL_LATITUDE_D520, 1211 + DELL_PRECISION_490, 1212 + DELL_STUDIO, 1213 + DELL_XPS, 1214 + }; 1215 + 1216 + static const struct i8k_config_data i8k_config_data[] __initconst = { 1217 + [DELL_LATITUDE_D520] = { 1218 + .fan_mult = 1, 1219 + .fan_max = I8K_FAN_TURBO, 1220 + }, 1221 + [DELL_PRECISION_490] = { 1222 + .fan_mult = 1, 1223 + .fan_max = I8K_FAN_TURBO, 1224 + }, 1225 + [DELL_STUDIO] = { 1226 + .fan_mult = 1, 1227 + .fan_max = I8K_FAN_HIGH, 1228 + }, 1229 + [DELL_XPS] = { 1230 + .fan_mult = 1, 1231 + .fan_max = I8K_FAN_HIGH, 1232 + }, 1233 + }; 1234 + 1235 + static const struct dmi_system_id i8k_config_dmi_table[] __initconst = { 1236 + { 1237 + .ident = "Dell Latitude D520", 1238 + .matches = { 1239 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1240 + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"), 1241 + }, 1242 + .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520], 1243 + }, 1244 + { 1245 + .ident = "Dell Precision 490", 1246 + .matches = { 1247 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1248 + DMI_MATCH(DMI_PRODUCT_NAME, 1249 + "Precision WorkStation 490"), 1250 + }, 1251 + .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490], 1252 + }, 1253 + { 1254 + .ident = "Dell Studio", 1255 + .matches = { 1256 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1257 + DMI_MATCH(DMI_PRODUCT_NAME, "Studio"), 1258 + }, 1259 + .driver_data = (void *)&i8k_config_data[DELL_STUDIO], 1260 + }, 1261 + { 1262 + .ident = "Dell XPS M140", 1263 + .matches = { 1264 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1265 + DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"), 1266 + }, 1267 + .driver_data = (void *)&i8k_config_data[DELL_XPS], 1268 + }, 1269 + { } 1270 + }; 1298 1271 1299 1272 /* 1300 1273 * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed ··· 1509 1338 }, 1510 1339 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3], 1511 1340 }, 1341 + { 1342 + .ident = "Dell Optiplex 7000", 1343 + .matches = { 1344 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1345 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7000"), 1346 + }, 1347 + .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3], 1348 + }, 1512 1349 { } 1513 1350 }; 1514 1351 1352 + /* 1353 + * Legacy SMM backend driver. 1354 + */ 1515 1355 static int __init dell_smm_probe(struct platform_device *pdev) 1516 1356 { 1517 - struct dell_smm_data *data; 1518 - const struct dmi_system_id *id, *fan_control; 1519 1357 int ret; 1520 1358 1521 - data = devm_kzalloc(&pdev->dev, sizeof(struct dell_smm_data), GFP_KERNEL); 1522 - if (!data) 1523 - return -ENOMEM; 1524 - 1525 - mutex_init(&data->i8k_mutex); 1526 - platform_set_drvdata(pdev, data); 1527 - 1528 - if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) { 1529 - if (!force) { 1530 - dev_notice(&pdev->dev, "Disabling fan support due to BIOS bugs\n"); 1531 - data->disallow_fan_support = true; 1532 - } else { 1533 - dev_warn(&pdev->dev, "Enabling fan support despite BIOS bugs\n"); 1534 - } 1535 - } 1536 - 1537 - if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) { 1538 - if (!force) { 1539 - dev_notice(&pdev->dev, "Disabling fan type call due to BIOS bugs\n"); 1540 - data->disallow_fan_type_call = true; 1541 - } else { 1542 - dev_warn(&pdev->dev, "Enabling fan type call despite BIOS bugs\n"); 1543 - } 1544 - } 1545 - 1546 - strscpy(data->bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), 1547 - sizeof(data->bios_version)); 1548 - strscpy(data->bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), 1549 - sizeof(data->bios_machineid)); 1550 - 1551 - /* 1552 - * Set fan multiplier and maximal fan speed from dmi config 1553 - * Values specified in module parameters override values from dmi 1554 - */ 1555 - id = dmi_first_match(i8k_dmi_table); 1556 - if (id && id->driver_data) { 1557 - const struct i8k_config_data *conf = id->driver_data; 1558 - 1559 - if (!fan_mult && conf->fan_mult) 1560 - fan_mult = conf->fan_mult; 1561 - 1562 - if (!fan_max && conf->fan_max) 1563 - fan_max = conf->fan_max; 1564 - } 1565 - 1566 - /* All options must not be 0 */ 1567 - data->i8k_fan_mult = fan_mult ? : I8K_FAN_MULT; 1568 - data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH; 1569 - data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max); 1570 - 1571 - fan_control = dmi_first_match(i8k_whitelist_fan_control); 1572 - if (fan_control && fan_control->driver_data) { 1573 - const struct i8k_fan_control_data *control = fan_control->driver_data; 1574 - 1575 - data->manual_fan = control->manual_fan; 1576 - data->auto_fan = control->auto_fan; 1577 - dev_info(&pdev->dev, "enabling support for setting automatic/manual fan control\n"); 1578 - } 1359 + ret = dell_smm_init_data(&pdev->dev, &i8k_smm_ops); 1360 + if (ret < 0) 1361 + return ret; 1579 1362 1580 1363 ret = dell_smm_init_hwmon(&pdev->dev); 1581 1364 if (ret) ··· 1549 1424 static struct platform_device *dell_smm_device; 1550 1425 1551 1426 /* 1427 + * WMI SMM backend driver. 1428 + */ 1429 + static int dell_smm_wmi_probe(struct wmi_device *wdev, const void *context) 1430 + { 1431 + struct dell_smm_ops *ops; 1432 + int ret; 1433 + 1434 + ops = devm_kzalloc(&wdev->dev, sizeof(*ops), GFP_KERNEL); 1435 + if (!ops) 1436 + return -ENOMEM; 1437 + 1438 + ops->smm_call = wmi_smm_call; 1439 + ops->smm_dev = &wdev->dev; 1440 + 1441 + if (dell_smm_get_signature(ops, I8K_SMM_GET_DELL_SIG1) && 1442 + dell_smm_get_signature(ops, I8K_SMM_GET_DELL_SIG2)) 1443 + return -ENODEV; 1444 + 1445 + ret = dell_smm_init_data(&wdev->dev, ops); 1446 + if (ret < 0) 1447 + return ret; 1448 + 1449 + return dell_smm_init_hwmon(&wdev->dev); 1450 + } 1451 + 1452 + static const struct wmi_device_id dell_smm_wmi_id_table[] = { 1453 + { DELL_SMM_WMI_GUID, NULL }, 1454 + { } 1455 + }; 1456 + MODULE_DEVICE_TABLE(wmi, dell_smm_wmi_id_table); 1457 + 1458 + static struct wmi_driver dell_smm_wmi_driver = { 1459 + .driver = { 1460 + .name = KBUILD_MODNAME, 1461 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 1462 + }, 1463 + .id_table = dell_smm_wmi_id_table, 1464 + .probe = dell_smm_wmi_probe, 1465 + }; 1466 + 1467 + /* 1552 1468 * Probe for the presence of a supported laptop. 1553 1469 */ 1554 - static int __init i8k_init(void) 1470 + static void __init dell_smm_init_dmi(void) 1555 1471 { 1472 + struct i8k_fan_control_data *control; 1473 + struct i8k_config_data *config; 1474 + const struct dmi_system_id *id; 1475 + 1476 + if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) { 1477 + if (!force) { 1478 + pr_notice("Disabling fan support due to BIOS bugs\n"); 1479 + disallow_fan_support = true; 1480 + } else { 1481 + pr_warn("Enabling fan support despite BIOS bugs\n"); 1482 + } 1483 + } 1484 + 1485 + if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) { 1486 + if (!force) { 1487 + pr_notice("Disabling fan type call due to BIOS bugs\n"); 1488 + disallow_fan_type_call = true; 1489 + } else { 1490 + pr_warn("Enabling fan type call despite BIOS bugs\n"); 1491 + } 1492 + } 1493 + 1556 1494 /* 1557 - * Get DMI information 1495 + * Set fan multiplier and maximal fan speed from DMI config. 1496 + * Values specified in module parameters override values from DMI. 1558 1497 */ 1498 + id = dmi_first_match(i8k_config_dmi_table); 1499 + if (id && id->driver_data) { 1500 + config = id->driver_data; 1501 + if (!fan_mult && config->fan_mult) 1502 + fan_mult = config->fan_mult; 1503 + 1504 + if (!fan_max && config->fan_max) 1505 + fan_max = config->fan_max; 1506 + } 1507 + 1508 + id = dmi_first_match(i8k_whitelist_fan_control); 1509 + if (id && id->driver_data) { 1510 + control = id->driver_data; 1511 + manual_fan = control->manual_fan; 1512 + auto_fan = control->auto_fan; 1513 + 1514 + pr_info("Enabling support for setting automatic/manual fan control\n"); 1515 + } 1516 + } 1517 + 1518 + static int __init dell_smm_legacy_check(void) 1519 + { 1559 1520 if (!dmi_check_system(i8k_dmi_table)) { 1560 1521 if (!ignore_dmi && !force) 1561 1522 return -ENODEV; 1562 1523 1563 - pr_info("not running on a supported Dell system.\n"); 1524 + pr_info("Probing for legacy SMM handler on unsupported machine\n"); 1564 1525 pr_info("vendor=%s, model=%s, version=%s\n", 1565 1526 i8k_get_dmi_data(DMI_SYS_VENDOR), 1566 1527 i8k_get_dmi_data(DMI_PRODUCT_NAME), 1567 1528 i8k_get_dmi_data(DMI_BIOS_VERSION)); 1568 1529 } 1569 1530 1570 - /* 1571 - * Get SMM Dell signature 1572 - */ 1573 - if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) && 1574 - i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) { 1531 + if (dell_smm_get_signature(&i8k_smm_ops, I8K_SMM_GET_DELL_SIG1) && 1532 + dell_smm_get_signature(&i8k_smm_ops, I8K_SMM_GET_DELL_SIG2)) { 1575 1533 if (!force) 1576 1534 return -ENODEV; 1577 1535 1578 - pr_err("Unable to get Dell SMM signature\n"); 1536 + pr_warn("Forcing legacy SMM calls on a possibly incompatible machine\n"); 1537 + } 1538 + 1539 + return 0; 1540 + } 1541 + 1542 + static int __init i8k_init(void) 1543 + { 1544 + int ret; 1545 + 1546 + dell_smm_init_dmi(); 1547 + 1548 + ret = dell_smm_legacy_check(); 1549 + if (ret < 0) { 1550 + /* 1551 + * On modern machines, SMM communication happens over WMI, meaning 1552 + * the SMM handler might not react to legacy SMM calls. 1553 + */ 1554 + return wmi_driver_register(&dell_smm_wmi_driver); 1579 1555 } 1580 1556 1581 1557 dell_smm_device = platform_create_bundle(&dell_smm_driver, dell_smm_probe, NULL, 0, NULL, ··· 1687 1461 1688 1462 static void __exit i8k_exit(void) 1689 1463 { 1690 - platform_device_unregister(dell_smm_device); 1691 - platform_driver_unregister(&dell_smm_driver); 1464 + if (dell_smm_device) { 1465 + platform_device_unregister(dell_smm_device); 1466 + platform_driver_unregister(&dell_smm_driver); 1467 + } else { 1468 + wmi_driver_unregister(&dell_smm_wmi_driver); 1469 + } 1692 1470 } 1693 1471 1694 1472 module_init(i8k_init);
+5 -1
drivers/hwmon/emc1403.c
··· 346 346 case 0x27: 347 347 strscpy(info->type, "emc1424", I2C_NAME_SIZE); 348 348 break; 349 + case 0x60: 350 + strscpy(info->type, "emc1442", I2C_NAME_SIZE); 351 + break; 349 352 default: 350 353 return -ENODEV; 351 354 } ··· 433 430 } 434 431 435 432 static const unsigned short emc1403_address_list[] = { 436 - 0x18, 0x1c, 0x29, 0x4c, 0x4d, 0x5c, I2C_CLIENT_END 433 + 0x18, 0x1c, 0x29, 0x3c, 0x4c, 0x4d, 0x5c, I2C_CLIENT_END 437 434 }; 438 435 439 436 /* Last digit of chip name indicates number of channels */ ··· 447 444 { "emc1422", emc1402 }, 448 445 { "emc1423", emc1403 }, 449 446 { "emc1424", emc1404 }, 447 + { "emc1442", emc1402 }, 450 448 { } 451 449 }; 452 450 MODULE_DEVICE_TABLE(i2c, emc1403_idtable);
+430
drivers/hwmon/gigabyte_waterforce.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * hwmon driver for Gigabyte AORUS Waterforce AIO CPU coolers: X240, X280 and X360. 4 + * 5 + * Copyright 2023 Aleksa Savic <savicaleksa83@gmail.com> 6 + */ 7 + 8 + #include <linux/debugfs.h> 9 + #include <linux/hid.h> 10 + #include <linux/hwmon.h> 11 + #include <linux/jiffies.h> 12 + #include <linux/module.h> 13 + #include <linux/spinlock.h> 14 + #include <asm/unaligned.h> 15 + 16 + #define DRIVER_NAME "gigabyte_waterforce" 17 + 18 + #define USB_VENDOR_ID_GIGABYTE 0x1044 19 + #define USB_PRODUCT_ID_WATERFORCE 0x7a4d /* Gigabyte AORUS WATERFORCE X240, X280 and X360 */ 20 + 21 + #define STATUS_VALIDITY (2 * 1000) /* ms */ 22 + #define MAX_REPORT_LENGTH 6144 23 + 24 + #define WATERFORCE_TEMP_SENSOR 0xD 25 + #define WATERFORCE_FAN_SPEED 0x02 26 + #define WATERFORCE_PUMP_SPEED 0x05 27 + #define WATERFORCE_FAN_DUTY 0x08 28 + #define WATERFORCE_PUMP_DUTY 0x09 29 + 30 + /* Control commands, inner offsets and lengths */ 31 + static const u8 get_status_cmd[] = { 0x99, 0xDA }; 32 + 33 + #define FIRMWARE_VER_START_OFFSET_1 2 34 + #define FIRMWARE_VER_START_OFFSET_2 3 35 + static const u8 get_firmware_ver_cmd[] = { 0x99, 0xD6 }; 36 + 37 + /* Command lengths */ 38 + #define GET_STATUS_CMD_LENGTH 2 39 + #define GET_FIRMWARE_VER_CMD_LENGTH 2 40 + 41 + static const char *const waterforce_temp_label[] = { 42 + "Coolant temp" 43 + }; 44 + 45 + static const char *const waterforce_speed_label[] = { 46 + "Fan speed", 47 + "Pump speed" 48 + }; 49 + 50 + struct waterforce_data { 51 + struct hid_device *hdev; 52 + struct device *hwmon_dev; 53 + struct dentry *debugfs; 54 + /* For locking access to buffer */ 55 + struct mutex buffer_lock; 56 + /* For queueing multiple readers */ 57 + struct mutex status_report_request_mutex; 58 + /* For reinitializing the completion below */ 59 + spinlock_t status_report_request_lock; 60 + struct completion status_report_received; 61 + struct completion fw_version_processed; 62 + 63 + /* Sensor data */ 64 + s32 temp_input[1]; 65 + u16 speed_input[2]; /* Fan and pump speed in RPM */ 66 + u8 duty_input[2]; /* Fan and pump duty in 0-100% */ 67 + 68 + u8 *buffer; 69 + int firmware_version; 70 + unsigned long updated; /* jiffies */ 71 + }; 72 + 73 + static umode_t waterforce_is_visible(const void *data, 74 + enum hwmon_sensor_types type, u32 attr, int channel) 75 + { 76 + switch (type) { 77 + case hwmon_temp: 78 + switch (attr) { 79 + case hwmon_temp_label: 80 + case hwmon_temp_input: 81 + return 0444; 82 + default: 83 + break; 84 + } 85 + break; 86 + case hwmon_fan: 87 + switch (attr) { 88 + case hwmon_fan_label: 89 + case hwmon_fan_input: 90 + return 0444; 91 + default: 92 + break; 93 + } 94 + break; 95 + case hwmon_pwm: 96 + switch (attr) { 97 + case hwmon_pwm_input: 98 + return 0444; 99 + default: 100 + break; 101 + } 102 + break; 103 + default: 104 + break; 105 + } 106 + 107 + return 0; 108 + } 109 + 110 + /* Writes the command to the device with the rest of the report filled with zeroes */ 111 + static int waterforce_write_expanded(struct waterforce_data *priv, const u8 *cmd, int cmd_length) 112 + { 113 + int ret; 114 + 115 + mutex_lock(&priv->buffer_lock); 116 + 117 + memcpy_and_pad(priv->buffer, MAX_REPORT_LENGTH, cmd, cmd_length, 0x00); 118 + ret = hid_hw_output_report(priv->hdev, priv->buffer, MAX_REPORT_LENGTH); 119 + 120 + mutex_unlock(&priv->buffer_lock); 121 + return ret; 122 + } 123 + 124 + static int waterforce_get_status(struct waterforce_data *priv) 125 + { 126 + int ret = mutex_lock_interruptible(&priv->status_report_request_mutex); 127 + 128 + if (ret < 0) 129 + return ret; 130 + 131 + if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { 132 + /* Data is up to date */ 133 + goto unlock_and_return; 134 + } 135 + 136 + /* 137 + * Disable raw event parsing for a moment to safely reinitialize the 138 + * completion. Reinit is done because hidraw could have triggered 139 + * the raw event parsing and marked the priv->status_report_received 140 + * completion as done. 141 + */ 142 + spin_lock_bh(&priv->status_report_request_lock); 143 + reinit_completion(&priv->status_report_received); 144 + spin_unlock_bh(&priv->status_report_request_lock); 145 + 146 + /* Send command for getting status */ 147 + ret = waterforce_write_expanded(priv, get_status_cmd, GET_STATUS_CMD_LENGTH); 148 + if (ret < 0) 149 + return ret; 150 + 151 + ret = wait_for_completion_interruptible_timeout(&priv->status_report_received, 152 + msecs_to_jiffies(STATUS_VALIDITY)); 153 + if (ret == 0) 154 + ret = -ETIMEDOUT; 155 + 156 + unlock_and_return: 157 + mutex_unlock(&priv->status_report_request_mutex); 158 + if (ret < 0) 159 + return ret; 160 + 161 + return 0; 162 + } 163 + 164 + static int waterforce_read(struct device *dev, enum hwmon_sensor_types type, 165 + u32 attr, int channel, long *val) 166 + { 167 + struct waterforce_data *priv = dev_get_drvdata(dev); 168 + int ret = waterforce_get_status(priv); 169 + 170 + if (ret < 0) 171 + return ret; 172 + 173 + switch (type) { 174 + case hwmon_temp: 175 + *val = priv->temp_input[channel]; 176 + break; 177 + case hwmon_fan: 178 + *val = priv->speed_input[channel]; 179 + break; 180 + case hwmon_pwm: 181 + switch (attr) { 182 + case hwmon_pwm_input: 183 + *val = DIV_ROUND_CLOSEST(priv->duty_input[channel] * 255, 100); 184 + break; 185 + default: 186 + return -EOPNOTSUPP; 187 + } 188 + break; 189 + default: 190 + return -EOPNOTSUPP; /* unreachable */ 191 + } 192 + 193 + return 0; 194 + } 195 + 196 + static int waterforce_read_string(struct device *dev, enum hwmon_sensor_types type, 197 + u32 attr, int channel, const char **str) 198 + { 199 + switch (type) { 200 + case hwmon_temp: 201 + *str = waterforce_temp_label[channel]; 202 + break; 203 + case hwmon_fan: 204 + *str = waterforce_speed_label[channel]; 205 + break; 206 + default: 207 + return -EOPNOTSUPP; /* unreachable */ 208 + } 209 + 210 + return 0; 211 + } 212 + 213 + static int waterforce_get_fw_ver(struct hid_device *hdev) 214 + { 215 + struct waterforce_data *priv = hid_get_drvdata(hdev); 216 + int ret; 217 + 218 + ret = waterforce_write_expanded(priv, get_firmware_ver_cmd, GET_FIRMWARE_VER_CMD_LENGTH); 219 + if (ret < 0) 220 + return ret; 221 + 222 + ret = wait_for_completion_interruptible_timeout(&priv->fw_version_processed, 223 + msecs_to_jiffies(STATUS_VALIDITY)); 224 + if (ret == 0) 225 + return -ETIMEDOUT; 226 + else if (ret < 0) 227 + return ret; 228 + 229 + return 0; 230 + } 231 + 232 + static const struct hwmon_ops waterforce_hwmon_ops = { 233 + .is_visible = waterforce_is_visible, 234 + .read = waterforce_read, 235 + .read_string = waterforce_read_string 236 + }; 237 + 238 + static const struct hwmon_channel_info *waterforce_info[] = { 239 + HWMON_CHANNEL_INFO(temp, 240 + HWMON_T_INPUT | HWMON_T_LABEL), 241 + HWMON_CHANNEL_INFO(fan, 242 + HWMON_F_INPUT | HWMON_F_LABEL, 243 + HWMON_F_INPUT | HWMON_F_LABEL), 244 + HWMON_CHANNEL_INFO(pwm, 245 + HWMON_PWM_INPUT, 246 + HWMON_PWM_INPUT), 247 + NULL 248 + }; 249 + 250 + static const struct hwmon_chip_info waterforce_chip_info = { 251 + .ops = &waterforce_hwmon_ops, 252 + .info = waterforce_info, 253 + }; 254 + 255 + static int waterforce_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, 256 + int size) 257 + { 258 + struct waterforce_data *priv = hid_get_drvdata(hdev); 259 + 260 + if (data[0] == get_firmware_ver_cmd[0] && data[1] == get_firmware_ver_cmd[1]) { 261 + /* Received a firmware version report */ 262 + priv->firmware_version = 263 + data[FIRMWARE_VER_START_OFFSET_1] * 10 + data[FIRMWARE_VER_START_OFFSET_2]; 264 + 265 + if (!completion_done(&priv->fw_version_processed)) 266 + complete_all(&priv->fw_version_processed); 267 + return 0; 268 + } 269 + 270 + if (data[0] != get_status_cmd[0] || data[1] != get_status_cmd[1]) 271 + return 0; 272 + 273 + priv->temp_input[0] = data[WATERFORCE_TEMP_SENSOR] * 1000; 274 + priv->speed_input[0] = get_unaligned_le16(data + WATERFORCE_FAN_SPEED); 275 + priv->speed_input[1] = get_unaligned_le16(data + WATERFORCE_PUMP_SPEED); 276 + priv->duty_input[0] = data[WATERFORCE_FAN_DUTY]; 277 + priv->duty_input[1] = data[WATERFORCE_PUMP_DUTY]; 278 + 279 + spin_lock(&priv->status_report_request_lock); 280 + if (!completion_done(&priv->status_report_received)) 281 + complete_all(&priv->status_report_received); 282 + spin_unlock(&priv->status_report_request_lock); 283 + 284 + priv->updated = jiffies; 285 + 286 + return 0; 287 + } 288 + 289 + static int firmware_version_show(struct seq_file *seqf, void *unused) 290 + { 291 + struct waterforce_data *priv = seqf->private; 292 + 293 + seq_printf(seqf, "%u\n", priv->firmware_version); 294 + 295 + return 0; 296 + } 297 + DEFINE_SHOW_ATTRIBUTE(firmware_version); 298 + 299 + static void waterforce_debugfs_init(struct waterforce_data *priv) 300 + { 301 + char name[64]; 302 + 303 + if (!priv->firmware_version) 304 + return; /* There's nothing to show in debugfs */ 305 + 306 + scnprintf(name, sizeof(name), "%s-%s", DRIVER_NAME, dev_name(&priv->hdev->dev)); 307 + 308 + priv->debugfs = debugfs_create_dir(name, NULL); 309 + debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops); 310 + } 311 + 312 + static int waterforce_probe(struct hid_device *hdev, const struct hid_device_id *id) 313 + { 314 + struct waterforce_data *priv; 315 + int ret; 316 + 317 + priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL); 318 + if (!priv) 319 + return -ENOMEM; 320 + 321 + priv->hdev = hdev; 322 + hid_set_drvdata(hdev, priv); 323 + 324 + /* 325 + * Initialize priv->updated to STATUS_VALIDITY seconds in the past, making 326 + * the initial empty data invalid for waterforce_read() without the need for 327 + * a special case there. 328 + */ 329 + priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY); 330 + 331 + ret = hid_parse(hdev); 332 + if (ret) { 333 + hid_err(hdev, "hid parse failed with %d\n", ret); 334 + return ret; 335 + } 336 + 337 + /* 338 + * Enable hidraw so existing user-space tools can continue to work. 339 + */ 340 + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 341 + if (ret) { 342 + hid_err(hdev, "hid hw start failed with %d\n", ret); 343 + return ret; 344 + } 345 + 346 + ret = hid_hw_open(hdev); 347 + if (ret) { 348 + hid_err(hdev, "hid hw open failed with %d\n", ret); 349 + goto fail_and_stop; 350 + } 351 + 352 + priv->buffer = devm_kzalloc(&hdev->dev, MAX_REPORT_LENGTH, GFP_KERNEL); 353 + if (!priv->buffer) { 354 + ret = -ENOMEM; 355 + goto fail_and_close; 356 + } 357 + 358 + mutex_init(&priv->status_report_request_mutex); 359 + mutex_init(&priv->buffer_lock); 360 + spin_lock_init(&priv->status_report_request_lock); 361 + init_completion(&priv->status_report_received); 362 + init_completion(&priv->fw_version_processed); 363 + 364 + hid_device_io_start(hdev); 365 + ret = waterforce_get_fw_ver(hdev); 366 + if (ret < 0) 367 + hid_warn(hdev, "fw version request failed with %d\n", ret); 368 + 369 + priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "waterforce", 370 + priv, &waterforce_chip_info, NULL); 371 + if (IS_ERR(priv->hwmon_dev)) { 372 + ret = PTR_ERR(priv->hwmon_dev); 373 + hid_err(hdev, "hwmon registration failed with %d\n", ret); 374 + goto fail_and_close; 375 + } 376 + 377 + waterforce_debugfs_init(priv); 378 + 379 + return 0; 380 + 381 + fail_and_close: 382 + hid_hw_close(hdev); 383 + fail_and_stop: 384 + hid_hw_stop(hdev); 385 + return ret; 386 + } 387 + 388 + static void waterforce_remove(struct hid_device *hdev) 389 + { 390 + struct waterforce_data *priv = hid_get_drvdata(hdev); 391 + 392 + debugfs_remove_recursive(priv->debugfs); 393 + hwmon_device_unregister(priv->hwmon_dev); 394 + 395 + hid_hw_close(hdev); 396 + hid_hw_stop(hdev); 397 + } 398 + 399 + static const struct hid_device_id waterforce_table[] = { 400 + { HID_USB_DEVICE(USB_VENDOR_ID_GIGABYTE, USB_PRODUCT_ID_WATERFORCE) }, 401 + { } 402 + }; 403 + 404 + MODULE_DEVICE_TABLE(hid, waterforce_table); 405 + 406 + static struct hid_driver waterforce_driver = { 407 + .name = "waterforce", 408 + .id_table = waterforce_table, 409 + .probe = waterforce_probe, 410 + .remove = waterforce_remove, 411 + .raw_event = waterforce_raw_event, 412 + }; 413 + 414 + static int __init waterforce_init(void) 415 + { 416 + return hid_register_driver(&waterforce_driver); 417 + } 418 + 419 + static void __exit waterforce_exit(void) 420 + { 421 + hid_unregister_driver(&waterforce_driver); 422 + } 423 + 424 + /* When compiled into the kernel, initialize after the HID bus */ 425 + late_initcall(waterforce_init); 426 + module_exit(waterforce_exit); 427 + 428 + MODULE_LICENSE("GPL"); 429 + MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>"); 430 + MODULE_DESCRIPTION("Hwmon driver for Gigabyte AORUS Waterforce AIO coolers");
+110 -15
drivers/hwmon/hp-wmi-sensors.c
··· 17 17 * Available: https://github.com/linuxhw/ACPI 18 18 * [4] P. Rohár, "bmfdec - Decompile binary MOF file (BMF) from WMI buffer", 19 19 * 2017. [Online]. Available: https://github.com/pali/bmfdec 20 + * [5] Microsoft Corporation, "Driver-Defined WMI Data Items", 2017. [Online]. 21 + * Available: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items 20 22 */ 21 23 22 24 #include <linux/acpi.h> ··· 26 24 #include <linux/hwmon.h> 27 25 #include <linux/jiffies.h> 28 26 #include <linux/mutex.h> 27 + #include <linux/nls.h> 29 28 #include <linux/units.h> 30 29 #include <linux/wmi.h> 31 30 ··· 398 395 struct mutex lock; /* Lock polling WMI and driver state changes. */ 399 396 }; 400 397 398 + static bool is_raw_wmi_string(const u8 *pointer, u32 length) 399 + { 400 + const u16 *ptr; 401 + u16 len; 402 + 403 + /* WMI strings are length-prefixed UTF-16 [5]. */ 404 + if (length <= sizeof(*ptr)) 405 + return false; 406 + 407 + length -= sizeof(*ptr); 408 + ptr = (const u16 *)pointer; 409 + len = *ptr; 410 + 411 + return len <= length && !(len & 1); 412 + } 413 + 414 + static char *convert_raw_wmi_string(const u8 *buf) 415 + { 416 + const wchar_t *src; 417 + unsigned int cps; 418 + unsigned int len; 419 + char *dst; 420 + int i; 421 + 422 + src = (const wchar_t *)buf; 423 + 424 + /* Count UTF-16 code points. Exclude trailing null padding. */ 425 + cps = *src / sizeof(*src); 426 + while (cps && !src[cps]) 427 + cps--; 428 + 429 + /* Each code point becomes up to 3 UTF-8 characters. */ 430 + len = min(cps * 3, HP_WMI_MAX_STR_SIZE - 1); 431 + 432 + dst = kmalloc((len + 1) * sizeof(*dst), GFP_KERNEL); 433 + if (!dst) 434 + return NULL; 435 + 436 + i = utf16s_to_utf8s(++src, cps, UTF16_LITTLE_ENDIAN, dst, len); 437 + dst[i] = '\0'; 438 + 439 + return dst; 440 + } 441 + 401 442 /* hp_wmi_strdup - devm_kstrdup, but length-limited */ 402 443 static char *hp_wmi_strdup(struct device *dev, const char *src) 403 444 { ··· 455 408 return NULL; 456 409 457 410 strscpy(dst, src, len + 1); 411 + 412 + return dst; 413 + } 414 + 415 + /* hp_wmi_wstrdup - hp_wmi_strdup, but for a raw WMI string */ 416 + static char *hp_wmi_wstrdup(struct device *dev, const u8 *buf) 417 + { 418 + char *src; 419 + char *dst; 420 + 421 + src = convert_raw_wmi_string(buf); 422 + if (!src) 423 + return NULL; 424 + 425 + dst = hp_wmi_strdup(dev, strim(src)); /* Note: Copy is trimmed. */ 426 + 427 + kfree(src); 458 428 459 429 return dst; 460 430 } ··· 526 462 for (prop = 0; prop <= last_prop; prop++) { 527 463 type = elements[prop].type; 528 464 valid_type = property_map[prop]; 529 - if (type != valid_type) 465 + if (type != valid_type) { 466 + if (type == ACPI_TYPE_BUFFER && 467 + valid_type == ACPI_TYPE_STRING && 468 + is_raw_wmi_string(elements[prop].buffer.pointer, 469 + elements[prop].buffer.length)) 470 + continue; 530 471 return -EINVAL; 472 + } 531 473 } 532 474 533 475 return 0; ··· 550 480 break; 551 481 552 482 case ACPI_TYPE_STRING: 553 - *out_string = hp_wmi_strdup(dev, strim(element->string.pointer)); 483 + *out_string = element->type == ACPI_TYPE_BUFFER ? 484 + hp_wmi_wstrdup(dev, element->buffer.pointer) : 485 + hp_wmi_strdup(dev, strim(element->string.pointer)); 554 486 if (!*out_string) 555 487 return -ENOMEM; 556 488 break; ··· 933 861 { 934 862 const union acpi_object *elements; 935 863 const union acpi_object *element; 936 - const char *string; 864 + const char *new_string; 865 + char *trimmed; 866 + char *string; 937 867 bool is_new; 938 868 int offset; 939 869 u8 size; ··· 959 885 offset = is_new ? size - 1 : -2; 960 886 961 887 element = &elements[HP_WMI_PROPERTY_CURRENT_STATE + offset]; 962 - string = strim(element->string.pointer); 888 + string = element->type == ACPI_TYPE_BUFFER ? 889 + convert_raw_wmi_string(element->buffer.pointer) : 890 + element->string.pointer; 963 891 964 - if (strcmp(string, nsensor->current_state)) { 965 - devm_kfree(dev, nsensor->current_state); 966 - nsensor->current_state = hp_wmi_strdup(dev, string); 892 + if (string) { 893 + trimmed = strim(string); 894 + if (strcmp(trimmed, nsensor->current_state)) { 895 + new_string = hp_wmi_strdup(dev, trimmed); 896 + if (new_string) { 897 + devm_kfree(dev, nsensor->current_state); 898 + nsensor->current_state = new_string; 899 + } 900 + } 901 + if (element->type == ACPI_TYPE_BUFFER) 902 + kfree(string); 967 903 } 968 904 969 905 /* Old variant: -2 (not -1) because it lacks the Size property. */ ··· 1080 996 HP_WMI_EVENT_PROPERTY_STATUS); 1081 997 } 1082 998 1083 - static int populate_event_from_wobj(struct hp_wmi_event *event, 999 + static int populate_event_from_wobj(struct device *dev, 1000 + struct hp_wmi_event *event, 1084 1001 union acpi_object *wobj) 1085 1002 { 1086 1003 int prop = HP_WMI_EVENT_PROPERTY_NAME; 1087 1004 union acpi_object *element; 1005 + acpi_object_type type; 1006 + char *string; 1007 + u32 value; 1088 1008 int err; 1089 1009 1090 1010 err = check_event_wobj(wobj); ··· 1097 1009 1098 1010 element = wobj->package.elements; 1099 1011 1100 - /* Extracted strings are NOT device-managed copies. */ 1101 - 1102 1012 for (; prop <= HP_WMI_EVENT_PROPERTY_CATEGORY; prop++, element++) { 1013 + type = hp_wmi_event_property_map[prop]; 1014 + 1015 + err = extract_acpi_value(dev, element, type, &value, &string); 1016 + if (err) 1017 + return err; 1018 + 1103 1019 switch (prop) { 1104 1020 case HP_WMI_EVENT_PROPERTY_NAME: 1105 - event->name = strim(element->string.pointer); 1021 + event->name = string; 1106 1022 break; 1107 1023 1108 1024 case HP_WMI_EVENT_PROPERTY_DESCRIPTION: 1109 - event->description = strim(element->string.pointer); 1025 + event->description = string; 1110 1026 break; 1111 1027 1112 1028 case HP_WMI_EVENT_PROPERTY_CATEGORY: 1113 - event->category = element->integer.value; 1029 + event->category = value; 1114 1030 break; 1115 1031 1116 1032 default: ··· 1603 1511 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 1604 1512 struct hp_wmi_sensors *state = context; 1605 1513 struct device *dev = &state->wdev->dev; 1514 + struct hp_wmi_event event = {}; 1606 1515 struct hp_wmi_info *fan_info; 1607 - struct hp_wmi_event event; 1608 1516 union acpi_object *wobj; 1609 1517 acpi_status err; 1610 1518 int event_type; ··· 1638 1546 1639 1547 wobj = out.pointer; 1640 1548 1641 - err = populate_event_from_wobj(&event, wobj); 1549 + err = populate_event_from_wobj(dev, &event, wobj); 1642 1550 if (err) { 1643 1551 dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type); 1644 1552 goto out_free_wobj; ··· 1668 1576 1669 1577 out_free_wobj: 1670 1578 kfree(wobj); 1579 + 1580 + devm_kfree(dev, event.name); 1581 + devm_kfree(dev, event.description); 1671 1582 1672 1583 out_unlock: 1673 1584 mutex_unlock(&state->lock);
+1
drivers/hwmon/k10temp.c
··· 455 455 456 456 switch (boot_cpu_data.x86_model) { 457 457 case 0x0 ... 0x1: /* Zen3 SP3/TR */ 458 + case 0x8: /* Zen3 TR Chagall */ 458 459 case 0x21: /* Zen3 Ryzen Desktop */ 459 460 case 0x50 ... 0x5f: /* Green Sardine */ 460 461 data->ccd_offset = 0x154;
+97 -17
drivers/hwmon/lm75.c
··· 7 7 8 8 #include <linux/module.h> 9 9 #include <linux/init.h> 10 + #include <linux/interrupt.h> 10 11 #include <linux/slab.h> 11 12 #include <linux/jiffies.h> 12 13 #include <linux/i2c.h> 13 14 #include <linux/hwmon.h> 14 - #include <linux/hwmon-sysfs.h> 15 15 #include <linux/err.h> 16 16 #include <linux/of.h> 17 17 #include <linux/regmap.h> ··· 25 25 26 26 enum lm75_type { /* keep sorted in alphabetical order */ 27 27 adt75, 28 + as6200, 28 29 at30ts74, 29 30 ds1775, 30 31 ds75, ··· 56 55 57 56 /** 58 57 * struct lm75_params - lm75 configuration parameters. 58 + * @config_reg_16bits: Configure register size is 2 bytes. 59 59 * @set_mask: Bits to set in configuration register when configuring 60 60 * the chip. 61 61 * @clr_mask: Bits to clear in configuration register when configuring ··· 77 75 * @sample_times: All the possible sample times to be set. Mandatory if 78 76 * num_sample_times is larger than 1. If set, number of 79 77 * entries must match num_sample_times. 78 + * @alarm: Alarm bit is supported. 80 79 */ 81 80 82 81 struct lm75_params { 83 - u8 set_mask; 84 - u8 clr_mask; 82 + bool config_reg_16bits; 83 + u16 set_mask; 84 + u16 clr_mask; 85 85 u8 default_resolution; 86 86 u8 resolution_limits; 87 87 const u8 *resolutions; 88 88 unsigned int default_sample_time; 89 89 u8 num_sample_times; 90 90 const unsigned int *sample_times; 91 + bool alarm; 91 92 }; 92 93 93 94 /* Addresses scanned */ ··· 109 104 struct i2c_client *client; 110 105 struct regmap *regmap; 111 106 struct regulator *vs; 112 - u8 orig_conf; 113 - u8 current_conf; 107 + u16 orig_conf; 108 + u16 current_conf; 114 109 u8 resolution; /* In bits, 9 to 16 */ 115 110 unsigned int sample_time; /* In ms */ 116 111 enum lm75_type kind; ··· 132 127 .clr_mask = 1 << 5, /* not one-shot mode */ 133 128 .default_resolution = 12, 134 129 .default_sample_time = MSEC_PER_SEC / 10, 130 + }, 131 + [as6200] = { 132 + .config_reg_16bits = true, 133 + .set_mask = 0x94C0, /* 8 sample/s, 4 CF, positive polarity */ 134 + .default_resolution = 12, 135 + .default_sample_time = 125, 136 + .num_sample_times = 4, 137 + .sample_times = (unsigned int []){ 125, 250, 1000, 4000 }, 138 + .alarm = true, 135 139 }, 136 140 [at30ts74] = { 137 141 .set_mask = 3 << 5, /* 12-bit mode*/ ··· 269 255 .resolutions = (u8 []) {9, 10, 11, 12 }, 270 256 }, 271 257 [tmp112] = { 272 - .set_mask = 3 << 5, /* 8 samples / second */ 273 - .clr_mask = 1 << 7, /* no one-shot mode*/ 258 + .config_reg_16bits = true, 259 + .set_mask = 0x60C0, /* 12-bit mode, 8 samples / second */ 260 + .clr_mask = 1 << 15, /* no one-shot mode*/ 274 261 .default_resolution = 12, 275 262 .default_sample_time = 125, 276 263 .num_sample_times = 4, ··· 332 317 return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); 333 318 } 334 319 335 - static int lm75_write_config(struct lm75_data *data, u8 set_mask, 336 - u8 clr_mask) 320 + static int lm75_write_config(struct lm75_data *data, u16 set_mask, 321 + u16 clr_mask) 337 322 { 338 - u8 value; 323 + unsigned int value; 339 324 340 - clr_mask |= LM75_SHUTDOWN; 325 + clr_mask |= LM75_SHUTDOWN << (8 * data->params->config_reg_16bits); 341 326 value = data->current_conf & ~clr_mask; 342 327 value |= set_mask; 343 328 344 329 if (data->current_conf != value) { 345 330 s32 err; 346 - 347 - err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF, 348 - value); 331 + if (data->params->config_reg_16bits) 332 + err = regmap_write(data->regmap, LM75_REG_CONF, value); 333 + else 334 + err = i2c_smbus_write_byte_data(data->client, 335 + LM75_REG_CONF, 336 + value); 349 337 if (err) 350 338 return err; 351 339 data->current_conf = value; 352 340 } 353 341 return 0; 342 + } 343 + 344 + static int lm75_read_config(struct lm75_data *data) 345 + { 346 + int ret; 347 + unsigned int status; 348 + 349 + if (data->params->config_reg_16bits) { 350 + ret = regmap_read(data->regmap, LM75_REG_CONF, &status); 351 + return ret ? ret : status; 352 + } 353 + 354 + return i2c_smbus_read_byte_data(data->client, LM75_REG_CONF); 355 + } 356 + 357 + static irqreturn_t lm75_alarm_handler(int irq, void *private) 358 + { 359 + struct device *hwmon_dev = private; 360 + 361 + hwmon_notify_event(hwmon_dev, hwmon_temp, hwmon_temp_alarm, 0); 362 + return IRQ_HANDLED; 354 363 } 355 364 356 365 static int lm75_read(struct device *dev, enum hwmon_sensor_types type, ··· 405 366 case hwmon_temp_max_hyst: 406 367 reg = LM75_REG_HYST; 407 368 break; 369 + case hwmon_temp_alarm: 370 + reg = LM75_REG_CONF; 371 + break; 408 372 default: 409 373 return -EINVAL; 410 374 } ··· 415 373 if (err < 0) 416 374 return err; 417 375 418 - *val = lm75_reg_to_mc(regval, data->resolution); 376 + if (attr == hwmon_temp_alarm) { 377 + switch (data->kind) { 378 + case as6200: 379 + *val = (regval >> 5) & 0x1; 380 + break; 381 + default: 382 + return -EINVAL; 383 + } 384 + } else { 385 + *val = lm75_reg_to_mc(regval, data->resolution); 386 + } 419 387 break; 420 388 default: 421 389 return -EINVAL; ··· 488 436 data->resolution = data->params->resolutions[index]; 489 437 break; 490 438 case tmp112: 439 + case as6200: 491 440 err = regmap_read(data->regmap, LM75_REG_CONF, &reg); 492 441 if (err < 0) 493 442 return err; ··· 556 503 case hwmon_temp_max: 557 504 case hwmon_temp_max_hyst: 558 505 return 0644; 506 + case hwmon_temp_alarm: 507 + if (config_data->params->alarm) 508 + return 0444; 509 + break; 559 510 } 560 511 break; 561 512 default: ··· 572 515 HWMON_CHANNEL_INFO(chip, 573 516 HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), 574 517 HWMON_CHANNEL_INFO(temp, 575 - HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), 518 + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 519 + HWMON_T_ALARM), 576 520 NULL 577 521 }; 578 522 ··· 681 623 return err; 682 624 683 625 /* Cache original configuration */ 684 - status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); 626 + status = lm75_read_config(data); 685 627 if (status < 0) { 686 628 dev_dbg(dev, "Can't read config? %d\n", status); 687 629 return status; ··· 704 646 if (IS_ERR(hwmon_dev)) 705 647 return PTR_ERR(hwmon_dev); 706 648 649 + if (client->irq) { 650 + if (data->params->alarm) { 651 + err = devm_request_threaded_irq(dev, 652 + client->irq, 653 + NULL, 654 + &lm75_alarm_handler, 655 + IRQF_ONESHOT, 656 + client->name, 657 + hwmon_dev); 658 + if (err) 659 + return err; 660 + } else { 661 + /* alarm is only supported for chips with alarm bit */ 662 + dev_err(dev, "alarm interrupt is not supported\n"); 663 + } 664 + } 665 + 707 666 dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); 708 667 709 668 return 0; ··· 728 653 729 654 static const struct i2c_device_id lm75_ids[] = { 730 655 { "adt75", adt75, }, 656 + { "as6200", as6200, }, 731 657 { "at30ts74", at30ts74, }, 732 658 { "ds1775", ds1775, }, 733 659 { "ds75", ds75, }, ··· 764 688 { 765 689 .compatible = "adi,adt75", 766 690 .data = (void *)adt75 691 + }, 692 + { 693 + .compatible = "ams,as6200", 694 + .data = (void *)as6200 767 695 }, 768 696 { 769 697 .compatible = "atmel,at30ts74",
+9 -11
drivers/hwmon/ltc2991.c
··· 54 54 #define LTC2991_VCC_CH_NR 0 55 55 56 56 struct ltc2991_state { 57 - struct device *dev; 58 57 struct regmap *regmap; 59 58 u32 r_sense_uohm[LTC2991_MAX_CHANNEL]; 60 59 bool temp_en[LTC2991_MAX_CHANNEL]; ··· 282 283 .max_register = 0x1D, 283 284 }; 284 285 285 - static int ltc2991_init(struct ltc2991_state *st) 286 + static int ltc2991_init(struct ltc2991_state *st, struct device *dev) 286 287 { 287 288 struct fwnode_handle *child; 288 289 int ret; 289 290 u32 val, addr; 290 291 u8 v5_v8_reg_data = 0, v1_v4_reg_data = 0; 291 292 292 - ret = devm_regulator_get_enable(st->dev, "vcc"); 293 + ret = devm_regulator_get_enable(dev, "vcc"); 293 294 if (ret) 294 - return dev_err_probe(st->dev, ret, 295 + return dev_err_probe(dev, ret, 295 296 "failed to enable regulator\n"); 296 297 297 - device_for_each_child_node(st->dev, child) { 298 + device_for_each_child_node(dev, child) { 298 299 ret = fwnode_property_read_u32(child, "reg", &addr); 299 300 if (ret < 0) { 300 301 fwnode_handle_put(child); ··· 311 312 &val); 312 313 if (!ret) { 313 314 if (!val) 314 - return dev_err_probe(st->dev, -EINVAL, 315 + return dev_err_probe(dev, -EINVAL, 315 316 "shunt resistor value cannot be zero\n"); 316 317 317 318 st->r_sense_uohm[addr] = val; ··· 360 361 361 362 ret = regmap_write(st->regmap, LTC2991_V5_V8_CTRL, v5_v8_reg_data); 362 363 if (ret) 363 - return dev_err_probe(st->dev, ret, 364 + return dev_err_probe(dev, ret, 364 365 "Error: Failed to set V5-V8 CTRL reg.\n"); 365 366 366 367 ret = regmap_write(st->regmap, LTC2991_V1_V4_CTRL, v1_v4_reg_data); 367 368 if (ret) 368 - return dev_err_probe(st->dev, ret, 369 + return dev_err_probe(dev, ret, 369 370 "Error: Failed to set V1-V4 CTRL reg.\n"); 370 371 371 372 ret = regmap_write(st->regmap, LTC2991_PWM_TH_LSB_T_INT, 372 373 LTC2991_REPEAT_ACQ_EN); 373 374 if (ret) 374 - return dev_err_probe(st->dev, ret, 375 + return dev_err_probe(dev, ret, 375 376 "Error: Failed to set continuous mode.\n"); 376 377 377 378 /* Enable all channels and trigger conversions */ ··· 391 392 if (!st) 392 393 return -ENOMEM; 393 394 394 - st->dev = &client->dev; 395 395 st->regmap = devm_regmap_init_i2c(client, &ltc2991_regmap_config); 396 396 if (IS_ERR(st->regmap)) 397 397 return PTR_ERR(st->regmap); 398 398 399 - ret = ltc2991_init(st); 399 + ret = ltc2991_init(st, &client->dev); 400 400 if (ret) 401 401 return ret; 402 402
+243 -32
drivers/hwmon/max31827.c
··· 11 11 #include <linux/hwmon.h> 12 12 #include <linux/i2c.h> 13 13 #include <linux/mutex.h> 14 + #include <linux/of_device.h> 14 15 #include <linux/regmap.h> 15 16 #include <linux/regulator/consumer.h> 16 17 ··· 24 23 25 24 #define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0) 26 25 #define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1) 26 + #define MAX31827_CONFIGURATION_TIMEOUT_MASK BIT(5) 27 + #define MAX31827_CONFIGURATION_RESOLUTION_MASK GENMASK(7, 6) 28 + #define MAX31827_CONFIGURATION_ALRM_POL_MASK BIT(8) 29 + #define MAX31827_CONFIGURATION_COMP_INT_MASK BIT(9) 30 + #define MAX31827_CONFIGURATION_FLT_Q_MASK GENMASK(11, 10) 27 31 #define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14) 28 32 #define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15) 29 33 34 + #define MAX31827_ALRM_POL_LOW 0x0 35 + #define MAX31827_ALRM_POL_HIGH 0x1 36 + #define MAX31827_FLT_Q_1 0x0 37 + #define MAX31827_FLT_Q_4 0x2 38 + 39 + #define MAX31827_8_BIT_CNV_TIME 9 40 + #define MAX31827_9_BIT_CNV_TIME 18 41 + #define MAX31827_10_BIT_CNV_TIME 35 30 42 #define MAX31827_12_BIT_CNV_TIME 140 31 43 32 44 #define MAX31827_16_BIT_TO_M_DGR(x) (sign_extend32(x, 15) * 1000 / 16) 33 45 #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) 34 46 #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) 47 + 48 + enum chips { max31827 = 1, max31828, max31829 }; 35 49 36 50 enum max31827_cnv { 37 51 MAX31827_CNV_1_DIV_64_HZ = 1, ··· 68 52 [MAX31827_CNV_8_HZ] = 125, 69 53 }; 70 54 55 + enum max31827_resolution { 56 + MAX31827_RES_8_BIT = 0, 57 + MAX31827_RES_9_BIT, 58 + MAX31827_RES_10_BIT, 59 + MAX31827_RES_12_BIT, 60 + }; 61 + 62 + static const u16 max31827_resolutions[] = { 63 + [MAX31827_RES_8_BIT] = 1000, 64 + [MAX31827_RES_9_BIT] = 500, 65 + [MAX31827_RES_10_BIT] = 250, 66 + [MAX31827_RES_12_BIT] = 62, 67 + }; 68 + 69 + static const u16 max31827_conv_times[] = { 70 + [MAX31827_RES_8_BIT] = MAX31827_8_BIT_CNV_TIME, 71 + [MAX31827_RES_9_BIT] = MAX31827_9_BIT_CNV_TIME, 72 + [MAX31827_RES_10_BIT] = MAX31827_10_BIT_CNV_TIME, 73 + [MAX31827_RES_12_BIT] = MAX31827_12_BIT_CNV_TIME, 74 + }; 75 + 71 76 struct max31827_state { 72 77 /* 73 78 * Prevent simultaneous access to the i2c client. ··· 96 59 struct mutex lock; 97 60 struct regmap *regmap; 98 61 bool enable; 62 + unsigned int resolution; 63 + unsigned int update_interval; 99 64 }; 100 65 101 66 static const struct regmap_config max31827_regmap = { ··· 107 68 }; 108 69 109 70 static int shutdown_write(struct max31827_state *st, unsigned int reg, 110 - unsigned int val) 71 + unsigned int mask, unsigned int val) 111 72 { 112 73 unsigned int cfg; 113 74 unsigned int cnv_rate; 114 75 int ret; 115 76 116 77 /* 117 - * Before the Temperature Threshold Alarm and Alarm Hysteresis Threshold 118 - * register values are changed over I2C, the part must be in shutdown 119 - * mode. 78 + * Before the Temperature Threshold Alarm, Alarm Hysteresis Threshold 79 + * and Resolution bits from Configuration register are changed over I2C, 80 + * the part must be in shutdown mode. 120 81 * 121 82 * Mutex is used to ensure, that some other process doesn't change the 122 83 * configuration register. ··· 124 85 mutex_lock(&st->lock); 125 86 126 87 if (!st->enable) { 127 - ret = regmap_write(st->regmap, reg, val); 88 + if (!mask) 89 + ret = regmap_write(st->regmap, reg, val); 90 + else 91 + ret = regmap_update_bits(st->regmap, reg, mask, val); 128 92 goto unlock; 129 93 } 130 94 ··· 142 100 if (ret) 143 101 goto unlock; 144 102 145 - ret = regmap_write(st->regmap, reg, val); 103 + if (!mask) 104 + ret = regmap_write(st->regmap, reg, val); 105 + else 106 + ret = regmap_update_bits(st->regmap, reg, mask, val); 107 + 146 108 if (ret) 147 109 goto unlock; 148 110 ··· 164 118 { 165 119 val = MAX31827_M_DGR_TO_16_BIT(val); 166 120 167 - return shutdown_write(st, reg, val); 121 + return shutdown_write(st, reg, 0, val); 168 122 } 169 123 170 124 static umode_t max31827_is_visible(const void *state, ··· 234 188 mutex_unlock(&st->lock); 235 189 return ret; 236 190 } 237 - 238 - msleep(MAX31827_12_BIT_CNV_TIME); 191 + msleep(max31827_conv_times[st->resolution]); 239 192 } 193 + 194 + /* 195 + * For 12-bit resolution the conversion time is 140 ms, 196 + * thus an additional 15 ms is needed to complete the 197 + * conversion: 125 ms + 15 ms = 140 ms 198 + */ 199 + if (max31827_resolutions[st->resolution] == 12 && 200 + st->update_interval == 125) 201 + usleep_range(15000, 20000); 202 + 240 203 ret = regmap_read(st->regmap, MAX31827_T_REG, &uval); 241 204 242 205 mutex_unlock(&st->lock); ··· 396 341 val < max31827_conversions[res]) 397 342 res++; 398 343 399 - if (res == ARRAY_SIZE(max31827_conversions) || 400 - val != max31827_conversions[res]) 401 - return -EINVAL; 344 + if (res == ARRAY_SIZE(max31827_conversions)) 345 + res = ARRAY_SIZE(max31827_conversions) - 1; 402 346 403 347 res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK, 404 348 res); 405 349 406 - return regmap_update_bits(st->regmap, 407 - MAX31827_CONFIGURATION_REG, 408 - MAX31827_CONFIGURATION_CNV_RATE_MASK, 409 - res); 350 + ret = regmap_update_bits(st->regmap, 351 + MAX31827_CONFIGURATION_REG, 352 + MAX31827_CONFIGURATION_CNV_RATE_MASK, 353 + res); 354 + if (ret) 355 + return ret; 356 + 357 + st->update_interval = val; 410 358 } 411 359 break; 412 360 ··· 417 359 return -EOPNOTSUPP; 418 360 } 419 361 420 - return -EOPNOTSUPP; 362 + return 0; 421 363 } 422 364 423 - static int max31827_init_client(struct max31827_state *st) 365 + static ssize_t temp1_resolution_show(struct device *dev, 366 + struct device_attribute *devattr, 367 + char *buf) 424 368 { 425 - st->enable = true; 369 + struct max31827_state *st = dev_get_drvdata(dev); 370 + unsigned int val; 371 + int ret; 426 372 427 - return regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, 428 - MAX31827_CONFIGURATION_1SHOT_MASK | 429 - MAX31827_CONFIGURATION_CNV_RATE_MASK, 430 - MAX31827_DEVICE_ENABLE(1)); 373 + ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &val); 374 + if (ret) 375 + return ret; 376 + 377 + val = FIELD_GET(MAX31827_CONFIGURATION_RESOLUTION_MASK, val); 378 + 379 + return scnprintf(buf, PAGE_SIZE, "%u\n", max31827_resolutions[val]); 380 + } 381 + 382 + static ssize_t temp1_resolution_store(struct device *dev, 383 + struct device_attribute *devattr, 384 + const char *buf, size_t count) 385 + { 386 + struct max31827_state *st = dev_get_drvdata(dev); 387 + unsigned int idx = 0; 388 + unsigned int val; 389 + int ret; 390 + 391 + ret = kstrtouint(buf, 10, &val); 392 + if (ret) 393 + return ret; 394 + 395 + /* 396 + * Convert the desired resolution into register 397 + * bits. idx is already initialized with 0. 398 + * 399 + * This was inspired by lm73 driver. 400 + */ 401 + while (idx < ARRAY_SIZE(max31827_resolutions) && 402 + val < max31827_resolutions[idx]) 403 + idx++; 404 + 405 + if (idx == ARRAY_SIZE(max31827_resolutions)) 406 + idx = ARRAY_SIZE(max31827_resolutions) - 1; 407 + 408 + st->resolution = idx; 409 + 410 + ret = shutdown_write(st, MAX31827_CONFIGURATION_REG, 411 + MAX31827_CONFIGURATION_RESOLUTION_MASK, 412 + FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK, 413 + idx)); 414 + 415 + return ret ? ret : count; 416 + } 417 + 418 + static DEVICE_ATTR_RW(temp1_resolution); 419 + 420 + static struct attribute *max31827_attrs[] = { 421 + &dev_attr_temp1_resolution.attr, 422 + NULL 423 + }; 424 + ATTRIBUTE_GROUPS(max31827); 425 + 426 + static const struct i2c_device_id max31827_i2c_ids[] = { 427 + { "max31827", max31827 }, 428 + { "max31828", max31828 }, 429 + { "max31829", max31829 }, 430 + { } 431 + }; 432 + MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids); 433 + 434 + static int max31827_init_client(struct max31827_state *st, 435 + struct device *dev) 436 + { 437 + struct fwnode_handle *fwnode; 438 + unsigned int res = 0; 439 + u32 data, lsb_idx; 440 + enum chips type; 441 + bool prop; 442 + int ret; 443 + 444 + fwnode = dev_fwnode(dev); 445 + 446 + st->enable = true; 447 + res |= MAX31827_DEVICE_ENABLE(1); 448 + 449 + res |= MAX31827_CONFIGURATION_RESOLUTION_MASK; 450 + 451 + prop = fwnode_property_read_bool(fwnode, "adi,comp-int"); 452 + res |= FIELD_PREP(MAX31827_CONFIGURATION_COMP_INT_MASK, prop); 453 + 454 + prop = fwnode_property_read_bool(fwnode, "adi,timeout-enable"); 455 + res |= FIELD_PREP(MAX31827_CONFIGURATION_TIMEOUT_MASK, !prop); 456 + 457 + type = (enum chips)(uintptr_t)device_get_match_data(dev); 458 + 459 + if (fwnode_property_present(fwnode, "adi,alarm-pol")) { 460 + ret = fwnode_property_read_u32(fwnode, "adi,alarm-pol", &data); 461 + if (ret) 462 + return ret; 463 + 464 + res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, !!data); 465 + } else { 466 + /* 467 + * Set default value. 468 + */ 469 + switch (type) { 470 + case max31827: 471 + case max31828: 472 + res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, 473 + MAX31827_ALRM_POL_LOW); 474 + break; 475 + case max31829: 476 + res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, 477 + MAX31827_ALRM_POL_HIGH); 478 + break; 479 + default: 480 + return -EOPNOTSUPP; 481 + } 482 + } 483 + 484 + if (fwnode_property_present(fwnode, "adi,fault-q")) { 485 + ret = fwnode_property_read_u32(fwnode, "adi,fault-q", &data); 486 + if (ret) 487 + return ret; 488 + 489 + /* 490 + * Convert the desired fault queue into register bits. 491 + */ 492 + if (data != 0) 493 + lsb_idx = __ffs(data); 494 + 495 + if (hweight32(data) != 1 || lsb_idx > 4) { 496 + dev_err(dev, "Invalid data in adi,fault-q\n"); 497 + return -EINVAL; 498 + } 499 + 500 + res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, lsb_idx); 501 + } else { 502 + /* 503 + * Set default value. 504 + */ 505 + switch (type) { 506 + case max31827: 507 + res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, 508 + MAX31827_FLT_Q_1); 509 + break; 510 + case max31828: 511 + case max31829: 512 + res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, 513 + MAX31827_FLT_Q_4); 514 + break; 515 + default: 516 + return -EOPNOTSUPP; 517 + } 518 + } 519 + 520 + return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res); 431 521 } 432 522 433 523 static const struct hwmon_channel_info *max31827_info[] = { ··· 623 417 if (err) 624 418 return dev_err_probe(dev, err, "failed to enable regulator\n"); 625 419 626 - err = max31827_init_client(st); 420 + err = max31827_init_client(st, dev); 627 421 if (err) 628 422 return err; 629 423 630 424 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st, 631 425 &max31827_chip_info, 632 - NULL); 426 + max31827_groups); 633 427 634 428 return PTR_ERR_OR_ZERO(hwmon_dev); 635 429 } 636 430 637 - static const struct i2c_device_id max31827_i2c_ids[] = { 638 - { "max31827", 0 }, 639 - { } 640 - }; 641 - MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids); 642 - 643 431 static const struct of_device_id max31827_of_match[] = { 644 - { .compatible = "adi,max31827" }, 432 + { 433 + .compatible = "adi,max31827", 434 + .data = (void *)max31827 435 + }, 436 + { 437 + .compatible = "adi,max31828", 438 + .data = (void *)max31828 439 + }, 440 + { 441 + .compatible = "adi,max31829", 442 + .data = (void *)max31829 443 + }, 645 444 { } 646 445 }; 647 446 MODULE_DEVICE_TABLE(of, max31827_of_match);
+3 -5
drivers/hwmon/max6650.c
··· 26 26 #include <linux/hwmon.h> 27 27 #include <linux/hwmon-sysfs.h> 28 28 #include <linux/err.h> 29 - #include <linux/of_device.h> 29 + #include <linux/of.h> 30 30 #include <linux/thermal.h> 31 31 32 32 /* ··· 763 763 { 764 764 struct thermal_cooling_device *cooling_dev; 765 765 struct device *dev = &client->dev; 766 - const struct of_device_id *of_id = 767 - of_match_device(of_match_ptr(max6650_dt_match), dev); 768 766 struct max6650_data *data; 769 767 struct device *hwmon_dev; 770 768 int err; ··· 774 776 data->client = client; 775 777 i2c_set_clientdata(client, data); 776 778 mutex_init(&data->update_lock); 777 - data->nr_fans = of_id ? (int)(uintptr_t)of_id->data : 778 - i2c_match_id(max6650_id, client)->driver_data; 779 + 780 + data->nr_fans = (uintptr_t)i2c_get_match_data(client); 779 781 780 782 /* 781 783 * Initialize the max6650 chip
+24 -17
drivers/hwmon/nct6775-core.c
··· 63 63 64 64 /* used to set data->name = nct6775_device_names[data->sio_kind] */ 65 65 static const char * const nct6775_device_names[] = { 66 - "nct6106", 67 - "nct6116", 68 - "nct6775", 69 - "nct6776", 70 - "nct6779", 71 - "nct6791", 72 - "nct6792", 73 - "nct6793", 74 - "nct6795", 75 - "nct6796", 76 - "nct6797", 77 - "nct6798", 78 - "nct6799", 66 + [nct6106] = "nct6106", 67 + [nct6116] = "nct6116", 68 + [nct6775] = "nct6775", 69 + [nct6776] = "nct6776", 70 + [nct6779] = "nct6779", 71 + [nct6791] = "nct6791", 72 + [nct6792] = "nct6792", 73 + [nct6793] = "nct6793", 74 + [nct6795] = "nct6795", 75 + [nct6796] = "nct6796", 76 + [nct6797] = "nct6797", 77 + [nct6798] = "nct6798", 78 + [nct6799] = "nct6799", 79 79 }; 80 80 81 81 /* Common and NCT6775 specific data */ ··· 767 767 static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6 }; 768 768 static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 }; 769 769 770 - static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 }; 771 - static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 }; 772 - static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c }; 770 + static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3, 0, 0 }; 771 + static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04, 0, 0 }; 772 + static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c, 0xd8, 0xd9 }; 773 773 static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 }; 774 774 static const u16 NCT6106_REG_TEMP_SOURCE[] = { 775 775 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 }; ··· 2553 2553 int err; 2554 2554 u16 reg; 2555 2555 2556 + /* 2557 + * The fan control mode should be set to manual if the user wants to adjust 2558 + * the fan speed. Otherwise, it will fail to set. 2559 + */ 2560 + if (index == 0 && data->pwm_enable[nr] > manual) 2561 + return -EBUSY; 2562 + 2556 2563 err = kstrtoul(buf, 10, &val); 2557 2564 if (err < 0) 2558 2565 return err; ··· 3602 3595 break; 3603 3596 case nct6116: 3604 3597 data->in_num = 9; 3605 - data->pwm_num = 3; 3598 + data->pwm_num = 5; 3606 3599 data->auto_pwm_num = 4; 3607 3600 data->temp_fixed_num = 3; 3608 3601 data->num_temp_alarms = 3;
+2 -12
drivers/hwmon/nct6775-i2c.c
··· 21 21 #include <linux/hwmon.h> 22 22 #include <linux/hwmon-sysfs.h> 23 23 #include <linux/err.h> 24 - #include <linux/of_device.h> 24 + #include <linux/of.h> 25 25 #include <linux/regmap.h> 26 26 #include "nct6775.h" 27 27 ··· 155 155 static int nct6775_i2c_probe(struct i2c_client *client) 156 156 { 157 157 struct nct6775_data *data; 158 - const struct of_device_id *of_id; 159 - const struct i2c_device_id *i2c_id; 160 158 struct device *dev = &client->dev; 161 - 162 - of_id = of_match_device(nct6775_i2c_of_match, dev); 163 - i2c_id = i2c_match_id(nct6775_i2c_id, client); 164 - 165 - if (of_id && (unsigned long)of_id->data != i2c_id->driver_data) 166 - dev_notice(dev, "Device mismatch: %s in device tree, %s detected\n", 167 - of_id->name, i2c_id->name); 168 159 169 160 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 170 161 if (!data) 171 162 return -ENOMEM; 172 163 173 - data->kind = i2c_id->driver_data; 174 - 164 + data->kind = (enum kinds)(uintptr_t)i2c_get_match_data(client); 175 165 data->read_only = true; 176 166 data->driver_data = client; 177 167 data->driver_init = nct6775_i2c_probe_init;
+13 -13
drivers/hwmon/nct6775-platform.c
··· 23 23 enum sensor_access { access_direct, access_asuswmi }; 24 24 25 25 static const char * const nct6775_sio_names[] __initconst = { 26 - "NCT6106D", 27 - "NCT6116D", 28 - "NCT6775F", 29 - "NCT6776D/F", 30 - "NCT6779D", 31 - "NCT6791D", 32 - "NCT6792D", 33 - "NCT6793D", 34 - "NCT6795D", 35 - "NCT6796D", 36 - "NCT6797D", 37 - "NCT6798D", 38 - "NCT6796D-S/NCT6799D-R", 26 + [nct6106] = "NCT6106D", 27 + [nct6116] = "NCT6116D", 28 + [nct6775] = "NCT6775F", 29 + [nct6776] = "NCT6776D/F", 30 + [nct6779] = "NCT6779D", 31 + [nct6791] = "NCT6791D", 32 + [nct6792] = "NCT6792D", 33 + [nct6793] = "NCT6793D", 34 + [nct6795] = "NCT6795D", 35 + [nct6796] = "NCT6796D", 36 + [nct6797] = "NCT6797D", 37 + [nct6798] = "NCT6798D", 38 + [nct6799] = "NCT6796D-S/NCT6799D-R", 39 39 }; 40 40 41 41 static unsigned short force_id;
+1 -1
drivers/hwmon/nct6775.h
··· 4 4 5 5 #include <linux/types.h> 6 6 7 - enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792, 7 + enum kinds { nct6106 = 1, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792, 8 8 nct6793, nct6795, nct6796, nct6797, nct6798, nct6799 }; 9 9 enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; 10 10
+26 -4
drivers/hwmon/npcm750-pwm-fan.c
··· 46 46 #define NPCM7XX_PWM_CTRL_CH3_EN_BIT BIT(16) 47 47 48 48 /* Define the maximum PWM channel number */ 49 - #define NPCM7XX_PWM_MAX_CHN_NUM 8 49 + #define NPCM7XX_PWM_MAX_CHN_NUM 12 50 50 #define NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE 4 51 - #define NPCM7XX_PWM_MAX_MODULES 2 51 + #define NPCM7XX_PWM_MAX_MODULES 3 52 52 53 53 /* Define the Counter Register, value = 100 for match 100% */ 54 54 #define NPCM7XX_PWM_COUNTER_DEFAULT_NUM 255 ··· 171 171 #define FAN_PREPARE_TO_GET_FIRST_CAPTURE 0x01 172 172 #define FAN_ENOUGH_SAMPLE 0x02 173 173 174 + struct npcm_hwmon_info { 175 + u32 pwm_max_channel; 176 + }; 177 + 174 178 struct npcm7xx_fan_dev { 175 179 u8 fan_st_flg; 176 180 u8 fan_pls_per_rev; ··· 208 204 struct timer_list fan_timer; 209 205 struct npcm7xx_fan_dev fan_dev[NPCM7XX_FAN_MAX_CHN_NUM]; 210 206 struct npcm7xx_cooling_device *cdev[NPCM7XX_PWM_MAX_CHN_NUM]; 207 + const struct npcm_hwmon_info *info; 211 208 u8 fan_select; 212 209 }; 213 210 ··· 547 542 { 548 543 const struct npcm7xx_pwm_fan_data *data = _data; 549 544 550 - if (!data->pwm_present[channel]) 545 + if (!data->pwm_present[channel] || channel >= data->info->pwm_max_channel) 551 546 return 0; 552 547 553 548 switch (attr) { ··· 643 638 HWMON_PWM_INPUT, 644 639 HWMON_PWM_INPUT, 645 640 HWMON_PWM_INPUT, 641 + HWMON_PWM_INPUT, 642 + HWMON_PWM_INPUT, 643 + HWMON_PWM_INPUT, 644 + HWMON_PWM_INPUT, 646 645 HWMON_PWM_INPUT), 647 646 HWMON_CHANNEL_INFO(fan, 648 647 HWMON_F_INPUT, ··· 677 668 static const struct hwmon_chip_info npcm7xx_chip_info = { 678 669 .ops = &npcm7xx_hwmon_ops, 679 670 .info = npcm7xx_info, 671 + }; 672 + 673 + static const struct npcm_hwmon_info npxm7xx_hwmon_info = { 674 + .pwm_max_channel = 8, 675 + }; 676 + 677 + static const struct npcm_hwmon_info npxm8xx_hwmon_info = { 678 + .pwm_max_channel = 12, 680 679 }; 681 680 682 681 static u32 npcm7xx_pwm_init(struct npcm7xx_pwm_fan_data *data) ··· 942 925 if (!data) 943 926 return -ENOMEM; 944 927 928 + data->info = device_get_match_data(dev); 929 + if (!data->info) 930 + return -EINVAL; 931 + 945 932 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); 946 933 if (!res) { 947 934 dev_err(dev, "pwm resource not found\n"); ··· 1038 1017 } 1039 1018 1040 1019 static const struct of_device_id of_pwm_fan_match_table[] = { 1041 - { .compatible = "nuvoton,npcm750-pwm-fan", }, 1020 + { .compatible = "nuvoton,npcm750-pwm-fan", .data = &npxm7xx_hwmon_info}, 1021 + { .compatible = "nuvoton,npcm845-pwm-fan", .data = &npxm8xx_hwmon_info}, 1042 1022 {}, 1043 1023 }; 1044 1024 MODULE_DEVICE_TABLE(of, of_pwm_fan_match_table);
+5 -1
drivers/hwmon/pc87360.c
··· 323 323 } 324 324 325 325 /* Voltages */ 326 - for (i = 0; i < data->innr; i++) { 326 + /* 327 + * The min() below does not have any practical meaning and is 328 + * only needed to silence a warning observed with gcc 12+. 329 + */ 330 + for (i = 0; i < min(data->innr, ARRAY_SIZE(data->in)); i++) { 327 331 data->in_status[i] = pc87360_read_value(data, LD_IN, i, 328 332 PC87365_REG_IN_STATUS); 329 333 /* Clear bits */
+1 -1
drivers/hwmon/peci/dimmtemp.c
··· 47 47 #define GET_TEMP_MAX(x) (((x) & DIMM_TEMP_MAX) >> 8) 48 48 #define GET_TEMP_CRIT(x) (((x) & DIMM_TEMP_CRIT) >> 16) 49 49 50 - #define NO_DIMM_RETRY_COUNT_MAX 5 50 + #define NO_DIMM_RETRY_COUNT_MAX 120 51 51 52 52 struct peci_dimmtemp; 53 53
+28
drivers/hwmon/pmbus/Kconfig
··· 227 227 This driver can also be built as a module. If so, the module will 228 228 be called ltc3815. 229 229 230 + config SENSORS_LTC4286 231 + bool "Analog Devices LTC4286" 232 + help 233 + LTC4286 is an integrated solution for hot swap applications that 234 + allows a board to be safely inserted and removed from a live 235 + backplane. 236 + This chip could be used to monitor voltage, current, ...etc. 237 + If you say yes here you get hardware monitoring support for Analog 238 + Devices LTC4286. 239 + 230 240 config SENSORS_MAX15301 231 241 tristate "Maxim MAX15301" 232 242 help ··· 309 299 This driver can also be built as a module. If so, the module will 310 300 be called max8688. 311 301 302 + config SENSORS_MP2856 303 + tristate "MPS MP2856" 304 + help 305 + If you say yes here you get hardware monitoring support for MPS 306 + MP2856 MP2857 Dual Loop Digital Multi-Phase Controller. 307 + 308 + This driver can also be built as a module. If so, the module will 309 + be called mp2856. 310 + 312 311 config SENSORS_MP2888 313 312 tristate "MPS MP2888" 314 313 help ··· 351 332 352 333 This driver can also be built as a module. If so, the module will 353 334 be called mp5023. 335 + 336 + config SENSORS_MP5990 337 + tristate "MPS MP5990" 338 + help 339 + If you say yes here you get hardware monitoring support for MPS 340 + MP5990. 341 + 342 + This driver can also be built as a module. If so, the module will 343 + be called mp5990. 354 344 355 345 config SENSORS_MPQ7932_REGULATOR 356 346 bool "Regulator support for MPQ7932"
+3
drivers/hwmon/pmbus/Makefile
··· 24 24 obj-$(CONFIG_SENSORS_LT7182S) += lt7182s.o 25 25 obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o 26 26 obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o 27 + obj-$(CONFIG_SENSORS_LTC4286) += ltc4286.o 27 28 obj-$(CONFIG_SENSORS_MAX15301) += max15301.o 28 29 obj-$(CONFIG_SENSORS_MAX16064) += max16064.o 29 30 obj-$(CONFIG_SENSORS_MAX16601) += max16601.o ··· 33 32 obj-$(CONFIG_SENSORS_MAX31785) += max31785.o 34 33 obj-$(CONFIG_SENSORS_MAX34440) += max34440.o 35 34 obj-$(CONFIG_SENSORS_MAX8688) += max8688.o 35 + obj-$(CONFIG_SENSORS_MP2856) += mp2856.o 36 36 obj-$(CONFIG_SENSORS_MP2888) += mp2888.o 37 37 obj-$(CONFIG_SENSORS_MP2975) += mp2975.o 38 38 obj-$(CONFIG_SENSORS_MP5023) += mp5023.o 39 + obj-$(CONFIG_SENSORS_MP5990) += mp5990.o 39 40 obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o 40 41 obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o 41 42 obj-$(CONFIG_SENSORS_PM6764TR) += pm6764tr.o
+3 -11
drivers/hwmon/pmbus/lm25066.c
··· 14 14 #include <linux/slab.h> 15 15 #include <linux/i2c.h> 16 16 #include <linux/log2.h> 17 - #include <linux/of_device.h> 17 + #include <linux/of.h> 18 18 #include "pmbus.h" 19 19 20 - enum chips { lm25056, lm25066, lm5064, lm5066, lm5066i }; 20 + enum chips { lm25056 = 1, lm25066, lm5064, lm5066, lm5066i }; 21 21 22 22 #define LM25066_READ_VAUX 0xd0 23 23 #define LM25066_MFR_READ_IIN 0xd1 ··· 468 468 struct lm25066_data *data; 469 469 struct pmbus_driver_info *info; 470 470 const struct __coeff *coeff; 471 - const struct of_device_id *of_id; 472 - const struct i2c_device_id *i2c_id; 473 471 474 472 if (!i2c_check_functionality(client->adapter, 475 473 I2C_FUNC_SMBUS_READ_BYTE_DATA)) ··· 482 484 if (config < 0) 483 485 return config; 484 486 485 - i2c_id = i2c_match_id(lm25066_id, client); 487 + data->id = (enum chips)(unsigned long)i2c_get_match_data(client); 486 488 487 - of_id = of_match_device(lm25066_of_match, &client->dev); 488 - if (of_id && (unsigned long)of_id->data != i2c_id->driver_data) 489 - dev_notice(&client->dev, "Device mismatch: %s in device tree, %s detected\n", 490 - of_id->name, i2c_id->name); 491 - 492 - data->id = i2c_id->driver_data; 493 489 info = &data->info; 494 490 495 491 info->pages = 1;
+175
drivers/hwmon/pmbus/ltc4286.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + #include <linux/err.h> 4 + #include <linux/i2c.h> 5 + #include <linux/init.h> 6 + #include <linux/kernel.h> 7 + #include <linux/module.h> 8 + #include <linux/pmbus.h> 9 + #include "pmbus.h" 10 + 11 + /* LTC4286 register */ 12 + #define LTC4286_MFR_CONFIG1 0xF2 13 + 14 + /* LTC4286 configuration */ 15 + #define VRANGE_SELECT_BIT BIT(1) 16 + 17 + #define LTC4286_MFR_ID_SIZE 3 18 + 19 + /* 20 + * Initialize the MBR as default settings which is referred to LTC4286 datasheet 21 + * (March 22, 2022 version) table 3 page 16 22 + */ 23 + static struct pmbus_driver_info ltc4286_info = { 24 + .pages = 1, 25 + .format[PSC_VOLTAGE_IN] = direct, 26 + .format[PSC_VOLTAGE_OUT] = direct, 27 + .format[PSC_CURRENT_OUT] = direct, 28 + .format[PSC_POWER] = direct, 29 + .format[PSC_TEMPERATURE] = direct, 30 + .m[PSC_VOLTAGE_IN] = 32, 31 + .b[PSC_VOLTAGE_IN] = 0, 32 + .R[PSC_VOLTAGE_IN] = 1, 33 + .m[PSC_VOLTAGE_OUT] = 32, 34 + .b[PSC_VOLTAGE_OUT] = 0, 35 + .R[PSC_VOLTAGE_OUT] = 1, 36 + .m[PSC_CURRENT_OUT] = 1024, 37 + .b[PSC_CURRENT_OUT] = 0, 38 + /* 39 + * The rsense value used in MBR formula in LTC4286 datasheet should be ohm unit. 40 + * However, the rsense value that user input is micro ohm. 41 + * Thus, the MBR setting which involves rsense should be shifted by 6 digits. 42 + */ 43 + .R[PSC_CURRENT_OUT] = 3 - 6, 44 + .m[PSC_POWER] = 1, 45 + .b[PSC_POWER] = 0, 46 + /* 47 + * The rsense value used in MBR formula in LTC4286 datasheet should be ohm unit. 48 + * However, the rsense value that user input is micro ohm. 49 + * Thus, the MBR setting which involves rsense should be shifted by 6 digits. 50 + */ 51 + .R[PSC_POWER] = 4 - 6, 52 + .m[PSC_TEMPERATURE] = 1, 53 + .b[PSC_TEMPERATURE] = 273, 54 + .R[PSC_TEMPERATURE] = 0, 55 + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | 56 + PMBUS_HAVE_PIN | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_VOUT | 57 + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_TEMP, 58 + }; 59 + 60 + static const struct i2c_device_id ltc4286_id[] = { 61 + { "ltc4286", 0 }, 62 + { "ltc4287", 1 }, 63 + {} 64 + }; 65 + MODULE_DEVICE_TABLE(i2c, ltc4286_id); 66 + 67 + static int ltc4286_probe(struct i2c_client *client) 68 + { 69 + int ret; 70 + const struct i2c_device_id *mid; 71 + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; 72 + struct pmbus_driver_info *info; 73 + u32 rsense; 74 + int vrange_nval, vrange_oval; 75 + 76 + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, block_buffer); 77 + if (ret < 0) { 78 + return dev_err_probe(&client->dev, ret, 79 + "Failed to read manufacturer id\n"); 80 + } 81 + 82 + /* 83 + * Refer to ltc4286 datasheet page 20 84 + * the manufacturer id is LTC 85 + */ 86 + if (ret != LTC4286_MFR_ID_SIZE || 87 + strncmp(block_buffer, "LTC", LTC4286_MFR_ID_SIZE)) { 88 + return dev_err_probe(&client->dev, -ENODEV, 89 + "Manufacturer id mismatch\n"); 90 + } 91 + 92 + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, block_buffer); 93 + if (ret < 0) { 94 + return dev_err_probe(&client->dev, ret, 95 + "Failed to read manufacturer model\n"); 96 + } 97 + 98 + for (mid = ltc4286_id; mid->name[0]; mid++) { 99 + if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) 100 + break; 101 + } 102 + if (!mid->name[0]) 103 + return dev_err_probe(&client->dev, -ENODEV, 104 + "Unsupported device\n"); 105 + 106 + if (of_property_read_u32(client->dev.of_node, 107 + "shunt-resistor-micro-ohms", &rsense)) 108 + rsense = 300; /* 0.3 mOhm if not set via DT */ 109 + 110 + if (rsense == 0) 111 + return -EINVAL; 112 + 113 + /* Check for the latter MBR value won't overflow */ 114 + if (rsense > (INT_MAX / 1024)) 115 + return -EINVAL; 116 + 117 + info = devm_kmemdup(&client->dev, &ltc4286_info, sizeof(*info), 118 + GFP_KERNEL); 119 + if (!info) 120 + return -ENOMEM; 121 + 122 + /* Check MFR1 CONFIG register bit 1 VRANGE_SELECT before driver loading */ 123 + vrange_oval = i2c_smbus_read_word_data(client, LTC4286_MFR_CONFIG1); 124 + if (vrange_oval < 0) 125 + return dev_err_probe(&client->dev, vrange_oval, 126 + "Failed to read manufacturer configuration one\n"); 127 + vrange_nval = vrange_oval; 128 + 129 + if (device_property_read_bool(&client->dev, "adi,vrange-low-enable")) { 130 + vrange_nval &= 131 + ~VRANGE_SELECT_BIT; /* VRANGE_SELECT = 0, 25.6 volts */ 132 + 133 + info->m[PSC_VOLTAGE_IN] = 128; 134 + info->m[PSC_VOLTAGE_OUT] = 128; 135 + info->m[PSC_POWER] = 4 * rsense; 136 + } else { 137 + vrange_nval |= 138 + VRANGE_SELECT_BIT; /* VRANGE_SELECT = 1, 102.4 volts */ 139 + 140 + info->m[PSC_POWER] = rsense; 141 + } 142 + if (vrange_nval != vrange_oval) { 143 + /* Set MFR1 CONFIG register bit 1 VRANGE_SELECT */ 144 + ret = i2c_smbus_write_word_data(client, LTC4286_MFR_CONFIG1, 145 + vrange_nval); 146 + if (ret < 0) 147 + return dev_err_probe(&client->dev, ret, 148 + "Failed to set vrange\n"); 149 + } 150 + 151 + info->m[PSC_CURRENT_OUT] = 1024 * rsense; 152 + 153 + return pmbus_do_probe(client, info); 154 + } 155 + 156 + static const struct of_device_id ltc4286_of_match[] = { 157 + { .compatible = "lltc,ltc4286" }, 158 + { .compatible = "lltc,ltc4287" }, 159 + {} 160 + }; 161 + 162 + static struct i2c_driver ltc4286_driver = { 163 + .driver = { 164 + .name = "ltc4286", 165 + .of_match_table = ltc4286_of_match, 166 + }, 167 + .probe = ltc4286_probe, 168 + .id_table = ltc4286_id, 169 + }; 170 + 171 + module_i2c_driver(ltc4286_driver); 172 + 173 + MODULE_AUTHOR("Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>"); 174 + MODULE_DESCRIPTION("PMBUS driver for LTC4286 and compatibles"); 175 + MODULE_LICENSE("GPL");
+466
drivers/hwmon/pmbus/mp2856.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Hardware monitoring driver for MPS2856/2857 4 + * Monolithic Power Systems VR Controllers 5 + * 6 + * Copyright (C) 2023 Quanta Computer lnc. 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/pmbus.h> 15 + #include "pmbus.h" 16 + 17 + /* Vendor specific registers. */ 18 + #define MP2856_MFR_VR_MULTI_CONFIG_R1 0x0d 19 + #define MP2856_MFR_VR_MULTI_CONFIG_R2 0x1d 20 + 21 + #define MP2856_MUL1_BOOT_SR_R2 0x10 22 + #define MP2856_VR_ACTIVE BIT(15) 23 + 24 + #define MP2856_MFR_VR_CONFIG2 0x5e 25 + #define MP2856_VOUT_MODE BIT(11) 26 + 27 + #define MP2856_MFR_VR_CONFIG1 0x68 28 + #define MP2856_DRMOS_KCS GENMASK(13, 12) 29 + 30 + #define MP2856_MFR_READ_CS1_2_R1 0x82 31 + #define MP2856_MFR_READ_CS3_4_R1 0x83 32 + #define MP2856_MFR_READ_CS5_6_R1 0x84 33 + #define MP2856_MFR_READ_CS7_8_R1 0x85 34 + #define MP2856_MFR_READ_CS9_10_R1 0x86 35 + #define MP2856_MFR_READ_CS11_12_R1 0x87 36 + 37 + #define MP2856_MFR_READ_CS1_2_R2 0x85 38 + #define MP2856_MFR_READ_CS3_4_R2 0x86 39 + #define MP2856_MFR_READ_CS5_6_R2 0x87 40 + 41 + #define MP2856_MAX_PHASE_RAIL1 8 42 + #define MP2856_MAX_PHASE_RAIL2 4 43 + 44 + #define MP2857_MAX_PHASE_RAIL1 12 45 + #define MP2857_MAX_PHASE_RAIL2 4 46 + 47 + #define MP2856_PAGE_NUM 2 48 + 49 + enum chips { mp2856 = 1, mp2857 }; 50 + 51 + static const int mp2856_max_phases[][MP2856_PAGE_NUM] = { 52 + [mp2856] = { MP2856_MAX_PHASE_RAIL1, MP2856_MAX_PHASE_RAIL2 }, 53 + [mp2857] = { MP2857_MAX_PHASE_RAIL1, MP2857_MAX_PHASE_RAIL2 }, 54 + }; 55 + 56 + static const struct i2c_device_id mp2856_id[] = { 57 + {"mp2856", mp2856}, 58 + {"mp2857", mp2857}, 59 + {} 60 + }; 61 + 62 + MODULE_DEVICE_TABLE(i2c, mp2856_id); 63 + 64 + struct mp2856_data { 65 + struct pmbus_driver_info info; 66 + int vout_format[MP2856_PAGE_NUM]; 67 + int curr_sense_gain[MP2856_PAGE_NUM]; 68 + int max_phases[MP2856_PAGE_NUM]; 69 + enum chips chip_id; 70 + }; 71 + 72 + #define to_mp2856_data(x) container_of(x, struct mp2856_data, info) 73 + 74 + #define MAX_LIN_MANTISSA (1023 * 1000) 75 + #define MIN_LIN_MANTISSA (511 * 1000) 76 + 77 + static u16 val2linear11(s64 val) 78 + { 79 + s16 exponent = 0, mantissa; 80 + bool negative = false; 81 + 82 + if (val == 0) 83 + return 0; 84 + 85 + if (val < 0) { 86 + negative = true; 87 + val = -val; 88 + } 89 + 90 + /* Reduce large mantissa until it fits into 10 bit */ 91 + while (val >= MAX_LIN_MANTISSA && exponent < 15) { 92 + exponent++; 93 + val >>= 1; 94 + } 95 + /* Increase small mantissa to improve precision */ 96 + while (val < MIN_LIN_MANTISSA && exponent > -15) { 97 + exponent--; 98 + val <<= 1; 99 + } 100 + 101 + /* Convert mantissa from milli-units to units */ 102 + mantissa = clamp_val(DIV_ROUND_CLOSEST_ULL(val, 1000), 0, 0x3ff); 103 + 104 + /* restore sign */ 105 + if (negative) 106 + mantissa = -mantissa; 107 + 108 + /* Convert to 5 bit exponent, 11 bit mantissa */ 109 + return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); 110 + } 111 + 112 + static int 113 + mp2856_read_word_helper(struct i2c_client *client, int page, int phase, u8 reg, 114 + u16 mask) 115 + { 116 + int ret = pmbus_read_word_data(client, page, phase, reg); 117 + 118 + return (ret > 0) ? ret & mask : ret; 119 + } 120 + 121 + static int 122 + mp2856_read_vout(struct i2c_client *client, struct mp2856_data *data, int page, 123 + int phase, u8 reg) 124 + { 125 + int ret; 126 + 127 + ret = mp2856_read_word_helper(client, page, phase, reg, 128 + GENMASK(9, 0)); 129 + if (ret < 0) 130 + return ret; 131 + 132 + /* convert vout result to direct format */ 133 + ret = (data->vout_format[page] == vid) ? 134 + ((ret + 49) * 5) : ((ret * 1000) >> 8); 135 + 136 + return ret; 137 + } 138 + 139 + static int 140 + mp2856_read_phase(struct i2c_client *client, struct mp2856_data *data, 141 + int page, int phase, u8 reg) 142 + { 143 + int ret; 144 + int val; 145 + 146 + ret = pmbus_read_word_data(client, page, phase, reg); 147 + if (ret < 0) 148 + return ret; 149 + 150 + if (!((phase + 1) % MP2856_PAGE_NUM)) 151 + ret >>= 8; 152 + ret &= 0xff; 153 + 154 + /* 155 + * Output value is calculated as: (READ_CSx * 12.5mV - 1.23V) / (Kcs * Rcs) 156 + */ 157 + val = (ret * 125) - 12300; 158 + 159 + return val2linear11(val); 160 + } 161 + 162 + static int 163 + mp2856_read_phases(struct i2c_client *client, struct mp2856_data *data, 164 + int page, int phase) 165 + { 166 + int ret; 167 + 168 + if (page == 0) { 169 + switch (phase) { 170 + case 0 ... 1: 171 + ret = mp2856_read_phase(client, data, page, phase, 172 + MP2856_MFR_READ_CS1_2_R1); 173 + break; 174 + case 2 ... 3: 175 + ret = mp2856_read_phase(client, data, page, phase, 176 + MP2856_MFR_READ_CS3_4_R1); 177 + break; 178 + case 4 ... 5: 179 + ret = mp2856_read_phase(client, data, page, phase, 180 + MP2856_MFR_READ_CS5_6_R1); 181 + break; 182 + case 6 ... 7: 183 + ret = mp2856_read_phase(client, data, page, phase, 184 + MP2856_MFR_READ_CS7_8_R1); 185 + break; 186 + default: 187 + return -ENODATA; 188 + } 189 + } else { 190 + switch (phase) { 191 + case 0 ... 1: 192 + ret = mp2856_read_phase(client, data, page, phase, 193 + MP2856_MFR_READ_CS1_2_R2); 194 + break; 195 + case 2 ... 3: 196 + ret = mp2856_read_phase(client, data, page, phase, 197 + MP2856_MFR_READ_CS1_2_R2); 198 + break; 199 + default: 200 + return -ENODATA; 201 + } 202 + } 203 + return ret; 204 + } 205 + 206 + static int 207 + mp2856_read_word_data(struct i2c_client *client, int page, 208 + int phase, int reg) 209 + { 210 + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 211 + struct mp2856_data *data = to_mp2856_data(info); 212 + int ret; 213 + 214 + switch (reg) { 215 + case PMBUS_READ_VOUT: 216 + ret = mp2856_read_vout(client, data, page, phase, reg); 217 + break; 218 + case PMBUS_READ_IOUT: 219 + if (phase != 0xff) 220 + ret = mp2856_read_phases(client, data, page, phase); 221 + else 222 + ret = pmbus_read_word_data(client, page, phase, reg); 223 + break; 224 + default: 225 + return -ENODATA; 226 + } 227 + 228 + return ret; 229 + } 230 + 231 + static int 232 + mp2856_read_byte_data(struct i2c_client *client, int page, int reg) 233 + { 234 + switch (reg) { 235 + case PMBUS_VOUT_MODE: 236 + /* Enforce VOUT direct format. */ 237 + return PB_VOUT_MODE_DIRECT; 238 + default: 239 + return -ENODATA; 240 + } 241 + } 242 + 243 + static int 244 + mp2856_identify_multiphase(struct i2c_client *client, u8 reg, u8 max_phase, 245 + u16 mask) 246 + { 247 + int ret; 248 + 249 + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2); 250 + if (ret < 0) 251 + return ret; 252 + 253 + ret = i2c_smbus_read_word_data(client, reg); 254 + if (ret < 0) 255 + return ret; 256 + 257 + ret &= mask; 258 + return (ret >= max_phase) ? max_phase : ret; 259 + } 260 + 261 + static int 262 + mp2856_identify_multiphase_rail1(struct i2c_client *client, 263 + struct mp2856_data *data) 264 + { 265 + int ret, i; 266 + 267 + ret = mp2856_identify_multiphase(client, MP2856_MFR_VR_MULTI_CONFIG_R1, 268 + MP2856_MAX_PHASE_RAIL1, GENMASK(3, 0)); 269 + if (ret < 0) 270 + return ret; 271 + 272 + data->info.phases[0] = (ret > data->max_phases[0]) ? 273 + data->max_phases[0] : ret; 274 + 275 + for (i = 0 ; i < data->info.phases[0]; i++) 276 + data->info.pfunc[i] |= PMBUS_HAVE_IOUT; 277 + 278 + return 0; 279 + } 280 + 281 + static int 282 + mp2856_identify_multiphase_rail2(struct i2c_client *client, 283 + struct mp2856_data *data) 284 + { 285 + int ret, i; 286 + 287 + ret = mp2856_identify_multiphase(client, MP2856_MFR_VR_MULTI_CONFIG_R2, 288 + MP2856_MAX_PHASE_RAIL2, GENMASK(2, 0)); 289 + if (ret < 0) 290 + return ret; 291 + 292 + data->info.phases[1] = (ret > data->max_phases[1]) ? 293 + data->max_phases[1] : ret; 294 + 295 + for (i = 0 ; i < data->info.phases[0]; i++) 296 + data->info.pfunc[i] |= PMBUS_HAVE_IOUT; 297 + 298 + return 0; 299 + } 300 + 301 + static int 302 + mp2856_current_sense_gain_get(struct i2c_client *client, 303 + struct mp2856_data *data) 304 + { 305 + int i, ret; 306 + 307 + /* 308 + * Obtain DrMOS current sense gain of power stage from the register 309 + * MP2856_MFR_VR_CONFIG1, bits 13-12. The value is selected as below: 310 + * 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. Other 311 + * values are invalid. 312 + */ 313 + for (i = 0 ; i < data->info.pages; i++) { 314 + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i); 315 + if (ret < 0) 316 + return ret; 317 + ret = i2c_smbus_read_word_data(client, 318 + MP2856_MFR_VR_CONFIG1); 319 + if (ret < 0) 320 + return ret; 321 + 322 + switch ((ret & MP2856_DRMOS_KCS) >> 12) { 323 + case 0: 324 + data->curr_sense_gain[i] = 50; 325 + break; 326 + case 1: 327 + data->curr_sense_gain[i] = 85; 328 + break; 329 + case 2: 330 + data->curr_sense_gain[i] = 97; 331 + break; 332 + default: 333 + data->curr_sense_gain[i] = 100; 334 + break; 335 + } 336 + } 337 + return 0; 338 + } 339 + 340 + static int 341 + mp2856_identify_vout_format(struct i2c_client *client, 342 + struct mp2856_data *data) 343 + { 344 + int i, ret; 345 + 346 + for (i = 0; i < data->info.pages; i++) { 347 + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i); 348 + if (ret < 0) 349 + return ret; 350 + 351 + ret = i2c_smbus_read_word_data(client, MP2856_MFR_VR_CONFIG2); 352 + if (ret < 0) 353 + return ret; 354 + 355 + data->vout_format[i] = (ret & MP2856_VOUT_MODE) ? linear : vid; 356 + } 357 + return 0; 358 + } 359 + 360 + static bool 361 + mp2856_is_rail2_active(struct i2c_client *client) 362 + { 363 + int ret; 364 + 365 + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2); 366 + if (ret < 0) 367 + return true; 368 + 369 + ret = i2c_smbus_read_word_data(client, MP2856_MUL1_BOOT_SR_R2); 370 + if (ret < 0) 371 + return true; 372 + 373 + return (ret & MP2856_VR_ACTIVE) ? true : false; 374 + } 375 + 376 + static struct pmbus_driver_info mp2856_info = { 377 + .pages = MP2856_PAGE_NUM, 378 + .format[PSC_VOLTAGE_IN] = linear, 379 + .format[PSC_VOLTAGE_OUT] = direct, 380 + .format[PSC_TEMPERATURE] = linear, 381 + .format[PSC_CURRENT_IN] = linear, 382 + .format[PSC_CURRENT_OUT] = linear, 383 + .format[PSC_POWER] = linear, 384 + .m[PSC_VOLTAGE_OUT] = 1, 385 + .R[PSC_VOLTAGE_OUT] = 3, 386 + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 387 + PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 388 + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT | 389 + PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, 390 + .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | 391 + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP, 392 + .read_byte_data = mp2856_read_byte_data, 393 + .read_word_data = mp2856_read_word_data, 394 + }; 395 + 396 + static int mp2856_probe(struct i2c_client *client) 397 + { 398 + struct pmbus_driver_info *info; 399 + struct mp2856_data *data; 400 + int ret; 401 + 402 + data = devm_kzalloc(&client->dev, sizeof(struct mp2856_data), 403 + GFP_KERNEL); 404 + if (!data) 405 + return -ENOMEM; 406 + 407 + data->chip_id = (enum chips)(uintptr_t)i2c_get_match_data(client); 408 + 409 + memcpy(data->max_phases, mp2856_max_phases[data->chip_id], 410 + sizeof(data->max_phases)); 411 + 412 + memcpy(&data->info, &mp2856_info, sizeof(*info)); 413 + info = &data->info; 414 + 415 + /* Identify multiphase configuration. */ 416 + ret = mp2856_identify_multiphase_rail1(client, data); 417 + if (ret < 0) 418 + return ret; 419 + 420 + if (mp2856_is_rail2_active(client)) { 421 + ret = mp2856_identify_multiphase_rail2(client, data); 422 + if (ret < 0) 423 + return ret; 424 + } else { 425 + /* rail2 is not active */ 426 + info->pages = 1; 427 + } 428 + 429 + /* Obtain current sense gain of power stage. */ 430 + ret = mp2856_current_sense_gain_get(client, data); 431 + if (ret) 432 + return ret; 433 + 434 + /* Identify vout format. */ 435 + ret = mp2856_identify_vout_format(client, data); 436 + if (ret) 437 + return ret; 438 + 439 + /* set the device to page 0 */ 440 + i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); 441 + 442 + return pmbus_do_probe(client, info); 443 + } 444 + 445 + static const struct of_device_id __maybe_unused mp2856_of_match[] = { 446 + {.compatible = "mps,mp2856", .data = (void *)mp2856}, 447 + {.compatible = "mps,mp2857", .data = (void *)mp2857}, 448 + {} 449 + }; 450 + MODULE_DEVICE_TABLE(of, mp2856_of_match); 451 + 452 + static struct i2c_driver mp2856_driver = { 453 + .driver = { 454 + .name = "mp2856", 455 + .of_match_table = mp2856_of_match, 456 + }, 457 + .probe = mp2856_probe, 458 + .id_table = mp2856_id, 459 + }; 460 + 461 + module_i2c_driver(mp2856_driver); 462 + 463 + MODULE_AUTHOR("Peter Yin <peter.yin@quantatw.com>"); 464 + MODULE_DESCRIPTION("PMBus driver for MPS MP2856/MP2857 device"); 465 + MODULE_LICENSE("GPL"); 466 + MODULE_IMPORT_NS(PMBUS);
+179
drivers/hwmon/pmbus/mp5990.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for MPS MP5990 Hot-Swap Controller 4 + */ 5 + 6 + #include <linux/i2c.h> 7 + #include <linux/module.h> 8 + #include <linux/of_device.h> 9 + #include "pmbus.h" 10 + 11 + #define MP5990_EFUSE_CFG (0xC4) 12 + #define MP5990_VOUT_FORMAT BIT(9) 13 + 14 + struct mp5990_data { 15 + struct pmbus_driver_info info; 16 + u8 vout_mode; 17 + u8 vout_linear_exponent; 18 + }; 19 + 20 + #define to_mp5990_data(x) container_of(x, struct mp5990_data, info) 21 + 22 + static int mp5990_read_byte_data(struct i2c_client *client, int page, int reg) 23 + { 24 + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 25 + struct mp5990_data *data = to_mp5990_data(info); 26 + 27 + switch (reg) { 28 + case PMBUS_VOUT_MODE: 29 + if (data->vout_mode == linear) { 30 + /* 31 + * The VOUT format used by the chip is linear11, 32 + * not linear16. Report that VOUT is in linear mode 33 + * and return exponent value extracted while probing 34 + * the chip. 35 + */ 36 + return data->vout_linear_exponent; 37 + } 38 + 39 + /* 40 + * The datasheet does not support the VOUT command, 41 + * but the device responds with a default value of 0x17. 42 + * In the standard, 0x17 represents linear mode. 43 + * Therefore, we should report that VOUT is in direct 44 + * format when the chip is configured for it. 45 + */ 46 + return PB_VOUT_MODE_DIRECT; 47 + 48 + default: 49 + return -ENODATA; 50 + } 51 + } 52 + 53 + static int mp5990_read_word_data(struct i2c_client *client, int page, 54 + int phase, int reg) 55 + { 56 + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 57 + struct mp5990_data *data = to_mp5990_data(info); 58 + int ret; 59 + s32 mantissa; 60 + 61 + switch (reg) { 62 + case PMBUS_READ_VOUT: 63 + ret = pmbus_read_word_data(client, page, phase, reg); 64 + if (ret < 0) 65 + return ret; 66 + /* 67 + * Because the VOUT format used by the chip is linear11 and not 68 + * linear16, we disregard bits[15:11]. The exponent is reported 69 + * as part of the VOUT_MODE command. 70 + */ 71 + if (data->vout_mode == linear) { 72 + mantissa = ((s16)((ret & 0x7ff) << 5)) >> 5; 73 + ret = mantissa; 74 + } 75 + break; 76 + default: 77 + return -ENODATA; 78 + } 79 + 80 + return ret; 81 + } 82 + 83 + static struct pmbus_driver_info mp5990_info = { 84 + .pages = 1, 85 + .format[PSC_VOLTAGE_IN] = direct, 86 + .format[PSC_VOLTAGE_OUT] = direct, 87 + .format[PSC_CURRENT_OUT] = direct, 88 + .format[PSC_POWER] = direct, 89 + .format[PSC_TEMPERATURE] = direct, 90 + .m[PSC_VOLTAGE_IN] = 32, 91 + .b[PSC_VOLTAGE_IN] = 0, 92 + .R[PSC_VOLTAGE_IN] = 0, 93 + .m[PSC_VOLTAGE_OUT] = 32, 94 + .b[PSC_VOLTAGE_OUT] = 0, 95 + .R[PSC_VOLTAGE_OUT] = 0, 96 + .m[PSC_CURRENT_OUT] = 16, 97 + .b[PSC_CURRENT_OUT] = 0, 98 + .R[PSC_CURRENT_OUT] = 0, 99 + .m[PSC_POWER] = 1, 100 + .b[PSC_POWER] = 0, 101 + .R[PSC_POWER] = 0, 102 + .m[PSC_TEMPERATURE] = 1, 103 + .b[PSC_TEMPERATURE] = 0, 104 + .R[PSC_TEMPERATURE] = 0, 105 + .func[0] = 106 + PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_PIN | 107 + PMBUS_HAVE_TEMP | PMBUS_HAVE_IOUT | 108 + PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP, 109 + .read_byte_data = mp5990_read_byte_data, 110 + .read_word_data = mp5990_read_word_data, 111 + }; 112 + 113 + static int mp5990_probe(struct i2c_client *client) 114 + { 115 + struct pmbus_driver_info *info; 116 + struct mp5990_data *data; 117 + int ret; 118 + 119 + data = devm_kzalloc(&client->dev, sizeof(struct mp5990_data), 120 + GFP_KERNEL); 121 + if (!data) 122 + return -ENOMEM; 123 + 124 + memcpy(&data->info, &mp5990_info, sizeof(*info)); 125 + info = &data->info; 126 + 127 + /* Read Vout Config */ 128 + ret = i2c_smbus_read_word_data(client, MP5990_EFUSE_CFG); 129 + if (ret < 0) { 130 + dev_err(&client->dev, "Can't get vout mode."); 131 + return ret; 132 + } 133 + 134 + /* 135 + * EFUSE_CFG (0xC4) bit9=1 is linear mode, bit=0 is direct mode. 136 + */ 137 + if (ret & MP5990_VOUT_FORMAT) { 138 + data->vout_mode = linear; 139 + data->info.format[PSC_VOLTAGE_IN] = linear; 140 + data->info.format[PSC_VOLTAGE_OUT] = linear; 141 + data->info.format[PSC_CURRENT_OUT] = linear; 142 + data->info.format[PSC_POWER] = linear; 143 + ret = i2c_smbus_read_word_data(client, PMBUS_READ_VOUT); 144 + if (ret < 0) { 145 + dev_err(&client->dev, "Can't get vout exponent."); 146 + return ret; 147 + } 148 + data->vout_linear_exponent = (u8)((ret >> 11) & 0x1f); 149 + } else { 150 + data->vout_mode = direct; 151 + } 152 + return pmbus_do_probe(client, info); 153 + } 154 + 155 + static const struct of_device_id mp5990_of_match[] = { 156 + { .compatible = "mps,mp5990" }, 157 + {} 158 + }; 159 + 160 + static const struct i2c_device_id mp5990_id[] = { 161 + {"mp5990", 0}, 162 + { } 163 + }; 164 + MODULE_DEVICE_TABLE(i2c, mp5990_id); 165 + 166 + static struct i2c_driver mp5990_driver = { 167 + .driver = { 168 + .name = "mp5990", 169 + .of_match_table = mp5990_of_match, 170 + }, 171 + .probe = mp5990_probe, 172 + .id_table = mp5990_id, 173 + }; 174 + module_i2c_driver(mp5990_driver); 175 + 176 + MODULE_AUTHOR("Peter Yin <peter.yin@quantatw.com>"); 177 + MODULE_DESCRIPTION("PMBus driver for MP5990 HSC"); 178 + MODULE_LICENSE("GPL"); 179 + MODULE_IMPORT_NS(PMBUS);
+2 -1
drivers/hwmon/sht4x.c
··· 49 49 * struct sht4x_data - All the data required to operate an SHT4X chip 50 50 * @client: the i2c client associated with the SHT4X 51 51 * @lock: a mutex that is used to prevent parallel access to the i2c client 52 + * @valid: validity of fields below 52 53 * @update_interval: the minimum poll interval 53 54 * @last_updated: the previous time that the SHT4X was polled 54 55 * @temperature: the latest temperature value received from the SHT4X ··· 67 66 68 67 /** 69 68 * sht4x_read_values() - read and parse the raw data from the SHT4X 70 - * @sht4x_data: the struct sht4x_data to use for the lock 69 + * @data: the struct sht4x_data to use for the lock 71 70 * Return: 0 if successful, -ERRNO if not 72 71 */ 73 72 static int sht4x_read_values(struct sht4x_data *data)
+27 -40
drivers/hwmon/smsc47m1.c
··· 33 33 module_param(force_id, ushort, 0); 34 34 MODULE_PARM_DESC(force_id, "Override the detected device ID"); 35 35 36 - static struct platform_device *pdev; 36 + static struct platform_device *smsc47m1_pdev; 37 37 38 38 #define DRVNAME "smsc47m1" 39 39 enum chips { smsc47m1, smsc47m2 }; ··· 840 840 return err; 841 841 } 842 842 843 - static int __exit smsc47m1_remove(struct platform_device *pdev) 843 + static void __exit smsc47m1_remove(struct platform_device *pdev) 844 844 { 845 845 struct smsc47m1_data *data = platform_get_drvdata(pdev); 846 846 847 847 hwmon_device_unregister(data->hwmon_dev); 848 848 smsc47m1_remove_files(&pdev->dev); 849 - 850 - return 0; 851 849 } 852 850 853 - static struct platform_driver smsc47m1_driver = { 851 + /* 852 + * smsc47m1_remove() lives in .exit.text. For drivers registered via 853 + * module_platform_driver_probe() this ok because they cannot get unbound at 854 + * runtime. The driver needs to be marked with __refdata, otherwise modpost 855 + * triggers a section mismatch warning. 856 + */ 857 + static struct platform_driver smsc47m1_driver __refdata = { 854 858 .driver = { 855 859 .name = DRVNAME, 856 860 }, 857 - .remove = __exit_p(smsc47m1_remove), 861 + .remove_new = __exit_p(smsc47m1_remove), 858 862 }; 859 863 860 864 static int __init smsc47m1_device_add(unsigned short address, 861 865 const struct smsc47m1_sio_data *sio_data) 862 866 { 863 - struct resource res = { 867 + const struct resource res = { 864 868 .start = address, 865 869 .end = address + SMSC_EXTENT - 1, 866 870 .name = DRVNAME, 867 871 .flags = IORESOURCE_IO, 868 872 }; 873 + const struct platform_device_info pdevinfo = { 874 + .name = DRVNAME, 875 + .id = address, 876 + .res = &res, 877 + .num_res = 1, 878 + .data = sio_data, 879 + .size_data = sizeof(struct smsc47m1_sio_data), 880 + }; 869 881 int err; 870 882 871 883 err = smsc47m1_handle_resources(address, sio_data->type, CHECK, NULL); 872 884 if (err) 873 - goto exit; 885 + return err; 874 886 875 - pdev = platform_device_alloc(DRVNAME, address); 876 - if (!pdev) { 877 - err = -ENOMEM; 887 + smsc47m1_pdev = platform_device_register_full(&pdevinfo); 888 + if (IS_ERR(smsc47m1_pdev)) { 878 889 pr_err("Device allocation failed\n"); 879 - goto exit; 880 - } 881 - 882 - err = platform_device_add_resources(pdev, &res, 1); 883 - if (err) { 884 - pr_err("Device resource addition failed (%d)\n", err); 885 - goto exit_device_put; 886 - } 887 - 888 - err = platform_device_add_data(pdev, sio_data, 889 - sizeof(struct smsc47m1_sio_data)); 890 - if (err) { 891 - pr_err("Platform data allocation failed\n"); 892 - goto exit_device_put; 893 - } 894 - 895 - err = platform_device_add(pdev); 896 - if (err) { 897 - pr_err("Device addition failed (%d)\n", err); 898 - goto exit_device_put; 890 + return PTR_ERR(smsc47m1_pdev); 899 891 } 900 892 901 893 return 0; 902 - 903 - exit_device_put: 904 - platform_device_put(pdev); 905 - exit: 906 - return err; 907 894 } 908 895 909 896 static int __init sm_smsc47m1_init(void) ··· 904 917 return err; 905 918 address = err; 906 919 907 - /* Sets global pdev as a side effect */ 920 + /* Sets global smsc47m1_pdev as a side effect */ 908 921 err = smsc47m1_device_add(address, &sio_data); 909 922 if (err) 910 923 return err; ··· 916 929 return 0; 917 930 918 931 exit_device: 919 - platform_device_unregister(pdev); 932 + platform_device_unregister(smsc47m1_pdev); 920 933 smsc47m1_restore(&sio_data); 921 934 return err; 922 935 } ··· 924 937 static void __exit sm_smsc47m1_exit(void) 925 938 { 926 939 platform_driver_unregister(&smsc47m1_driver); 927 - smsc47m1_restore(dev_get_platdata(&pdev->dev)); 928 - platform_device_unregister(pdev); 940 + smsc47m1_restore(dev_get_platdata(&smsc47m1_pdev->dev)); 941 + platform_device_unregister(smsc47m1_pdev); 929 942 } 930 943 931 944 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
+31 -33
drivers/hwmon/tmp513.c
··· 19 19 * the Free Software Foundation; version 2 of the License. 20 20 */ 21 21 22 + #include <linux/bitops.h> 23 + #include <linux/bug.h> 24 + #include <linux/device.h> 22 25 #include <linux/err.h> 23 26 #include <linux/hwmon.h> 24 27 #include <linux/i2c.h> 25 28 #include <linux/init.h> 26 - #include <linux/kernel.h> 29 + #include <linux/math.h> 27 30 #include <linux/module.h> 31 + #include <linux/property.h> 28 32 #include <linux/regmap.h> 29 33 #include <linux/slab.h> 30 - #include <linux/util_macros.h> 34 + #include <linux/types.h> 35 + #include <linux/units.h> 31 36 32 37 // Common register definition 33 38 #define TMP51X_SHUNT_CONFIG 0x00 ··· 102 97 #define TMP51X_REMOTE_TEMP_LIMIT_2_POS 8 103 98 #define TMP513_REMOTE_TEMP_LIMIT_3_POS 7 104 99 105 - #define TMP51X_VBUS_RANGE_32V 32000000 106 - #define TMP51X_VBUS_RANGE_16V 16000000 100 + #define TMP51X_VBUS_RANGE_32V (32 * MICRO) 101 + #define TMP51X_VBUS_RANGE_16V (16 * MICRO) 107 102 108 103 // Max and Min value 109 104 #define MAX_BUS_VOLTAGE_32_LIMIT 32764 ··· 205 200 * on the pga gain setting. 1lsb = 10uV 206 201 */ 207 202 *val = sign_extend32(regval, 17 - tmp51x_get_pga_shift(data)); 208 - *val = DIV_ROUND_CLOSEST(*val * 10000, data->shunt_uohms); 203 + *val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms); 209 204 break; 210 205 case TMP51X_BUS_VOLTAGE_RESULT: 211 206 case TMP51X_BUS_VOLTAGE_H_LIMIT: ··· 221 216 case TMP51X_BUS_CURRENT_RESULT: 222 217 // Current = (ShuntVoltage * CalibrationRegister) / 4096 223 218 *val = sign_extend32(regval, 16) * data->curr_lsb_ua; 224 - *val = DIV_ROUND_CLOSEST(*val, 1000); 219 + *val = DIV_ROUND_CLOSEST(*val, MILLI); 225 220 break; 226 221 case TMP51X_LOCAL_TEMP_RESULT: 227 222 case TMP51X_REMOTE_TEMP_RESULT_1: ··· 261 256 * The user enter current value and we convert it to 262 257 * voltage. 1lsb = 10uV 263 258 */ 264 - val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10000); 259 + val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI); 265 260 max_val = U16_MAX >> tmp51x_get_pga_shift(data); 266 261 regval = clamp_val(val, -max_val, max_val); 267 262 break; ··· 551 546 if (data->shunt_uohms == 0) 552 547 return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, 0); 553 548 554 - max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * 1000 * 1000, 555 - data->shunt_uohms); 549 + max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * MICRO, data->shunt_uohms); 556 550 557 551 /* 558 552 * Calculate the minimal bit resolution for the current and the power. 559 553 * Those values will be used during register interpretation. 560 554 */ 561 - data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * 1000, 32767); 555 + data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * MILLI, 32767); 562 556 data->pwr_lsb_uw = 20 * data->curr_lsb_ua; 563 557 564 - div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms, 565 - 1000 * 1000); 558 + div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms, MICRO); 566 559 567 560 return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, 568 561 DIV_ROUND_CLOSEST(40960, div)); ··· 629 626 } else if (data->vbus_range_uvolt == TMP51X_VBUS_RANGE_16V) { 630 627 data->shunt_config &= ~TMP51X_BUS_VOLTAGE_MASK; 631 628 } else { 632 - dev_err(dev, "ti,bus-range-microvolt is invalid: %u\n", 633 - data->vbus_range_uvolt); 634 - return -EINVAL; 629 + return dev_err_probe(dev, -EINVAL, 630 + "ti,bus-range-microvolt is invalid: %u\n", 631 + data->vbus_range_uvolt); 635 632 } 636 633 return 0; 637 634 } ··· 647 644 } else if (data->pga_gain == 1) { 648 645 data->shunt_config |= CURRENT_SENSE_VOLTAGE_40_MASK; 649 646 } else { 650 - dev_err(dev, "ti,pga-gain is invalid: %u\n", data->pga_gain); 651 - return -EINVAL; 647 + return dev_err_probe(dev, -EINVAL, 648 + "ti,pga-gain is invalid: %u\n", data->pga_gain); 652 649 } 653 650 return 0; 654 651 } ··· 677 674 data->max_channels - 1); 678 675 679 676 // Check if shunt value is compatible with pga-gain 680 - if (data->shunt_uohms > data->pga_gain * 40 * 1000 * 1000) { 681 - dev_err(dev, "shunt-resistor: %u too big for pga_gain: %u\n", 682 - data->shunt_uohms, data->pga_gain); 683 - return -EINVAL; 677 + if (data->shunt_uohms > data->pga_gain * 40 * MICRO) { 678 + return dev_err_probe(dev, -EINVAL, 679 + "shunt-resistor: %u too big for pga_gain: %u\n", 680 + data->shunt_uohms, data->pga_gain); 684 681 } 685 682 686 683 return 0; ··· 720 717 data->max_channels = (uintptr_t)i2c_get_match_data(client); 721 718 722 719 ret = tmp51x_configure(dev, data); 723 - if (ret < 0) { 724 - dev_err(dev, "error configuring the device: %d\n", ret); 725 - return ret; 726 - } 720 + if (ret < 0) 721 + return dev_err_probe(dev, ret, "error configuring the device\n"); 727 722 728 723 data->regmap = devm_regmap_init_i2c(client, &tmp51x_regmap_config); 729 - if (IS_ERR(data->regmap)) { 730 - dev_err(dev, "failed to allocate register map\n"); 731 - return PTR_ERR(data->regmap); 732 - } 724 + if (IS_ERR(data->regmap)) 725 + return dev_err_probe(dev, PTR_ERR(data->regmap), 726 + "failed to allocate register map\n"); 733 727 734 728 ret = tmp51x_init(data); 735 - if (ret < 0) { 736 - dev_err(dev, "error configuring the device: %d\n", ret); 737 - return -ENODEV; 738 - } 729 + if (ret < 0) 730 + return dev_err_probe(dev, ret, "error configuring the device\n"); 739 731 740 732 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 741 733 data,
+1
drivers/platform/x86/wmi.c
··· 92 92 "8A42EA14-4F2A-FD45-6422-0087F7A7E608", /* dell-wmi-ddv */ 93 93 "44FADEB1-B204-40F2-8581-394BBDC1B651", /* intel-wmi-sbl-fw-update */ 94 94 "86CCFD48-205E-4A77-9C48-2021CBEDE341", /* intel-wmi-thunderbolt */ 95 + "F1DDEE52-063C-4784-A11E-8A06684B9B01", /* dell-smm-hwmon */ 95 96 NULL 96 97 }; 97 98