diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-29 14:20:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-29 14:20:45 -0500 |
commit | 47d5cc5be396eca67cc89572957ff16f10fd768e (patch) | |
tree | 1f7cc53be5c3d857a3a1724a8dd773997d20620b | |
parent | 0fc7e74663447682c904fe375bb680b004ddaa14 (diff) | |
parent | 6fbc4232a5ac944531bda397f3644d1cf66bdd13 (diff) |
Merge tag 'hwmon-for-linus-v4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon updates from Guenter Roeck:
- New driver for W83773G
- Fan control support for PMBus drivers
- Improvements and minor fixes in several drivers
* tag 'hwmon-for-linus-v4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (32 commits)
hwmon: (dell-smm) Disable fan support for Dell Vostro 3360
hwmon: (dell-smm) Disable fan support for Dell Inspiron 7720
hwmon: (dell-smm) Enable broken functionality via "force" module param
hwmon: (k10temp) Add temperature offset for Ryzen 1900X
hwmon: (lm75) Fix trailing semicolon
hwmon: (ina2xx) Fix access to uninitialized mutex
hwmon: (pmbus/ir35221) Remove unnecessary scaling
hwmon: (sht3x) wait predefined limits loading complete before access
hwmon: (pmbus/ibm-cffps) Add dependency on LEDS_CLASS
hwmon: (pmbus/cffps) Add led class device for power supply fault led
hwmon: (pmbus) cffps: Add PMBUS_SKIP_STATUS_CHECK
hwmon: (aspeed-pwm-tacho) Deassert reset in probe
dt-bindings: hwmon: aspeed-pwm-tacho: Add reset node
hwmon: (pmbus) cffps: Add debugfs entries
hwmon: (pmbus) Export pmbus device debugfs directory entry
hwmon: (w83773g) Fix fault detection and reporting
hwmon: (hih6130) Fix documentation of struct hih6130
hwmon: (iio_hwmon) Fix documentation of struct iio_hwmon_state
hwmon: (sht15) Fix parameter documentation of sht15_crc8()
hwmon: (sht21) Fix documentation of struct sht21
...
26 files changed, 1408 insertions, 382 deletions
diff --git a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt index 367c8203213b..3ac02988a1a5 100644 --- a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt +++ b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt | |||
@@ -22,8 +22,9 @@ Required properties for pwm-tacho node: | |||
22 | - compatible : should be "aspeed,ast2400-pwm-tacho" for AST2400 and | 22 | - compatible : should be "aspeed,ast2400-pwm-tacho" for AST2400 and |
23 | "aspeed,ast2500-pwm-tacho" for AST2500. | 23 | "aspeed,ast2500-pwm-tacho" for AST2500. |
24 | 24 | ||
25 | - clocks : a fixed clock providing input clock frequency(PWM | 25 | - clocks : phandle to clock provider with the clock number in the second cell |
26 | and Fan Tach clock) | 26 | |
27 | - resets : phandle to reset controller with the reset number in the second cell | ||
27 | 28 | ||
28 | fan subnode format: | 29 | fan subnode format: |
29 | =================== | 30 | =================== |
@@ -48,19 +49,14 @@ Required properties for each child node: | |||
48 | 49 | ||
49 | Examples: | 50 | Examples: |
50 | 51 | ||
51 | pwm_tacho_fixed_clk: fixedclk { | ||
52 | compatible = "fixed-clock"; | ||
53 | #clock-cells = <0>; | ||
54 | clock-frequency = <24000000>; | ||
55 | }; | ||
56 | |||
57 | pwm_tacho: pwmtachocontroller@1e786000 { | 52 | pwm_tacho: pwmtachocontroller@1e786000 { |
58 | #address-cells = <1>; | 53 | #address-cells = <1>; |
59 | #size-cells = <1>; | 54 | #size-cells = <1>; |
60 | #cooling-cells = <2>; | 55 | #cooling-cells = <2>; |
61 | reg = <0x1E786000 0x1000>; | 56 | reg = <0x1E786000 0x1000>; |
62 | compatible = "aspeed,ast2500-pwm-tacho"; | 57 | compatible = "aspeed,ast2500-pwm-tacho"; |
63 | clocks = <&pwm_tacho_fixed_clk>; | 58 | clocks = <&syscon ASPEED_CLK_APB>; |
59 | resets = <&syscon ASPEED_RESET_PWM>; | ||
64 | pinctrl-names = "default"; | 60 | pinctrl-names = "default"; |
65 | pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>; | 61 | pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>; |
66 | 62 | ||
diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066 index 3fa6bf820c88..51b32aa203a8 100644 --- a/Documentation/hwmon/lm25066 +++ b/Documentation/hwmon/lm25066 | |||
@@ -8,11 +8,6 @@ Supported chips: | |||
8 | Datasheets: | 8 | Datasheets: |
9 | http://www.ti.com/lit/gpn/lm25056 | 9 | http://www.ti.com/lit/gpn/lm25056 |
10 | http://www.ti.com/lit/gpn/lm25056a | 10 | http://www.ti.com/lit/gpn/lm25056a |
11 | * TI LM25063 | ||
12 | Prefix: 'lm25063' | ||
13 | Addresses scanned: - | ||
14 | Datasheet: | ||
15 | To be announced | ||
16 | * National Semiconductor LM25066 | 11 | * National Semiconductor LM25066 |
17 | Prefix: 'lm25066' | 12 | Prefix: 'lm25066' |
18 | Addresses scanned: - | 13 | Addresses scanned: - |
@@ -42,7 +37,7 @@ Description | |||
42 | ----------- | 37 | ----------- |
43 | 38 | ||
44 | This driver supports hardware monitoring for National Semiconductor / TI LM25056, | 39 | This driver supports hardware monitoring for National Semiconductor / TI LM25056, |
45 | LM25063, LM25066, LM5064, and LM5066/LM5066I Power Management, Monitoring, | 40 | LM25066, LM5064, and LM5066/LM5066I Power Management, Monitoring, |
46 | Control, and Protection ICs. | 41 | Control, and Protection ICs. |
47 | 42 | ||
48 | The driver is a client driver to the core PMBus driver. Please see | 43 | The driver is a client driver to the core PMBus driver. Please see |
@@ -74,12 +69,8 @@ in1_input Measured input voltage. | |||
74 | in1_average Average measured input voltage. | 69 | in1_average Average measured input voltage. |
75 | in1_min Minimum input voltage. | 70 | in1_min Minimum input voltage. |
76 | in1_max Maximum input voltage. | 71 | in1_max Maximum input voltage. |
77 | in1_crit Critical high input voltage (LM25063 only). | ||
78 | in1_lcrit Critical low input voltage (LM25063 only). | ||
79 | in1_min_alarm Input voltage low alarm. | 72 | in1_min_alarm Input voltage low alarm. |
80 | in1_max_alarm Input voltage high alarm. | 73 | in1_max_alarm Input voltage high alarm. |
81 | in1_lcrit_alarm Input voltage critical low alarm (LM25063 only). | ||
82 | in1_crit_alarm Input voltage critical high alarm. (LM25063 only). | ||
83 | 74 | ||
84 | in2_label "vmon" | 75 | in2_label "vmon" |
85 | in2_input Measured voltage on VAUX pin | 76 | in2_input Measured voltage on VAUX pin |
@@ -94,16 +85,12 @@ in3_input Measured output voltage. | |||
94 | in3_average Average measured output voltage. | 85 | in3_average Average measured output voltage. |
95 | in3_min Minimum output voltage. | 86 | in3_min Minimum output voltage. |
96 | in3_min_alarm Output voltage low alarm. | 87 | in3_min_alarm Output voltage low alarm. |
97 | in3_highest Historical minimum output voltage (LM25063 only). | ||
98 | in3_lowest Historical maximum output voltage (LM25063 only). | ||
99 | 88 | ||
100 | curr1_label "iin" | 89 | curr1_label "iin" |
101 | curr1_input Measured input current. | 90 | curr1_input Measured input current. |
102 | curr1_average Average measured input current. | 91 | curr1_average Average measured input current. |
103 | curr1_max Maximum input current. | 92 | curr1_max Maximum input current. |
104 | curr1_crit Critical input current (LM25063 only). | ||
105 | curr1_max_alarm Input current high alarm. | 93 | curr1_max_alarm Input current high alarm. |
106 | curr1_crit_alarm Input current critical high alarm (LM25063 only). | ||
107 | 94 | ||
108 | power1_label "pin" | 95 | power1_label "pin" |
109 | power1_input Measured input power. | 96 | power1_input Measured input power. |
@@ -113,11 +100,6 @@ power1_alarm Input power alarm | |||
113 | power1_input_highest Historical maximum power. | 100 | power1_input_highest Historical maximum power. |
114 | power1_reset_history Write any value to reset maximum power history. | 101 | power1_reset_history Write any value to reset maximum power history. |
115 | 102 | ||
116 | power2_label "pout". LM25063 only. | ||
117 | power2_input Measured output power. | ||
118 | power2_max Maximum output power limit. | ||
119 | power2_crit Critical output power limit. | ||
120 | |||
121 | temp1_input Measured temperature. | 103 | temp1_input Measured temperature. |
122 | temp1_max Maximum temperature. | 104 | temp1_max Maximum temperature. |
123 | temp1_crit Critical high temperature. | 105 | temp1_crit Critical high temperature. |
diff --git a/Documentation/hwmon/max31785 b/Documentation/hwmon/max31785 index 45fb6093dec2..270c5f865261 100644 --- a/Documentation/hwmon/max31785 +++ b/Documentation/hwmon/max31785 | |||
@@ -17,8 +17,9 @@ management with temperature and remote voltage sensing. Various fan control | |||
17 | features are provided, including PWM frequency control, temperature hysteresis, | 17 | features are provided, including PWM frequency control, temperature hysteresis, |
18 | dual tachometer measurements, and fan health monitoring. | 18 | dual tachometer measurements, and fan health monitoring. |
19 | 19 | ||
20 | For dual rotor fan configuration, the MAX31785 exposes the slowest rotor of the | 20 | For dual-rotor configurations the MAX31785A exposes the second rotor tachometer |
21 | two in the fan[1-4]_input attributes. | 21 | readings in attributes fan[5-8]_input. By contrast the MAX31785 only exposes |
22 | the slowest rotor measurement, and does so in the fan[1-4]_input attributes. | ||
22 | 23 | ||
23 | Usage Notes | 24 | Usage Notes |
24 | ----------- | 25 | ----------- |
@@ -31,7 +32,9 @@ Sysfs attributes | |||
31 | 32 | ||
32 | fan[1-4]_alarm Fan alarm. | 33 | fan[1-4]_alarm Fan alarm. |
33 | fan[1-4]_fault Fan fault. | 34 | fan[1-4]_fault Fan fault. |
34 | fan[1-4]_input Fan RPM. | 35 | fan[1-8]_input Fan RPM. On the MAX31785A, inputs 5-8 correspond to the |
36 | second rotor of fans 1-4 | ||
37 | fan[1-4]_target Fan input target | ||
35 | 38 | ||
36 | in[1-6]_crit Critical maximum output voltage | 39 | in[1-6]_crit Critical maximum output voltage |
37 | in[1-6]_crit_alarm Output voltage critical high alarm | 40 | in[1-6]_crit_alarm Output voltage critical high alarm |
@@ -44,6 +47,12 @@ in[1-6]_max_alarm Output voltage high alarm | |||
44 | in[1-6]_min Minimum output voltage | 47 | in[1-6]_min Minimum output voltage |
45 | in[1-6]_min_alarm Output voltage low alarm | 48 | in[1-6]_min_alarm Output voltage low alarm |
46 | 49 | ||
50 | pwm[1-4] Fan target duty cycle (0..255) | ||
51 | pwm[1-4]_enable 0: Full-speed | ||
52 | 1: Manual PWM control | ||
53 | 2: Automatic PWM (tach-feedback RPM fan-control) | ||
54 | 3: Automatic closed-loop (temp-feedback fan-control) | ||
55 | |||
47 | temp[1-11]_crit Critical high temperature | 56 | temp[1-11]_crit Critical high temperature |
48 | temp[1-11]_crit_alarm Chip temperature critical high alarm | 57 | temp[1-11]_crit_alarm Chip temperature critical high alarm |
49 | temp[1-11]_input Measured temperature | 58 | temp[1-11]_input Measured temperature |
diff --git a/Documentation/hwmon/w83773g b/Documentation/hwmon/w83773g new file mode 100644 index 000000000000..4cc6c0b8257f --- /dev/null +++ b/Documentation/hwmon/w83773g | |||
@@ -0,0 +1,33 @@ | |||
1 | Kernel driver w83773g | ||
2 | ==================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Nuvoton W83773G | ||
6 | Prefix: 'w83773g' | ||
7 | Addresses scanned: I2C 0x4c and 0x4d | ||
8 | Datasheet: https://www.nuvoton.com/resource-files/W83773G_SG_DatasheetV1_2.pdf | ||
9 | |||
10 | Authors: | ||
11 | Lei YU <mine260309@gmail.com> | ||
12 | |||
13 | Description | ||
14 | ----------- | ||
15 | |||
16 | This driver implements support for Nuvoton W83773G temperature sensor | ||
17 | chip. This chip implements one local and two remote sensors. | ||
18 | The chip also features offsets for the two remote sensors which get added to | ||
19 | the input readings. The chip does all the scaling by itself and the driver | ||
20 | therefore reports true temperatures that don't need any user-space adjustments. | ||
21 | Temperature is measured in degrees Celsius. | ||
22 | The chip is wired over I2C/SMBus and specified over a temperature | ||
23 | range of -40 to +125 degrees Celsius (for local sensor) and -40 to +127 | ||
24 | degrees Celsius (for remote sensors). | ||
25 | Resolution for both the local and remote channels is 0.125 degree C. | ||
26 | |||
27 | The chip supports only temperature measurement. The driver exports | ||
28 | the temperature values via the following sysfs files: | ||
29 | |||
30 | temp[1-3]_input | ||
31 | temp[2-3]_fault | ||
32 | temp[2-3]_offset | ||
33 | update_interval | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 7ad017690e3a..ef23553ff5cb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -26,11 +26,9 @@ if HWMON | |||
26 | 26 | ||
27 | config HWMON_VID | 27 | config HWMON_VID |
28 | tristate | 28 | tristate |
29 | default n | ||
30 | 29 | ||
31 | config HWMON_DEBUG_CHIP | 30 | config HWMON_DEBUG_CHIP |
32 | bool "Hardware Monitoring Chip debugging messages" | 31 | bool "Hardware Monitoring Chip debugging messages" |
33 | default n | ||
34 | help | 32 | help |
35 | Say Y here if you want the I2C chip drivers to produce a bunch of | 33 | Say Y here if you want the I2C chip drivers to produce a bunch of |
36 | debug messages to the system log. Select this if you are having | 34 | debug messages to the system log. Select this if you are having |
@@ -42,7 +40,6 @@ comment "Native drivers" | |||
42 | config SENSORS_AB8500 | 40 | config SENSORS_AB8500 |
43 | tristate "AB8500 thermal monitoring" | 41 | tristate "AB8500 thermal monitoring" |
44 | depends on AB8500_GPADC && AB8500_BM | 42 | depends on AB8500_GPADC && AB8500_BM |
45 | default n | ||
46 | help | 43 | help |
47 | If you say yes here you get support for the thermal sensor part | 44 | If you say yes here you get support for the thermal sensor part |
48 | of the AB8500 chip. The driver includes thermal management for | 45 | of the AB8500 chip. The driver includes thermal management for |
@@ -302,7 +299,6 @@ config SENSORS_APPLESMC | |||
302 | select NEW_LEDS | 299 | select NEW_LEDS |
303 | select LEDS_CLASS | 300 | select LEDS_CLASS |
304 | select INPUT_POLLDEV | 301 | select INPUT_POLLDEV |
305 | default n | ||
306 | help | 302 | help |
307 | This driver provides support for the Apple System Management | 303 | This driver provides support for the Apple System Management |
308 | Controller, which provides an accelerometer (Apple Sudden Motion | 304 | Controller, which provides an accelerometer (Apple Sudden Motion |
@@ -678,7 +674,6 @@ config SENSORS_JC42 | |||
678 | config SENSORS_POWR1220 | 674 | config SENSORS_POWR1220 |
679 | tristate "Lattice POWR1220 Power Monitoring" | 675 | tristate "Lattice POWR1220 Power Monitoring" |
680 | depends on I2C | 676 | depends on I2C |
681 | default n | ||
682 | help | 677 | help |
683 | If you say yes here you get access to the hardware monitoring | 678 | If you say yes here you get access to the hardware monitoring |
684 | functions of the Lattice POWR1220 isp Power Supply Monitoring, | 679 | functions of the Lattice POWR1220 isp Power Supply Monitoring, |
@@ -702,7 +697,6 @@ config SENSORS_LTC2945 | |||
702 | tristate "Linear Technology LTC2945" | 697 | tristate "Linear Technology LTC2945" |
703 | depends on I2C | 698 | depends on I2C |
704 | select REGMAP_I2C | 699 | select REGMAP_I2C |
705 | default n | ||
706 | help | 700 | help |
707 | If you say yes here you get support for Linear Technology LTC2945 | 701 | If you say yes here you get support for Linear Technology LTC2945 |
708 | I2C System Monitor. | 702 | I2C System Monitor. |
@@ -727,7 +721,6 @@ config SENSORS_LTC2990 | |||
727 | config SENSORS_LTC4151 | 721 | config SENSORS_LTC4151 |
728 | tristate "Linear Technology LTC4151" | 722 | tristate "Linear Technology LTC4151" |
729 | depends on I2C | 723 | depends on I2C |
730 | default n | ||
731 | help | 724 | help |
732 | If you say yes here you get support for Linear Technology LTC4151 | 725 | If you say yes here you get support for Linear Technology LTC4151 |
733 | High Voltage I2C Current and Voltage Monitor interface. | 726 | High Voltage I2C Current and Voltage Monitor interface. |
@@ -738,7 +731,6 @@ config SENSORS_LTC4151 | |||
738 | config SENSORS_LTC4215 | 731 | config SENSORS_LTC4215 |
739 | tristate "Linear Technology LTC4215" | 732 | tristate "Linear Technology LTC4215" |
740 | depends on I2C | 733 | depends on I2C |
741 | default n | ||
742 | help | 734 | help |
743 | If you say yes here you get support for Linear Technology LTC4215 | 735 | If you say yes here you get support for Linear Technology LTC4215 |
744 | Hot Swap Controller I2C interface. | 736 | Hot Swap Controller I2C interface. |
@@ -750,7 +742,6 @@ config SENSORS_LTC4222 | |||
750 | tristate "Linear Technology LTC4222" | 742 | tristate "Linear Technology LTC4222" |
751 | depends on I2C | 743 | depends on I2C |
752 | select REGMAP_I2C | 744 | select REGMAP_I2C |
753 | default n | ||
754 | help | 745 | help |
755 | If you say yes here you get support for Linear Technology LTC4222 | 746 | If you say yes here you get support for Linear Technology LTC4222 |
756 | Dual Hot Swap Controller I2C interface. | 747 | Dual Hot Swap Controller I2C interface. |
@@ -761,7 +752,6 @@ config SENSORS_LTC4222 | |||
761 | config SENSORS_LTC4245 | 752 | config SENSORS_LTC4245 |
762 | tristate "Linear Technology LTC4245" | 753 | tristate "Linear Technology LTC4245" |
763 | depends on I2C | 754 | depends on I2C |
764 | default n | ||
765 | help | 755 | help |
766 | If you say yes here you get support for Linear Technology LTC4245 | 756 | If you say yes here you get support for Linear Technology LTC4245 |
767 | Multiple Supply Hot Swap Controller I2C interface. | 757 | Multiple Supply Hot Swap Controller I2C interface. |
@@ -773,7 +763,6 @@ config SENSORS_LTC4260 | |||
773 | tristate "Linear Technology LTC4260" | 763 | tristate "Linear Technology LTC4260" |
774 | depends on I2C | 764 | depends on I2C |
775 | select REGMAP_I2C | 765 | select REGMAP_I2C |
776 | default n | ||
777 | help | 766 | help |
778 | If you say yes here you get support for Linear Technology LTC4260 | 767 | If you say yes here you get support for Linear Technology LTC4260 |
779 | Positive Voltage Hot Swap Controller I2C interface. | 768 | Positive Voltage Hot Swap Controller I2C interface. |
@@ -784,7 +773,6 @@ config SENSORS_LTC4260 | |||
784 | config SENSORS_LTC4261 | 773 | config SENSORS_LTC4261 |
785 | tristate "Linear Technology LTC4261" | 774 | tristate "Linear Technology LTC4261" |
786 | depends on I2C | 775 | depends on I2C |
787 | default n | ||
788 | help | 776 | help |
789 | If you say yes here you get support for Linear Technology LTC4261 | 777 | If you say yes here you get support for Linear Technology LTC4261 |
790 | Negative Voltage Hot Swap Controller I2C interface. | 778 | Negative Voltage Hot Swap Controller I2C interface. |
@@ -1276,7 +1264,6 @@ config SENSORS_NSA320 | |||
1276 | config SENSORS_PCF8591 | 1264 | config SENSORS_PCF8591 |
1277 | tristate "Philips PCF8591 ADC/DAC" | 1265 | tristate "Philips PCF8591 ADC/DAC" |
1278 | depends on I2C | 1266 | depends on I2C |
1279 | default n | ||
1280 | help | 1267 | help |
1281 | If you say yes here you get support for Philips PCF8591 4-channel | 1268 | If you say yes here you get support for Philips PCF8591 4-channel |
1282 | ADC, 1-channel DAC chips. | 1269 | ADC, 1-channel DAC chips. |
@@ -1459,7 +1446,6 @@ config SENSORS_SMSC47B397 | |||
1459 | 1446 | ||
1460 | config SENSORS_SCH56XX_COMMON | 1447 | config SENSORS_SCH56XX_COMMON |
1461 | tristate | 1448 | tristate |
1462 | default n | ||
1463 | 1449 | ||
1464 | config SENSORS_SCH5627 | 1450 | config SENSORS_SCH5627 |
1465 | tristate "SMSC SCH5627" | 1451 | tristate "SMSC SCH5627" |
@@ -1505,7 +1491,6 @@ config SENSORS_STTS751 | |||
1505 | config SENSORS_SMM665 | 1491 | config SENSORS_SMM665 |
1506 | tristate "Summit Microelectronics SMM665" | 1492 | tristate "Summit Microelectronics SMM665" |
1507 | depends on I2C | 1493 | depends on I2C |
1508 | default n | ||
1509 | help | 1494 | help |
1510 | If you say yes here you get support for the hardware monitoring | 1495 | If you say yes here you get support for the hardware monitoring |
1511 | features of the Summit Microelectronics SMM665/SMM665B Six-Channel | 1496 | features of the Summit Microelectronics SMM665/SMM665B Six-Channel |
@@ -1725,6 +1710,16 @@ config SENSORS_VT8231 | |||
1725 | This driver can also be built as a module. If so, the module | 1710 | This driver can also be built as a module. If so, the module |
1726 | will be called vt8231. | 1711 | will be called vt8231. |
1727 | 1712 | ||
1713 | config SENSORS_W83773G | ||
1714 | tristate "Nuvoton W83773G" | ||
1715 | depends on I2C | ||
1716 | help | ||
1717 | If you say yes here you get support for the Nuvoton W83773G hardware | ||
1718 | monitoring chip. | ||
1719 | |||
1720 | This driver can also be built as a module. If so, the module | ||
1721 | will be called w83773g. | ||
1722 | |||
1728 | config SENSORS_W83781D | 1723 | config SENSORS_W83781D |
1729 | tristate "Winbond W83781D, W83782D, W83783S, Asus AS99127F" | 1724 | tristate "Winbond W83781D, W83782D, W83783S, Asus AS99127F" |
1730 | depends on I2C | 1725 | depends on I2C |
@@ -1782,7 +1777,6 @@ config SENSORS_W83795 | |||
1782 | config SENSORS_W83795_FANCTRL | 1777 | config SENSORS_W83795_FANCTRL |
1783 | bool "Include automatic fan control support (DANGEROUS)" | 1778 | bool "Include automatic fan control support (DANGEROUS)" |
1784 | depends on SENSORS_W83795 | 1779 | depends on SENSORS_W83795 |
1785 | default n | ||
1786 | help | 1780 | help |
1787 | If you say yes here, support for automatic fan speed control | 1781 | If you say yes here, support for automatic fan speed control |
1788 | will be included in the driver. | 1782 | will be included in the driver. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 0fe489fab663..f814b4ace138 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o | |||
14 | # asb100, then w83781d go first, as they can override other drivers' addresses. | 14 | # asb100, then w83781d go first, as they can override other drivers' addresses. |
15 | obj-$(CONFIG_SENSORS_ASB100) += asb100.o | 15 | obj-$(CONFIG_SENSORS_ASB100) += asb100.o |
16 | obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o | 16 | obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o |
17 | obj-$(CONFIG_SENSORS_W83773G) += w83773g.o | ||
17 | obj-$(CONFIG_SENSORS_W83792D) += w83792d.o | 18 | obj-$(CONFIG_SENSORS_W83792D) += w83792d.o |
18 | obj-$(CONFIG_SENSORS_W83793) += w83793.o | 19 | obj-$(CONFIG_SENSORS_W83793) += w83793.o |
19 | obj-$(CONFIG_SENSORS_W83795) += w83795.o | 20 | obj-$(CONFIG_SENSORS_W83795) += w83795.o |
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c index 63a95e23ca81..693a3d53cab5 100644 --- a/drivers/hwmon/aspeed-pwm-tacho.c +++ b/drivers/hwmon/aspeed-pwm-tacho.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/regmap.h> | 21 | #include <linux/regmap.h> |
22 | #include <linux/reset.h> | ||
22 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
23 | #include <linux/thermal.h> | 24 | #include <linux/thermal.h> |
24 | 25 | ||
@@ -181,6 +182,7 @@ struct aspeed_cooling_device { | |||
181 | 182 | ||
182 | struct aspeed_pwm_tacho_data { | 183 | struct aspeed_pwm_tacho_data { |
183 | struct regmap *regmap; | 184 | struct regmap *regmap; |
185 | struct reset_control *rst; | ||
184 | unsigned long clk_freq; | 186 | unsigned long clk_freq; |
185 | bool pwm_present[8]; | 187 | bool pwm_present[8]; |
186 | bool fan_tach_present[16]; | 188 | bool fan_tach_present[16]; |
@@ -905,6 +907,13 @@ static int aspeed_create_fan(struct device *dev, | |||
905 | return 0; | 907 | return 0; |
906 | } | 908 | } |
907 | 909 | ||
910 | static void aspeed_pwm_tacho_remove(void *data) | ||
911 | { | ||
912 | struct aspeed_pwm_tacho_data *priv = data; | ||
913 | |||
914 | reset_control_assert(priv->rst); | ||
915 | } | ||
916 | |||
908 | static int aspeed_pwm_tacho_probe(struct platform_device *pdev) | 917 | static int aspeed_pwm_tacho_probe(struct platform_device *pdev) |
909 | { | 918 | { |
910 | struct device *dev = &pdev->dev; | 919 | struct device *dev = &pdev->dev; |
@@ -931,6 +940,19 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev) | |||
931 | &aspeed_pwm_tacho_regmap_config); | 940 | &aspeed_pwm_tacho_regmap_config); |
932 | if (IS_ERR(priv->regmap)) | 941 | if (IS_ERR(priv->regmap)) |
933 | return PTR_ERR(priv->regmap); | 942 | return PTR_ERR(priv->regmap); |
943 | |||
944 | priv->rst = devm_reset_control_get_exclusive(dev, NULL); | ||
945 | if (IS_ERR(priv->rst)) { | ||
946 | dev_err(dev, | ||
947 | "missing or invalid reset controller device tree entry"); | ||
948 | return PTR_ERR(priv->rst); | ||
949 | } | ||
950 | reset_control_deassert(priv->rst); | ||
951 | |||
952 | ret = devm_add_action_or_reset(dev, aspeed_pwm_tacho_remove, priv); | ||
953 | if (ret) | ||
954 | return ret; | ||
955 | |||
934 | regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE, 0); | 956 | regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE, 0); |
935 | regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE_EXT, 0); | 957 | regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE_EXT, 0); |
936 | 958 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index c13a4fd86b3c..4bdbf77f7197 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -246,7 +246,8 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
246 | int err; | 246 | int err; |
247 | u32 eax, edx; | 247 | u32 eax, edx; |
248 | int i; | 248 | int i; |
249 | struct pci_dev *host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); | 249 | u16 devfn = PCI_DEVFN(0, 0); |
250 | struct pci_dev *host_bridge = pci_get_domain_bus_and_slot(0, 0, devfn); | ||
250 | 251 | ||
251 | /* | 252 | /* |
252 | * Explicit tjmax table entries override heuristics. | 253 | * Explicit tjmax table entries override heuristics. |
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index c7c9e95e58a8..bf3bb7e1adab 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c | |||
@@ -76,6 +76,7 @@ static uint i8k_fan_mult = I8K_FAN_MULT; | |||
76 | static uint i8k_pwm_mult; | 76 | static uint i8k_pwm_mult; |
77 | static uint i8k_fan_max = I8K_FAN_HIGH; | 77 | static uint i8k_fan_max = I8K_FAN_HIGH; |
78 | static bool disallow_fan_type_call; | 78 | static bool disallow_fan_type_call; |
79 | static bool disallow_fan_support; | ||
79 | 80 | ||
80 | #define I8K_HWMON_HAVE_TEMP1 (1 << 0) | 81 | #define I8K_HWMON_HAVE_TEMP1 (1 << 0) |
81 | #define I8K_HWMON_HAVE_TEMP2 (1 << 1) | 82 | #define I8K_HWMON_HAVE_TEMP2 (1 << 1) |
@@ -242,6 +243,9 @@ static int i8k_get_fan_status(int fan) | |||
242 | { | 243 | { |
243 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, }; | 244 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, }; |
244 | 245 | ||
246 | if (disallow_fan_support) | ||
247 | return -EINVAL; | ||
248 | |||
245 | regs.ebx = fan & 0xff; | 249 | regs.ebx = fan & 0xff; |
246 | return i8k_smm(®s) ? : regs.eax & 0xff; | 250 | return i8k_smm(®s) ? : regs.eax & 0xff; |
247 | } | 251 | } |
@@ -253,6 +257,9 @@ static int i8k_get_fan_speed(int fan) | |||
253 | { | 257 | { |
254 | struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; | 258 | struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; |
255 | 259 | ||
260 | if (disallow_fan_support) | ||
261 | return -EINVAL; | ||
262 | |||
256 | regs.ebx = fan & 0xff; | 263 | regs.ebx = fan & 0xff; |
257 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * i8k_fan_mult; | 264 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * i8k_fan_mult; |
258 | } | 265 | } |
@@ -264,7 +271,7 @@ static int _i8k_get_fan_type(int fan) | |||
264 | { | 271 | { |
265 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, }; | 272 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, }; |
266 | 273 | ||
267 | if (disallow_fan_type_call) | 274 | if (disallow_fan_support || disallow_fan_type_call) |
268 | return -EINVAL; | 275 | return -EINVAL; |
269 | 276 | ||
270 | regs.ebx = fan & 0xff; | 277 | regs.ebx = fan & 0xff; |
@@ -289,6 +296,9 @@ static int i8k_get_fan_nominal_speed(int fan, int speed) | |||
289 | { | 296 | { |
290 | struct smm_regs regs = { .eax = I8K_SMM_GET_NOM_SPEED, }; | 297 | struct smm_regs regs = { .eax = I8K_SMM_GET_NOM_SPEED, }; |
291 | 298 | ||
299 | if (disallow_fan_support) | ||
300 | return -EINVAL; | ||
301 | |||
292 | regs.ebx = (fan & 0xff) | (speed << 8); | 302 | regs.ebx = (fan & 0xff) | (speed << 8); |
293 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * i8k_fan_mult; | 303 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * i8k_fan_mult; |
294 | } | 304 | } |
@@ -300,6 +310,9 @@ static int i8k_set_fan(int fan, int speed) | |||
300 | { | 310 | { |
301 | struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, }; | 311 | struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, }; |
302 | 312 | ||
313 | if (disallow_fan_support) | ||
314 | return -EINVAL; | ||
315 | |||
303 | speed = (speed < 0) ? 0 : ((speed > i8k_fan_max) ? i8k_fan_max : speed); | 316 | speed = (speed < 0) ? 0 : ((speed > i8k_fan_max) ? i8k_fan_max : speed); |
304 | regs.ebx = (fan & 0xff) | (speed << 8); | 317 | regs.ebx = (fan & 0xff) | (speed << 8); |
305 | 318 | ||
@@ -772,6 +785,8 @@ static struct attribute *i8k_attrs[] = { | |||
772 | static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, | 785 | static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, |
773 | int index) | 786 | int index) |
774 | { | 787 | { |
788 | if (disallow_fan_support && index >= 8) | ||
789 | return 0; | ||
775 | if (disallow_fan_type_call && | 790 | if (disallow_fan_type_call && |
776 | (index == 9 || index == 12 || index == 15)) | 791 | (index == 9 || index == 12 || index == 15)) |
777 | return 0; | 792 | return 0; |
@@ -1039,6 +1054,30 @@ static const struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initconst | |||
1039 | }; | 1054 | }; |
1040 | 1055 | ||
1041 | /* | 1056 | /* |
1057 | * On some machines all fan related SMM functions implemented by Dell BIOS | ||
1058 | * firmware freeze kernel for about 500ms. Until Dell fixes these problems fan | ||
1059 | * support for affected blacklisted Dell machines stay disabled. | ||
1060 | * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=195751 | ||
1061 | */ | ||
1062 | static struct dmi_system_id i8k_blacklist_fan_support_dmi_table[] __initdata = { | ||
1063 | { | ||
1064 | .ident = "Dell Inspiron 7720", | ||
1065 | .matches = { | ||
1066 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
1067 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"), | ||
1068 | }, | ||
1069 | }, | ||
1070 | { | ||
1071 | .ident = "Dell Vostro 3360", | ||
1072 | .matches = { | ||
1073 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
1074 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"), | ||
1075 | }, | ||
1076 | }, | ||
1077 | { } | ||
1078 | }; | ||
1079 | |||
1080 | /* | ||
1042 | * Probe for the presence of a supported laptop. | 1081 | * Probe for the presence of a supported laptop. |
1043 | */ | 1082 | */ |
1044 | static int __init i8k_probe(void) | 1083 | static int __init i8k_probe(void) |
@@ -1060,8 +1099,17 @@ static int __init i8k_probe(void) | |||
1060 | i8k_get_dmi_data(DMI_BIOS_VERSION)); | 1099 | i8k_get_dmi_data(DMI_BIOS_VERSION)); |
1061 | } | 1100 | } |
1062 | 1101 | ||
1063 | if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) | 1102 | if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) { |
1064 | disallow_fan_type_call = true; | 1103 | pr_warn("broken Dell BIOS detected, disallow fan support\n"); |
1104 | if (!force) | ||
1105 | disallow_fan_support = true; | ||
1106 | } | ||
1107 | |||
1108 | if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) { | ||
1109 | pr_warn("broken Dell BIOS detected, disallow fan type call\n"); | ||
1110 | if (!force) | ||
1111 | disallow_fan_type_call = true; | ||
1112 | } | ||
1065 | 1113 | ||
1066 | strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), | 1114 | strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), |
1067 | sizeof(bios_version)); | 1115 | sizeof(bios_version)); |
diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c index 7b73d2002d3e..0ae1ee1dbf76 100644 --- a/drivers/hwmon/hih6130.c +++ b/drivers/hwmon/hih6130.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | /** | 38 | /** |
39 | * struct hih6130 - HIH-6130 device specific data | 39 | * struct hih6130 - HIH-6130 device specific data |
40 | * @hwmon_dev: device registered with hwmon | 40 | * @client: pointer to I2C client device |
41 | * @lock: mutex to protect measurement values | 41 | * @lock: mutex to protect measurement values |
42 | * @valid: only false before first measurement is taken | 42 | * @valid: only false before first measurement is taken |
43 | * @last_update: time of last update (jiffies) | 43 | * @last_update: time of last update (jiffies) |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index af5123042990..32083e452cde 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -678,7 +678,7 @@ EXPORT_SYMBOL_GPL(hwmon_device_register_with_groups); | |||
678 | * @dev: the parent device | 678 | * @dev: the parent device |
679 | * @name: hwmon name attribute | 679 | * @name: hwmon name attribute |
680 | * @drvdata: driver data to attach to created device | 680 | * @drvdata: driver data to attach to created device |
681 | * @info: pointer to hwmon chip information | 681 | * @chip: pointer to hwmon chip information |
682 | * @extra_groups: pointer to list of additional non-standard attribute groups | 682 | * @extra_groups: pointer to list of additional non-standard attribute groups |
683 | * | 683 | * |
684 | * hwmon_device_unregister() must be called when the device is no | 684 | * hwmon_device_unregister() must be called when the device is no |
@@ -785,11 +785,11 @@ EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups); | |||
785 | 785 | ||
786 | /** | 786 | /** |
787 | * devm_hwmon_device_register_with_info - register w/ hwmon | 787 | * devm_hwmon_device_register_with_info - register w/ hwmon |
788 | * @dev: the parent device | 788 | * @dev: the parent device |
789 | * @name: hwmon name attribute | 789 | * @name: hwmon name attribute |
790 | * @drvdata: driver data to attach to created device | 790 | * @drvdata: driver data to attach to created device |
791 | * @info: Pointer to hwmon chip information | 791 | * @chip: pointer to hwmon chip information |
792 | * @groups - pointer to list of driver specific attribute groups | 792 | * @groups: pointer to list of driver specific attribute groups |
793 | * | 793 | * |
794 | * Returns the pointer to the new device. The new device is automatically | 794 | * Returns the pointer to the new device. The new device is automatically |
795 | * unregistered with the parent device. | 795 | * unregistered with the parent device. |
diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index f6a76679c650..5e5b32a1ec4b 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c | |||
@@ -23,7 +23,8 @@ | |||
23 | * @channels: filled with array of channels from iio | 23 | * @channels: filled with array of channels from iio |
24 | * @num_channels: number of channels in channels (saves counting twice) | 24 | * @num_channels: number of channels in channels (saves counting twice) |
25 | * @hwmon_dev: associated hwmon device | 25 | * @hwmon_dev: associated hwmon device |
26 | * @attr_group: the group of attributes | 26 | * @attr_group: the group of attributes |
27 | * @groups: null terminated array of attribute groups | ||
27 | * @attrs: null terminated array of attribute pointers. | 28 | * @attrs: null terminated array of attribute pointers. |
28 | */ | 29 | */ |
29 | struct iio_hwmon_state { | 30 | struct iio_hwmon_state { |
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 62e38fa8cda2..e9e6aeabbf84 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c | |||
@@ -95,18 +95,20 @@ enum ina2xx_ids { ina219, ina226 }; | |||
95 | 95 | ||
96 | struct ina2xx_config { | 96 | struct ina2xx_config { |
97 | u16 config_default; | 97 | u16 config_default; |
98 | int calibration_factor; | 98 | int calibration_value; |
99 | int registers; | 99 | int registers; |
100 | int shunt_div; | 100 | int shunt_div; |
101 | int bus_voltage_shift; | 101 | int bus_voltage_shift; |
102 | int bus_voltage_lsb; /* uV */ | 102 | int bus_voltage_lsb; /* uV */ |
103 | int power_lsb; /* uW */ | 103 | int power_lsb_factor; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | struct ina2xx_data { | 106 | struct ina2xx_data { |
107 | const struct ina2xx_config *config; | 107 | const struct ina2xx_config *config; |
108 | 108 | ||
109 | long rshunt; | 109 | long rshunt; |
110 | long current_lsb_uA; | ||
111 | long power_lsb_uW; | ||
110 | struct mutex config_lock; | 112 | struct mutex config_lock; |
111 | struct regmap *regmap; | 113 | struct regmap *regmap; |
112 | 114 | ||
@@ -116,21 +118,21 @@ struct ina2xx_data { | |||
116 | static const struct ina2xx_config ina2xx_config[] = { | 118 | static const struct ina2xx_config ina2xx_config[] = { |
117 | [ina219] = { | 119 | [ina219] = { |
118 | .config_default = INA219_CONFIG_DEFAULT, | 120 | .config_default = INA219_CONFIG_DEFAULT, |
119 | .calibration_factor = 40960000, | 121 | .calibration_value = 4096, |
120 | .registers = INA219_REGISTERS, | 122 | .registers = INA219_REGISTERS, |
121 | .shunt_div = 100, | 123 | .shunt_div = 100, |
122 | .bus_voltage_shift = 3, | 124 | .bus_voltage_shift = 3, |
123 | .bus_voltage_lsb = 4000, | 125 | .bus_voltage_lsb = 4000, |
124 | .power_lsb = 20000, | 126 | .power_lsb_factor = 20, |
125 | }, | 127 | }, |
126 | [ina226] = { | 128 | [ina226] = { |
127 | .config_default = INA226_CONFIG_DEFAULT, | 129 | .config_default = INA226_CONFIG_DEFAULT, |
128 | .calibration_factor = 5120000, | 130 | .calibration_value = 2048, |
129 | .registers = INA226_REGISTERS, | 131 | .registers = INA226_REGISTERS, |
130 | .shunt_div = 400, | 132 | .shunt_div = 400, |
131 | .bus_voltage_shift = 0, | 133 | .bus_voltage_shift = 0, |
132 | .bus_voltage_lsb = 1250, | 134 | .bus_voltage_lsb = 1250, |
133 | .power_lsb = 25000, | 135 | .power_lsb_factor = 25, |
134 | }, | 136 | }, |
135 | }; | 137 | }; |
136 | 138 | ||
@@ -169,12 +171,16 @@ static u16 ina226_interval_to_reg(int interval) | |||
169 | return INA226_SHIFT_AVG(avg_bits); | 171 | return INA226_SHIFT_AVG(avg_bits); |
170 | } | 172 | } |
171 | 173 | ||
174 | /* | ||
175 | * Calibration register is set to the best value, which eliminates | ||
176 | * truncation errors on calculating current register in hardware. | ||
177 | * According to datasheet (eq. 3) the best values are 2048 for | ||
178 | * ina226 and 4096 for ina219. They are hardcoded as calibration_value. | ||
179 | */ | ||
172 | static int ina2xx_calibrate(struct ina2xx_data *data) | 180 | static int ina2xx_calibrate(struct ina2xx_data *data) |
173 | { | 181 | { |
174 | u16 val = DIV_ROUND_CLOSEST(data->config->calibration_factor, | 182 | return regmap_write(data->regmap, INA2XX_CALIBRATION, |
175 | data->rshunt); | 183 | data->config->calibration_value); |
176 | |||
177 | return regmap_write(data->regmap, INA2XX_CALIBRATION, val); | ||
178 | } | 184 | } |
179 | 185 | ||
180 | /* | 186 | /* |
@@ -187,10 +193,6 @@ static int ina2xx_init(struct ina2xx_data *data) | |||
187 | if (ret < 0) | 193 | if (ret < 0) |
188 | return ret; | 194 | return ret; |
189 | 195 | ||
190 | /* | ||
191 | * Set current LSB to 1mA, shunt is in uOhms | ||
192 | * (equation 13 in datasheet). | ||
193 | */ | ||
194 | return ina2xx_calibrate(data); | 196 | return ina2xx_calibrate(data); |
195 | } | 197 | } |
196 | 198 | ||
@@ -268,15 +270,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, | |||
268 | val = DIV_ROUND_CLOSEST(val, 1000); | 270 | val = DIV_ROUND_CLOSEST(val, 1000); |
269 | break; | 271 | break; |
270 | case INA2XX_POWER: | 272 | case INA2XX_POWER: |
271 | val = regval * data->config->power_lsb; | 273 | val = regval * data->power_lsb_uW; |
272 | break; | 274 | break; |
273 | case INA2XX_CURRENT: | 275 | case INA2XX_CURRENT: |
274 | /* signed register, LSB=1mA (selected), in mA */ | 276 | /* signed register, result in mA */ |
275 | val = (s16)regval; | 277 | val = regval * data->current_lsb_uA; |
278 | val = DIV_ROUND_CLOSEST(val, 1000); | ||
276 | break; | 279 | break; |
277 | case INA2XX_CALIBRATION: | 280 | case INA2XX_CALIBRATION: |
278 | val = DIV_ROUND_CLOSEST(data->config->calibration_factor, | 281 | val = regval; |
279 | regval); | ||
280 | break; | 282 | break; |
281 | default: | 283 | default: |
282 | /* programmer goofed */ | 284 | /* programmer goofed */ |
@@ -304,9 +306,32 @@ static ssize_t ina2xx_show_value(struct device *dev, | |||
304 | ina2xx_get_value(data, attr->index, regval)); | 306 | ina2xx_get_value(data, attr->index, regval)); |
305 | } | 307 | } |
306 | 308 | ||
307 | static ssize_t ina2xx_set_shunt(struct device *dev, | 309 | /* |
308 | struct device_attribute *da, | 310 | * In order to keep calibration register value fixed, the product |
309 | const char *buf, size_t count) | 311 | * of current_lsb and shunt_resistor should also be fixed and equal |
312 | * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order | ||
313 | * to keep the scale. | ||
314 | */ | ||
315 | static int ina2xx_set_shunt(struct ina2xx_data *data, long val) | ||
316 | { | ||
317 | unsigned int dividend = DIV_ROUND_CLOSEST(1000000000, | ||
318 | data->config->shunt_div); | ||
319 | if (val <= 0 || val > dividend) | ||
320 | return -EINVAL; | ||
321 | |||
322 | mutex_lock(&data->config_lock); | ||
323 | data->rshunt = val; | ||
324 | data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); | ||
325 | data->power_lsb_uW = data->config->power_lsb_factor * | ||
326 | data->current_lsb_uA; | ||
327 | mutex_unlock(&data->config_lock); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static ssize_t ina2xx_store_shunt(struct device *dev, | ||
333 | struct device_attribute *da, | ||
334 | const char *buf, size_t count) | ||
310 | { | 335 | { |
311 | unsigned long val; | 336 | unsigned long val; |
312 | int status; | 337 | int status; |
@@ -316,18 +341,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev, | |||
316 | if (status < 0) | 341 | if (status < 0) |
317 | return status; | 342 | return status; |
318 | 343 | ||
319 | if (val == 0 || | 344 | status = ina2xx_set_shunt(data, val); |
320 | /* Values greater than the calibration factor make no sense. */ | ||
321 | val > data->config->calibration_factor) | ||
322 | return -EINVAL; | ||
323 | |||
324 | mutex_lock(&data->config_lock); | ||
325 | data->rshunt = val; | ||
326 | status = ina2xx_calibrate(data); | ||
327 | mutex_unlock(&data->config_lock); | ||
328 | if (status < 0) | 345 | if (status < 0) |
329 | return status; | 346 | return status; |
330 | |||
331 | return count; | 347 | return count; |
332 | } | 348 | } |
333 | 349 | ||
@@ -387,7 +403,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, | |||
387 | 403 | ||
388 | /* shunt resistance */ | 404 | /* shunt resistance */ |
389 | static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR, | 405 | static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR, |
390 | ina2xx_show_value, ina2xx_set_shunt, | 406 | ina2xx_show_value, ina2xx_store_shunt, |
391 | INA2XX_CALIBRATION); | 407 | INA2XX_CALIBRATION); |
392 | 408 | ||
393 | /* update interval (ina226 only) */ | 409 | /* update interval (ina226 only) */ |
@@ -438,6 +454,7 @@ static int ina2xx_probe(struct i2c_client *client, | |||
438 | 454 | ||
439 | /* set the device type */ | 455 | /* set the device type */ |
440 | data->config = &ina2xx_config[chip]; | 456 | data->config = &ina2xx_config[chip]; |
457 | mutex_init(&data->config_lock); | ||
441 | 458 | ||
442 | if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { | 459 | if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { |
443 | struct ina2xx_platform_data *pdata = dev_get_platdata(dev); | 460 | struct ina2xx_platform_data *pdata = dev_get_platdata(dev); |
@@ -448,10 +465,7 @@ static int ina2xx_probe(struct i2c_client *client, | |||
448 | val = INA2XX_RSHUNT_DEFAULT; | 465 | val = INA2XX_RSHUNT_DEFAULT; |
449 | } | 466 | } |
450 | 467 | ||
451 | if (val <= 0 || val > data->config->calibration_factor) | 468 | ina2xx_set_shunt(data, val); |
452 | return -ENODEV; | ||
453 | |||
454 | data->rshunt = val; | ||
455 | 469 | ||
456 | ina2xx_regmap_config.max_register = data->config->registers; | 470 | ina2xx_regmap_config.max_register = data->config->registers; |
457 | 471 | ||
@@ -467,8 +481,6 @@ static int ina2xx_probe(struct i2c_client *client, | |||
467 | return -ENODEV; | 481 | return -ENODEV; |
468 | } | 482 | } |
469 | 483 | ||
470 | mutex_init(&data->config_lock); | ||
471 | |||
472 | data->groups[group++] = &ina2xx_group; | 484 | data->groups[group++] = &ina2xx_group; |
473 | if (id->driver_data == ina226) | 485 | if (id->driver_data == ina226) |
474 | data->groups[group++] = &ina226_group; | 486 | data->groups[group++] = &ina226_group; |
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 0721e175664a..06b4e1c78bd8 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c | |||
@@ -86,6 +86,7 @@ static const struct tctl_offset tctl_offset_table[] = { | |||
86 | { 0x17, "AMD Ryzen 7 1800X", 20000 }, | 86 | { 0x17, "AMD Ryzen 7 1800X", 20000 }, |
87 | { 0x17, "AMD Ryzen Threadripper 1950X", 27000 }, | 87 | { 0x17, "AMD Ryzen Threadripper 1950X", 27000 }, |
88 | { 0x17, "AMD Ryzen Threadripper 1920X", 27000 }, | 88 | { 0x17, "AMD Ryzen Threadripper 1920X", 27000 }, |
89 | { 0x17, "AMD Ryzen Threadripper 1900X", 27000 }, | ||
89 | { 0x17, "AMD Ryzen Threadripper 1950", 10000 }, | 90 | { 0x17, "AMD Ryzen Threadripper 1950", 10000 }, |
90 | { 0x17, "AMD Ryzen Threadripper 1920", 10000 }, | 91 | { 0x17, "AMD Ryzen Threadripper 1920", 10000 }, |
91 | { 0x17, "AMD Ryzen Threadripper 1910", 10000 }, | 92 | { 0x17, "AMD Ryzen Threadripper 1910", 10000 }, |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 005ffb5ffa92..49f4b33a5685 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -100,7 +100,7 @@ static int lm75_read(struct device *dev, enum hwmon_sensor_types type, | |||
100 | switch (attr) { | 100 | switch (attr) { |
101 | case hwmon_chip_update_interval: | 101 | case hwmon_chip_update_interval: |
102 | *val = data->sample_time; | 102 | *val = data->sample_time; |
103 | break;; | 103 | break; |
104 | default: | 104 | default: |
105 | return -EINVAL; | 105 | return -EINVAL; |
106 | } | 106 | } |
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 08479006c7f9..6e4298e99222 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -39,6 +39,7 @@ config SENSORS_ADM1275 | |||
39 | 39 | ||
40 | config SENSORS_IBM_CFFPS | 40 | config SENSORS_IBM_CFFPS |
41 | tristate "IBM Common Form Factor Power Supply" | 41 | tristate "IBM Common Form Factor Power Supply" |
42 | depends on LEDS_CLASS | ||
42 | help | 43 | help |
43 | If you say yes here you get hardware monitoring support for the IBM | 44 | If you say yes here you get hardware monitoring support for the IBM |
44 | Common Form Factor power supply. | 45 | Common Form Factor power supply. |
diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c index cb56da6834e5..93d9a9ea112b 100644 --- a/drivers/hwmon/pmbus/ibm-cffps.c +++ b/drivers/hwmon/pmbus/ibm-cffps.c | |||
@@ -8,12 +8,29 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
11 | #include <linux/debugfs.h> | ||
11 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/fs.h> | ||
12 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/jiffies.h> | ||
16 | #include <linux/leds.h> | ||
13 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/mutex.h> | ||
19 | #include <linux/pmbus.h> | ||
14 | 20 | ||
15 | #include "pmbus.h" | 21 | #include "pmbus.h" |
16 | 22 | ||
23 | #define CFFPS_FRU_CMD 0x9A | ||
24 | #define CFFPS_PN_CMD 0x9B | ||
25 | #define CFFPS_SN_CMD 0x9E | ||
26 | #define CFFPS_CCIN_CMD 0xBD | ||
27 | #define CFFPS_FW_CMD_START 0xFA | ||
28 | #define CFFPS_FW_NUM_BYTES 4 | ||
29 | #define CFFPS_SYS_CONFIG_CMD 0xDA | ||
30 | |||
31 | #define CFFPS_INPUT_HISTORY_CMD 0xD6 | ||
32 | #define CFFPS_INPUT_HISTORY_SIZE 100 | ||
33 | |||
17 | /* STATUS_MFR_SPECIFIC bits */ | 34 | /* STATUS_MFR_SPECIFIC bits */ |
18 | #define CFFPS_MFR_FAN_FAULT BIT(0) | 35 | #define CFFPS_MFR_FAN_FAULT BIT(0) |
19 | #define CFFPS_MFR_THERMAL_FAULT BIT(1) | 36 | #define CFFPS_MFR_THERMAL_FAULT BIT(1) |
@@ -24,6 +41,153 @@ | |||
24 | #define CFFPS_MFR_VAUX_FAULT BIT(6) | 41 | #define CFFPS_MFR_VAUX_FAULT BIT(6) |
25 | #define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7) | 42 | #define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7) |
26 | 43 | ||
44 | #define CFFPS_LED_BLINK BIT(0) | ||
45 | #define CFFPS_LED_ON BIT(1) | ||
46 | #define CFFPS_LED_OFF BIT(2) | ||
47 | #define CFFPS_BLINK_RATE_MS 250 | ||
48 | |||
49 | enum { | ||
50 | CFFPS_DEBUGFS_INPUT_HISTORY = 0, | ||
51 | CFFPS_DEBUGFS_FRU, | ||
52 | CFFPS_DEBUGFS_PN, | ||
53 | CFFPS_DEBUGFS_SN, | ||
54 | CFFPS_DEBUGFS_CCIN, | ||
55 | CFFPS_DEBUGFS_FW, | ||
56 | CFFPS_DEBUGFS_NUM_ENTRIES | ||
57 | }; | ||
58 | |||
59 | struct ibm_cffps_input_history { | ||
60 | struct mutex update_lock; | ||
61 | unsigned long last_update; | ||
62 | |||
63 | u8 byte_count; | ||
64 | u8 data[CFFPS_INPUT_HISTORY_SIZE]; | ||
65 | }; | ||
66 | |||
67 | struct ibm_cffps { | ||
68 | struct i2c_client *client; | ||
69 | |||
70 | struct ibm_cffps_input_history input_history; | ||
71 | |||
72 | int debugfs_entries[CFFPS_DEBUGFS_NUM_ENTRIES]; | ||
73 | |||
74 | char led_name[32]; | ||
75 | u8 led_state; | ||
76 | struct led_classdev led; | ||
77 | }; | ||
78 | |||
79 | #define to_psu(x, y) container_of((x), struct ibm_cffps, debugfs_entries[(y)]) | ||
80 | |||
81 | static ssize_t ibm_cffps_read_input_history(struct ibm_cffps *psu, | ||
82 | char __user *buf, size_t count, | ||
83 | loff_t *ppos) | ||
84 | { | ||
85 | int rc; | ||
86 | u8 msgbuf0[1] = { CFFPS_INPUT_HISTORY_CMD }; | ||
87 | u8 msgbuf1[CFFPS_INPUT_HISTORY_SIZE + 1] = { 0 }; | ||
88 | struct i2c_msg msg[2] = { | ||
89 | { | ||
90 | .addr = psu->client->addr, | ||
91 | .flags = psu->client->flags, | ||
92 | .len = 1, | ||
93 | .buf = msgbuf0, | ||
94 | }, { | ||
95 | .addr = psu->client->addr, | ||
96 | .flags = psu->client->flags | I2C_M_RD, | ||
97 | .len = CFFPS_INPUT_HISTORY_SIZE + 1, | ||
98 | .buf = msgbuf1, | ||
99 | }, | ||
100 | }; | ||
101 | |||
102 | if (!*ppos) { | ||
103 | mutex_lock(&psu->input_history.update_lock); | ||
104 | if (time_after(jiffies, psu->input_history.last_update + HZ)) { | ||
105 | /* | ||
106 | * Use a raw i2c transfer, since we need more bytes | ||
107 | * than Linux I2C supports through smbus xfr (only 32). | ||
108 | */ | ||
109 | rc = i2c_transfer(psu->client->adapter, msg, 2); | ||
110 | if (rc < 0) { | ||
111 | mutex_unlock(&psu->input_history.update_lock); | ||
112 | return rc; | ||
113 | } | ||
114 | |||
115 | psu->input_history.byte_count = msgbuf1[0]; | ||
116 | memcpy(psu->input_history.data, &msgbuf1[1], | ||
117 | CFFPS_INPUT_HISTORY_SIZE); | ||
118 | psu->input_history.last_update = jiffies; | ||
119 | } | ||
120 | |||
121 | mutex_unlock(&psu->input_history.update_lock); | ||
122 | } | ||
123 | |||
124 | return simple_read_from_buffer(buf, count, ppos, | ||
125 | psu->input_history.data, | ||
126 | psu->input_history.byte_count); | ||
127 | } | ||
128 | |||
129 | static ssize_t ibm_cffps_debugfs_op(struct file *file, char __user *buf, | ||
130 | size_t count, loff_t *ppos) | ||
131 | { | ||
132 | u8 cmd; | ||
133 | int i, rc; | ||
134 | int *idxp = file->private_data; | ||
135 | int idx = *idxp; | ||
136 | struct ibm_cffps *psu = to_psu(idxp, idx); | ||
137 | char data[I2C_SMBUS_BLOCK_MAX] = { 0 }; | ||
138 | |||
139 | switch (idx) { | ||
140 | case CFFPS_DEBUGFS_INPUT_HISTORY: | ||
141 | return ibm_cffps_read_input_history(psu, buf, count, ppos); | ||
142 | case CFFPS_DEBUGFS_FRU: | ||
143 | cmd = CFFPS_FRU_CMD; | ||
144 | break; | ||
145 | case CFFPS_DEBUGFS_PN: | ||
146 | cmd = CFFPS_PN_CMD; | ||
147 | break; | ||
148 | case CFFPS_DEBUGFS_SN: | ||
149 | cmd = CFFPS_SN_CMD; | ||
150 | break; | ||
151 | case CFFPS_DEBUGFS_CCIN: | ||
152 | rc = i2c_smbus_read_word_swapped(psu->client, CFFPS_CCIN_CMD); | ||
153 | if (rc < 0) | ||
154 | return rc; | ||
155 | |||
156 | rc = snprintf(data, 5, "%04X", rc); | ||
157 | goto done; | ||
158 | case CFFPS_DEBUGFS_FW: | ||
159 | for (i = 0; i < CFFPS_FW_NUM_BYTES; ++i) { | ||
160 | rc = i2c_smbus_read_byte_data(psu->client, | ||
161 | CFFPS_FW_CMD_START + i); | ||
162 | if (rc < 0) | ||
163 | return rc; | ||
164 | |||
165 | snprintf(&data[i * 2], 3, "%02X", rc); | ||
166 | } | ||
167 | |||
168 | rc = i * 2; | ||
169 | goto done; | ||
170 | default: | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | |||
174 | rc = i2c_smbus_read_block_data(psu->client, cmd, data); | ||
175 | if (rc < 0) | ||
176 | return rc; | ||
177 | |||
178 | done: | ||
179 | data[rc] = '\n'; | ||
180 | rc += 2; | ||
181 | |||
182 | return simple_read_from_buffer(buf, count, ppos, data, rc); | ||
183 | } | ||
184 | |||
185 | static const struct file_operations ibm_cffps_fops = { | ||
186 | .llseek = noop_llseek, | ||
187 | .read = ibm_cffps_debugfs_op, | ||
188 | .open = simple_open, | ||
189 | }; | ||
190 | |||
27 | static int ibm_cffps_read_byte_data(struct i2c_client *client, int page, | 191 | static int ibm_cffps_read_byte_data(struct i2c_client *client, int page, |
28 | int reg) | 192 | int reg) |
29 | { | 193 | { |
@@ -105,6 +269,69 @@ static int ibm_cffps_read_word_data(struct i2c_client *client, int page, | |||
105 | return rc; | 269 | return rc; |
106 | } | 270 | } |
107 | 271 | ||
272 | static void ibm_cffps_led_brightness_set(struct led_classdev *led_cdev, | ||
273 | enum led_brightness brightness) | ||
274 | { | ||
275 | int rc; | ||
276 | struct ibm_cffps *psu = container_of(led_cdev, struct ibm_cffps, led); | ||
277 | |||
278 | if (brightness == LED_OFF) { | ||
279 | psu->led_state = CFFPS_LED_OFF; | ||
280 | } else { | ||
281 | brightness = LED_FULL; | ||
282 | if (psu->led_state != CFFPS_LED_BLINK) | ||
283 | psu->led_state = CFFPS_LED_ON; | ||
284 | } | ||
285 | |||
286 | rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD, | ||
287 | psu->led_state); | ||
288 | if (rc < 0) | ||
289 | return; | ||
290 | |||
291 | led_cdev->brightness = brightness; | ||
292 | } | ||
293 | |||
294 | static int ibm_cffps_led_blink_set(struct led_classdev *led_cdev, | ||
295 | unsigned long *delay_on, | ||
296 | unsigned long *delay_off) | ||
297 | { | ||
298 | int rc; | ||
299 | struct ibm_cffps *psu = container_of(led_cdev, struct ibm_cffps, led); | ||
300 | |||
301 | psu->led_state = CFFPS_LED_BLINK; | ||
302 | |||
303 | if (led_cdev->brightness == LED_OFF) | ||
304 | return 0; | ||
305 | |||
306 | rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD, | ||
307 | CFFPS_LED_BLINK); | ||
308 | if (rc < 0) | ||
309 | return rc; | ||
310 | |||
311 | *delay_on = CFFPS_BLINK_RATE_MS; | ||
312 | *delay_off = CFFPS_BLINK_RATE_MS; | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static void ibm_cffps_create_led_class(struct ibm_cffps *psu) | ||
318 | { | ||
319 | int rc; | ||
320 | struct i2c_client *client = psu->client; | ||
321 | struct device *dev = &client->dev; | ||
322 | |||
323 | snprintf(psu->led_name, sizeof(psu->led_name), "%s-%02x", client->name, | ||
324 | client->addr); | ||
325 | psu->led.name = psu->led_name; | ||
326 | psu->led.max_brightness = LED_FULL; | ||
327 | psu->led.brightness_set = ibm_cffps_led_brightness_set; | ||
328 | psu->led.blink_set = ibm_cffps_led_blink_set; | ||
329 | |||
330 | rc = devm_led_classdev_register(dev, &psu->led); | ||
331 | if (rc) | ||
332 | dev_warn(dev, "failed to register led class: %d\n", rc); | ||
333 | } | ||
334 | |||
108 | static struct pmbus_driver_info ibm_cffps_info = { | 335 | static struct pmbus_driver_info ibm_cffps_info = { |
109 | .pages = 1, | 336 | .pages = 1, |
110 | .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | | 337 | .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | |
@@ -116,10 +343,69 @@ static struct pmbus_driver_info ibm_cffps_info = { | |||
116 | .read_word_data = ibm_cffps_read_word_data, | 343 | .read_word_data = ibm_cffps_read_word_data, |
117 | }; | 344 | }; |
118 | 345 | ||
346 | static struct pmbus_platform_data ibm_cffps_pdata = { | ||
347 | .flags = PMBUS_SKIP_STATUS_CHECK, | ||
348 | }; | ||
349 | |||
119 | static int ibm_cffps_probe(struct i2c_client *client, | 350 | static int ibm_cffps_probe(struct i2c_client *client, |
120 | const struct i2c_device_id *id) | 351 | const struct i2c_device_id *id) |
121 | { | 352 | { |
122 | return pmbus_do_probe(client, id, &ibm_cffps_info); | 353 | int i, rc; |
354 | struct dentry *debugfs; | ||
355 | struct dentry *ibm_cffps_dir; | ||
356 | struct ibm_cffps *psu; | ||
357 | |||
358 | client->dev.platform_data = &ibm_cffps_pdata; | ||
359 | rc = pmbus_do_probe(client, id, &ibm_cffps_info); | ||
360 | if (rc) | ||
361 | return rc; | ||
362 | |||
363 | /* | ||
364 | * Don't fail the probe if there isn't enough memory for leds and | ||
365 | * debugfs. | ||
366 | */ | ||
367 | psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL); | ||
368 | if (!psu) | ||
369 | return 0; | ||
370 | |||
371 | psu->client = client; | ||
372 | mutex_init(&psu->input_history.update_lock); | ||
373 | psu->input_history.last_update = jiffies - HZ; | ||
374 | |||
375 | ibm_cffps_create_led_class(psu); | ||
376 | |||
377 | /* Don't fail the probe if we can't create debugfs */ | ||
378 | debugfs = pmbus_get_debugfs_dir(client); | ||
379 | if (!debugfs) | ||
380 | return 0; | ||
381 | |||
382 | ibm_cffps_dir = debugfs_create_dir(client->name, debugfs); | ||
383 | if (!ibm_cffps_dir) | ||
384 | return 0; | ||
385 | |||
386 | for (i = 0; i < CFFPS_DEBUGFS_NUM_ENTRIES; ++i) | ||
387 | psu->debugfs_entries[i] = i; | ||
388 | |||
389 | debugfs_create_file("input_history", 0444, ibm_cffps_dir, | ||
390 | &psu->debugfs_entries[CFFPS_DEBUGFS_INPUT_HISTORY], | ||
391 | &ibm_cffps_fops); | ||
392 | debugfs_create_file("fru", 0444, ibm_cffps_dir, | ||
393 | &psu->debugfs_entries[CFFPS_DEBUGFS_FRU], | ||
394 | &ibm_cffps_fops); | ||
395 | debugfs_create_file("part_number", 0444, ibm_cffps_dir, | ||
396 | &psu->debugfs_entries[CFFPS_DEBUGFS_PN], | ||
397 | &ibm_cffps_fops); | ||
398 | debugfs_create_file("serial_number", 0444, ibm_cffps_dir, | ||
399 | &psu->debugfs_entries[CFFPS_DEBUGFS_SN], | ||
400 | &ibm_cffps_fops); | ||
401 | debugfs_create_file("ccin", 0444, ibm_cffps_dir, | ||
402 | &psu->debugfs_entries[CFFPS_DEBUGFS_CCIN], | ||
403 | &ibm_cffps_fops); | ||
404 | debugfs_create_file("fw_version", 0444, ibm_cffps_dir, | ||
405 | &psu->debugfs_entries[CFFPS_DEBUGFS_FW], | ||
406 | &ibm_cffps_fops); | ||
407 | |||
408 | return 0; | ||
123 | } | 409 | } |
124 | 410 | ||
125 | static const struct i2c_device_id ibm_cffps_id[] = { | 411 | static const struct i2c_device_id ibm_cffps_id[] = { |
diff --git a/drivers/hwmon/pmbus/ir35221.c b/drivers/hwmon/pmbus/ir35221.c index 8b906b44484b..977315b0fd90 100644 --- a/drivers/hwmon/pmbus/ir35221.c +++ b/drivers/hwmon/pmbus/ir35221.c | |||
@@ -25,168 +25,19 @@ | |||
25 | #define IR35221_MFR_IOUT_VALLEY 0xcb | 25 | #define IR35221_MFR_IOUT_VALLEY 0xcb |
26 | #define IR35221_MFR_TEMP_VALLEY 0xcc | 26 | #define IR35221_MFR_TEMP_VALLEY 0xcc |
27 | 27 | ||
28 | static long ir35221_reg2data(int data, enum pmbus_sensor_classes class) | ||
29 | { | ||
30 | s16 exponent; | ||
31 | s32 mantissa; | ||
32 | long val; | ||
33 | |||
34 | /* We only modify LINEAR11 formats */ | ||
35 | exponent = ((s16)data) >> 11; | ||
36 | mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; | ||
37 | |||
38 | val = mantissa * 1000L; | ||
39 | |||
40 | /* scale result to micro-units for power sensors */ | ||
41 | if (class == PSC_POWER) | ||
42 | val = val * 1000L; | ||
43 | |||
44 | if (exponent >= 0) | ||
45 | val <<= exponent; | ||
46 | else | ||
47 | val >>= -exponent; | ||
48 | |||
49 | return val; | ||
50 | } | ||
51 | |||
52 | #define MAX_MANTISSA (1023 * 1000) | ||
53 | #define MIN_MANTISSA (511 * 1000) | ||
54 | |||
55 | static u16 ir35221_data2reg(long val, enum pmbus_sensor_classes class) | ||
56 | { | ||
57 | s16 exponent = 0, mantissa; | ||
58 | bool negative = false; | ||
59 | |||
60 | if (val == 0) | ||
61 | return 0; | ||
62 | |||
63 | if (val < 0) { | ||
64 | negative = true; | ||
65 | val = -val; | ||
66 | } | ||
67 | |||
68 | /* Power is in uW. Convert to mW before converting. */ | ||
69 | if (class == PSC_POWER) | ||
70 | val = DIV_ROUND_CLOSEST(val, 1000L); | ||
71 | |||
72 | /* Reduce large mantissa until it fits into 10 bit */ | ||
73 | while (val >= MAX_MANTISSA && exponent < 15) { | ||
74 | exponent++; | ||
75 | val >>= 1; | ||
76 | } | ||
77 | /* Increase small mantissa to improve precision */ | ||
78 | while (val < MIN_MANTISSA && exponent > -15) { | ||
79 | exponent--; | ||
80 | val <<= 1; | ||
81 | } | ||
82 | |||
83 | /* Convert mantissa from milli-units to units */ | ||
84 | mantissa = DIV_ROUND_CLOSEST(val, 1000); | ||
85 | |||
86 | /* Ensure that resulting number is within range */ | ||
87 | if (mantissa > 0x3ff) | ||
88 | mantissa = 0x3ff; | ||
89 | |||
90 | /* restore sign */ | ||
91 | if (negative) | ||
92 | mantissa = -mantissa; | ||
93 | |||
94 | /* Convert to 5 bit exponent, 11 bit mantissa */ | ||
95 | return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); | ||
96 | } | ||
97 | |||
98 | static u16 ir35221_scale_result(s16 data, int shift, | ||
99 | enum pmbus_sensor_classes class) | ||
100 | { | ||
101 | long val; | ||
102 | |||
103 | val = ir35221_reg2data(data, class); | ||
104 | |||
105 | if (shift < 0) | ||
106 | val >>= -shift; | ||
107 | else | ||
108 | val <<= shift; | ||
109 | |||
110 | return ir35221_data2reg(val, class); | ||
111 | } | ||
112 | |||
113 | static int ir35221_read_word_data(struct i2c_client *client, int page, int reg) | 28 | static int ir35221_read_word_data(struct i2c_client *client, int page, int reg) |
114 | { | 29 | { |
115 | int ret; | 30 | int ret; |
116 | 31 | ||
117 | switch (reg) { | 32 | switch (reg) { |
118 | case PMBUS_IOUT_OC_FAULT_LIMIT: | ||
119 | case PMBUS_IOUT_OC_WARN_LIMIT: | ||
120 | ret = pmbus_read_word_data(client, page, reg); | ||
121 | if (ret < 0) | ||
122 | break; | ||
123 | ret = ir35221_scale_result(ret, 1, PSC_CURRENT_OUT); | ||
124 | break; | ||
125 | case PMBUS_VIN_OV_FAULT_LIMIT: | ||
126 | case PMBUS_VIN_OV_WARN_LIMIT: | ||
127 | case PMBUS_VIN_UV_WARN_LIMIT: | ||
128 | ret = pmbus_read_word_data(client, page, reg); | ||
129 | ret = ir35221_scale_result(ret, -4, PSC_VOLTAGE_IN); | ||
130 | break; | ||
131 | case PMBUS_IIN_OC_WARN_LIMIT: | ||
132 | ret = pmbus_read_word_data(client, page, reg); | ||
133 | if (ret < 0) | ||
134 | break; | ||
135 | ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN); | ||
136 | break; | ||
137 | case PMBUS_READ_VIN: | ||
138 | ret = pmbus_read_word_data(client, page, PMBUS_READ_VIN); | ||
139 | if (ret < 0) | ||
140 | break; | ||
141 | ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN); | ||
142 | break; | ||
143 | case PMBUS_READ_IIN: | ||
144 | ret = pmbus_read_word_data(client, page, PMBUS_READ_IIN); | ||
145 | if (ret < 0) | ||
146 | break; | ||
147 | if (page == 0) | ||
148 | ret = ir35221_scale_result(ret, -4, PSC_CURRENT_IN); | ||
149 | else | ||
150 | ret = ir35221_scale_result(ret, -5, PSC_CURRENT_IN); | ||
151 | break; | ||
152 | case PMBUS_READ_POUT: | ||
153 | ret = pmbus_read_word_data(client, page, PMBUS_READ_POUT); | ||
154 | if (ret < 0) | ||
155 | break; | ||
156 | ret = ir35221_scale_result(ret, -1, PSC_POWER); | ||
157 | break; | ||
158 | case PMBUS_READ_PIN: | ||
159 | ret = pmbus_read_word_data(client, page, PMBUS_READ_PIN); | ||
160 | if (ret < 0) | ||
161 | break; | ||
162 | ret = ir35221_scale_result(ret, -1, PSC_POWER); | ||
163 | break; | ||
164 | case PMBUS_READ_IOUT: | ||
165 | ret = pmbus_read_word_data(client, page, PMBUS_READ_IOUT); | ||
166 | if (ret < 0) | ||
167 | break; | ||
168 | if (page == 0) | ||
169 | ret = ir35221_scale_result(ret, -1, PSC_CURRENT_OUT); | ||
170 | else | ||
171 | ret = ir35221_scale_result(ret, -2, PSC_CURRENT_OUT); | ||
172 | break; | ||
173 | case PMBUS_VIRT_READ_VIN_MAX: | 33 | case PMBUS_VIRT_READ_VIN_MAX: |
174 | ret = pmbus_read_word_data(client, page, IR35221_MFR_VIN_PEAK); | 34 | ret = pmbus_read_word_data(client, page, IR35221_MFR_VIN_PEAK); |
175 | if (ret < 0) | ||
176 | break; | ||
177 | ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN); | ||
178 | break; | 35 | break; |
179 | case PMBUS_VIRT_READ_VOUT_MAX: | 36 | case PMBUS_VIRT_READ_VOUT_MAX: |
180 | ret = pmbus_read_word_data(client, page, IR35221_MFR_VOUT_PEAK); | 37 | ret = pmbus_read_word_data(client, page, IR35221_MFR_VOUT_PEAK); |
181 | break; | 38 | break; |
182 | case PMBUS_VIRT_READ_IOUT_MAX: | 39 | case PMBUS_VIRT_READ_IOUT_MAX: |
183 | ret = pmbus_read_word_data(client, page, IR35221_MFR_IOUT_PEAK); | 40 | ret = pmbus_read_word_data(client, page, IR35221_MFR_IOUT_PEAK); |
184 | if (ret < 0) | ||
185 | break; | ||
186 | if (page == 0) | ||
187 | ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN); | ||
188 | else | ||
189 | ret = ir35221_scale_result(ret, -2, PSC_CURRENT_IN); | ||
190 | break; | 41 | break; |
191 | case PMBUS_VIRT_READ_TEMP_MAX: | 42 | case PMBUS_VIRT_READ_TEMP_MAX: |
192 | ret = pmbus_read_word_data(client, page, IR35221_MFR_TEMP_PEAK); | 43 | ret = pmbus_read_word_data(client, page, IR35221_MFR_TEMP_PEAK); |
@@ -194,9 +45,6 @@ static int ir35221_read_word_data(struct i2c_client *client, int page, int reg) | |||
194 | case PMBUS_VIRT_READ_VIN_MIN: | 45 | case PMBUS_VIRT_READ_VIN_MIN: |
195 | ret = pmbus_read_word_data(client, page, | 46 | ret = pmbus_read_word_data(client, page, |
196 | IR35221_MFR_VIN_VALLEY); | 47 | IR35221_MFR_VIN_VALLEY); |
197 | if (ret < 0) | ||
198 | break; | ||
199 | ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN); | ||
200 | break; | 48 | break; |
201 | case PMBUS_VIRT_READ_VOUT_MIN: | 49 | case PMBUS_VIRT_READ_VOUT_MIN: |
202 | ret = pmbus_read_word_data(client, page, | 50 | ret = pmbus_read_word_data(client, page, |
@@ -205,12 +53,6 @@ static int ir35221_read_word_data(struct i2c_client *client, int page, int reg) | |||
205 | case PMBUS_VIRT_READ_IOUT_MIN: | 53 | case PMBUS_VIRT_READ_IOUT_MIN: |
206 | ret = pmbus_read_word_data(client, page, | 54 | ret = pmbus_read_word_data(client, page, |
207 | IR35221_MFR_IOUT_VALLEY); | 55 | IR35221_MFR_IOUT_VALLEY); |
208 | if (ret < 0) | ||
209 | break; | ||
210 | if (page == 0) | ||
211 | ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN); | ||
212 | else | ||
213 | ret = ir35221_scale_result(ret, -2, PSC_CURRENT_IN); | ||
214 | break; | 56 | break; |
215 | case PMBUS_VIRT_READ_TEMP_MIN: | 57 | case PMBUS_VIRT_READ_TEMP_MIN: |
216 | ret = pmbus_read_word_data(client, page, | 58 | ret = pmbus_read_word_data(client, page, |
@@ -224,36 +66,6 @@ static int ir35221_read_word_data(struct i2c_client *client, int page, int reg) | |||
224 | return ret; | 66 | return ret; |
225 | } | 67 | } |
226 | 68 | ||
227 | static int ir35221_write_word_data(struct i2c_client *client, int page, int reg, | ||
228 | u16 word) | ||
229 | { | ||
230 | int ret; | ||
231 | u16 val; | ||
232 | |||
233 | switch (reg) { | ||
234 | case PMBUS_IOUT_OC_FAULT_LIMIT: | ||
235 | case PMBUS_IOUT_OC_WARN_LIMIT: | ||
236 | val = ir35221_scale_result(word, -1, PSC_CURRENT_OUT); | ||
237 | ret = pmbus_write_word_data(client, page, reg, val); | ||
238 | break; | ||
239 | case PMBUS_VIN_OV_FAULT_LIMIT: | ||
240 | case PMBUS_VIN_OV_WARN_LIMIT: | ||
241 | case PMBUS_VIN_UV_WARN_LIMIT: | ||
242 | val = ir35221_scale_result(word, 4, PSC_VOLTAGE_IN); | ||
243 | ret = pmbus_write_word_data(client, page, reg, val); | ||
244 | break; | ||
245 | case PMBUS_IIN_OC_WARN_LIMIT: | ||
246 | val = ir35221_scale_result(word, 1, PSC_CURRENT_IN); | ||
247 | ret = pmbus_write_word_data(client, page, reg, val); | ||
248 | break; | ||
249 | default: | ||
250 | ret = -ENODATA; | ||
251 | break; | ||
252 | } | ||
253 | |||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static int ir35221_probe(struct i2c_client *client, | 69 | static int ir35221_probe(struct i2c_client *client, |
258 | const struct i2c_device_id *id) | 70 | const struct i2c_device_id *id) |
259 | { | 71 | { |
@@ -292,7 +104,6 @@ static int ir35221_probe(struct i2c_client *client, | |||
292 | if (!info) | 104 | if (!info) |
293 | return -ENOMEM; | 105 | return -ENOMEM; |
294 | 106 | ||
295 | info->write_word_data = ir35221_write_word_data; | ||
296 | info->read_word_data = ir35221_read_word_data; | 107 | info->read_word_data = ir35221_read_word_data; |
297 | 108 | ||
298 | info->pages = 2; | 109 | info->pages = 2; |
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 10d17fb8f283..53db78753a0d 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for LM25056 / LM25063 / LM25066 / LM5064 / LM5066 | 2 | * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Ericsson AB. | 4 | * Copyright (c) 2011 Ericsson AB. |
5 | * Copyright (c) 2013 Guenter Roeck | 5 | * Copyright (c) 2013 Guenter Roeck |
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include "pmbus.h" | 29 | #include "pmbus.h" |
30 | 30 | ||
31 | enum chips { lm25056, lm25063, lm25066, lm5064, lm5066, lm5066i }; | 31 | enum chips { lm25056, lm25066, lm5064, lm5066, lm5066i }; |
32 | 32 | ||
33 | #define LM25066_READ_VAUX 0xd0 | 33 | #define LM25066_READ_VAUX 0xd0 |
34 | #define LM25066_MFR_READ_IIN 0xd1 | 34 | #define LM25066_MFR_READ_IIN 0xd1 |
@@ -53,11 +53,6 @@ enum chips { lm25056, lm25063, lm25066, lm5064, lm5066, lm5066i }; | |||
53 | #define LM25056_MFR_STS_VAUX_OV_WARN BIT(1) | 53 | #define LM25056_MFR_STS_VAUX_OV_WARN BIT(1) |
54 | #define LM25056_MFR_STS_VAUX_UV_WARN BIT(0) | 54 | #define LM25056_MFR_STS_VAUX_UV_WARN BIT(0) |
55 | 55 | ||
56 | /* LM25063 only */ | ||
57 | |||
58 | #define LM25063_READ_VOUT_MAX 0xe5 | ||
59 | #define LM25063_READ_VOUT_MIN 0xe6 | ||
60 | |||
61 | struct __coeff { | 56 | struct __coeff { |
62 | short m, b, R; | 57 | short m, b, R; |
63 | }; | 58 | }; |
@@ -122,36 +117,6 @@ static struct __coeff lm25066_coeff[6][PSC_NUM_CLASSES + 2] = { | |||
122 | .m = 16, | 117 | .m = 16, |
123 | }, | 118 | }, |
124 | }, | 119 | }, |
125 | [lm25063] = { | ||
126 | [PSC_VOLTAGE_IN] = { | ||
127 | .m = 16000, | ||
128 | .R = -2, | ||
129 | }, | ||
130 | [PSC_VOLTAGE_OUT] = { | ||
131 | .m = 16000, | ||
132 | .R = -2, | ||
133 | }, | ||
134 | [PSC_CURRENT_IN] = { | ||
135 | .m = 10000, | ||
136 | .R = -2, | ||
137 | }, | ||
138 | [PSC_CURRENT_IN_L] = { | ||
139 | .m = 10000, | ||
140 | .R = -2, | ||
141 | }, | ||
142 | [PSC_POWER] = { | ||
143 | .m = 5000, | ||
144 | .R = -3, | ||
145 | }, | ||
146 | [PSC_POWER_L] = { | ||
147 | .m = 5000, | ||
148 | .R = -3, | ||
149 | }, | ||
150 | [PSC_TEMPERATURE] = { | ||
151 | .m = 15596, | ||
152 | .R = -3, | ||
153 | }, | ||
154 | }, | ||
155 | [lm5064] = { | 120 | [lm5064] = { |
156 | [PSC_VOLTAGE_IN] = { | 121 | [PSC_VOLTAGE_IN] = { |
157 | .m = 4611, | 122 | .m = 4611, |
@@ -272,10 +237,6 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
272 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ | 237 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ |
273 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); | 238 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
274 | break; | 239 | break; |
275 | case lm25063: | ||
276 | /* VIN: 6.25 mV VAUX: 200.0 uV LSB */ | ||
277 | ret = DIV_ROUND_CLOSEST(ret * 20, 625); | ||
278 | break; | ||
279 | case lm25066: | 240 | case lm25066: |
280 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ | 241 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ |
281 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); | 242 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); |
@@ -330,24 +291,6 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
330 | return ret; | 291 | return ret; |
331 | } | 292 | } |
332 | 293 | ||
333 | static int lm25063_read_word_data(struct i2c_client *client, int page, int reg) | ||
334 | { | ||
335 | int ret; | ||
336 | |||
337 | switch (reg) { | ||
338 | case PMBUS_VIRT_READ_VOUT_MAX: | ||
339 | ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MAX); | ||
340 | break; | ||
341 | case PMBUS_VIRT_READ_VOUT_MIN: | ||
342 | ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MIN); | ||
343 | break; | ||
344 | default: | ||
345 | ret = lm25066_read_word_data(client, page, reg); | ||
346 | break; | ||
347 | } | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) | 294 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) |
352 | { | 295 | { |
353 | int ret; | 296 | int ret; |
@@ -502,11 +445,6 @@ static int lm25066_probe(struct i2c_client *client, | |||
502 | info->read_word_data = lm25056_read_word_data; | 445 | info->read_word_data = lm25056_read_word_data; |
503 | info->read_byte_data = lm25056_read_byte_data; | 446 | info->read_byte_data = lm25056_read_byte_data; |
504 | data->rlimit = 0x0fff; | 447 | data->rlimit = 0x0fff; |
505 | } else if (data->id == lm25063) { | ||
506 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
507 | | PMBUS_HAVE_POUT; | ||
508 | info->read_word_data = lm25063_read_word_data; | ||
509 | data->rlimit = 0xffff; | ||
510 | } else { | 448 | } else { |
511 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | 449 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; |
512 | info->read_word_data = lm25066_read_word_data; | 450 | info->read_word_data = lm25066_read_word_data; |
@@ -543,7 +481,6 @@ static int lm25066_probe(struct i2c_client *client, | |||
543 | 481 | ||
544 | static const struct i2c_device_id lm25066_id[] = { | 482 | static const struct i2c_device_id lm25066_id[] = { |
545 | {"lm25056", lm25056}, | 483 | {"lm25056", lm25056}, |
546 | {"lm25063", lm25063}, | ||
547 | {"lm25066", lm25066}, | 484 | {"lm25066", lm25066}, |
548 | {"lm5064", lm5064}, | 485 | {"lm5064", lm5064}, |
549 | {"lm5066", lm5066}, | 486 | {"lm5066", lm5066}, |
diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c index 9313849d5160..c9dc8799b5e1 100644 --- a/drivers/hwmon/pmbus/max31785.c +++ b/drivers/hwmon/pmbus/max31785.c | |||
@@ -16,12 +16,231 @@ | |||
16 | 16 | ||
17 | enum max31785_regs { | 17 | enum max31785_regs { |
18 | MFR_REVISION = 0x9b, | 18 | MFR_REVISION = 0x9b, |
19 | MFR_FAN_CONFIG = 0xf1, | ||
19 | }; | 20 | }; |
20 | 21 | ||
22 | #define MAX31785 0x3030 | ||
23 | #define MAX31785A 0x3040 | ||
24 | |||
25 | #define MFR_FAN_CONFIG_DUAL_TACH BIT(12) | ||
26 | |||
21 | #define MAX31785_NR_PAGES 23 | 27 | #define MAX31785_NR_PAGES 23 |
28 | #define MAX31785_NR_FAN_PAGES 6 | ||
29 | |||
30 | static int max31785_read_byte_data(struct i2c_client *client, int page, | ||
31 | int reg) | ||
32 | { | ||
33 | if (page < MAX31785_NR_PAGES) | ||
34 | return -ENODATA; | ||
35 | |||
36 | switch (reg) { | ||
37 | case PMBUS_VOUT_MODE: | ||
38 | return -ENOTSUPP; | ||
39 | case PMBUS_FAN_CONFIG_12: | ||
40 | return pmbus_read_byte_data(client, page - MAX31785_NR_PAGES, | ||
41 | reg); | ||
42 | } | ||
43 | |||
44 | return -ENODATA; | ||
45 | } | ||
46 | |||
47 | static int max31785_write_byte(struct i2c_client *client, int page, u8 value) | ||
48 | { | ||
49 | if (page < MAX31785_NR_PAGES) | ||
50 | return -ENODATA; | ||
51 | |||
52 | return -ENOTSUPP; | ||
53 | } | ||
54 | |||
55 | static int max31785_read_long_data(struct i2c_client *client, int page, | ||
56 | int reg, u32 *data) | ||
57 | { | ||
58 | unsigned char cmdbuf[1]; | ||
59 | unsigned char rspbuf[4]; | ||
60 | int rc; | ||
61 | |||
62 | struct i2c_msg msg[2] = { | ||
63 | { | ||
64 | .addr = client->addr, | ||
65 | .flags = 0, | ||
66 | .len = sizeof(cmdbuf), | ||
67 | .buf = cmdbuf, | ||
68 | }, | ||
69 | { | ||
70 | .addr = client->addr, | ||
71 | .flags = I2C_M_RD, | ||
72 | .len = sizeof(rspbuf), | ||
73 | .buf = rspbuf, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | cmdbuf[0] = reg; | ||
78 | |||
79 | rc = pmbus_set_page(client, page); | ||
80 | if (rc < 0) | ||
81 | return rc; | ||
82 | |||
83 | rc = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); | ||
84 | if (rc < 0) | ||
85 | return rc; | ||
86 | |||
87 | *data = (rspbuf[0] << (0 * 8)) | (rspbuf[1] << (1 * 8)) | | ||
88 | (rspbuf[2] << (2 * 8)) | (rspbuf[3] << (3 * 8)); | ||
89 | |||
90 | return rc; | ||
91 | } | ||
92 | |||
93 | static int max31785_get_pwm(struct i2c_client *client, int page) | ||
94 | { | ||
95 | int rv; | ||
96 | |||
97 | rv = pmbus_get_fan_rate_device(client, page, 0, percent); | ||
98 | if (rv < 0) | ||
99 | return rv; | ||
100 | else if (rv >= 0x8000) | ||
101 | return 0; | ||
102 | else if (rv >= 0x2711) | ||
103 | return 0x2710; | ||
104 | |||
105 | return rv; | ||
106 | } | ||
107 | |||
108 | static int max31785_get_pwm_mode(struct i2c_client *client, int page) | ||
109 | { | ||
110 | int config; | ||
111 | int command; | ||
112 | |||
113 | config = pmbus_read_byte_data(client, page, PMBUS_FAN_CONFIG_12); | ||
114 | if (config < 0) | ||
115 | return config; | ||
116 | |||
117 | command = pmbus_read_word_data(client, page, PMBUS_FAN_COMMAND_1); | ||
118 | if (command < 0) | ||
119 | return command; | ||
120 | |||
121 | if (config & PB_FAN_1_RPM) | ||
122 | return (command >= 0x8000) ? 3 : 2; | ||
123 | |||
124 | if (command >= 0x8000) | ||
125 | return 3; | ||
126 | else if (command >= 0x2711) | ||
127 | return 0; | ||
128 | |||
129 | return 1; | ||
130 | } | ||
131 | |||
132 | static int max31785_read_word_data(struct i2c_client *client, int page, | ||
133 | int reg) | ||
134 | { | ||
135 | u32 val; | ||
136 | int rv; | ||
137 | |||
138 | switch (reg) { | ||
139 | case PMBUS_READ_FAN_SPEED_1: | ||
140 | if (page < MAX31785_NR_PAGES) | ||
141 | return -ENODATA; | ||
142 | |||
143 | rv = max31785_read_long_data(client, page - MAX31785_NR_PAGES, | ||
144 | reg, &val); | ||
145 | if (rv < 0) | ||
146 | return rv; | ||
147 | |||
148 | rv = (val >> 16) & 0xffff; | ||
149 | break; | ||
150 | case PMBUS_FAN_COMMAND_1: | ||
151 | /* | ||
152 | * PMBUS_FAN_COMMAND_x is probed to judge whether or not to | ||
153 | * expose fan control registers. | ||
154 | * | ||
155 | * Don't expose fan_target attribute for virtual pages. | ||
156 | */ | ||
157 | rv = (page >= MAX31785_NR_PAGES) ? -ENOTSUPP : -ENODATA; | ||
158 | break; | ||
159 | case PMBUS_VIRT_PWM_1: | ||
160 | rv = max31785_get_pwm(client, page); | ||
161 | break; | ||
162 | case PMBUS_VIRT_PWM_ENABLE_1: | ||
163 | rv = max31785_get_pwm_mode(client, page); | ||
164 | break; | ||
165 | default: | ||
166 | rv = -ENODATA; | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | return rv; | ||
171 | } | ||
172 | |||
173 | static inline u32 max31785_scale_pwm(u32 sensor_val) | ||
174 | { | ||
175 | /* | ||
176 | * The datasheet describes the accepted value range for manual PWM as | ||
177 | * [0, 0x2710], while the hwmon pwmX sysfs interface accepts values in | ||
178 | * [0, 255]. The MAX31785 uses DIRECT mode to scale the FAN_COMMAND | ||
179 | * registers and in PWM mode the coefficients are m=1, b=0, R=2. The | ||
180 | * important observation here is that 0x2710 == 10000 == 100 * 100. | ||
181 | * | ||
182 | * R=2 (== 10^2 == 100) accounts for scaling the value provided at the | ||
183 | * sysfs interface into the required hardware resolution, but it does | ||
184 | * not yet yield a value that we can write to the device (this initial | ||
185 | * scaling is handled by pmbus_data2reg()). Multiplying by 100 below | ||
186 | * translates the parameter value into the percentage units required by | ||
187 | * PMBus, and then we scale back by 255 as required by the hwmon pwmX | ||
188 | * interface to yield the percentage value at the appropriate | ||
189 | * resolution for hardware. | ||
190 | */ | ||
191 | return (sensor_val * 100) / 255; | ||
192 | } | ||
193 | |||
194 | static int max31785_pwm_enable(struct i2c_client *client, int page, | ||
195 | u16 word) | ||
196 | { | ||
197 | int config = 0; | ||
198 | int rate; | ||
199 | |||
200 | switch (word) { | ||
201 | case 0: | ||
202 | rate = 0x7fff; | ||
203 | break; | ||
204 | case 1: | ||
205 | rate = pmbus_get_fan_rate_cached(client, page, 0, percent); | ||
206 | if (rate < 0) | ||
207 | return rate; | ||
208 | rate = max31785_scale_pwm(rate); | ||
209 | break; | ||
210 | case 2: | ||
211 | config = PB_FAN_1_RPM; | ||
212 | rate = pmbus_get_fan_rate_cached(client, page, 0, rpm); | ||
213 | if (rate < 0) | ||
214 | return rate; | ||
215 | break; | ||
216 | case 3: | ||
217 | rate = 0xffff; | ||
218 | break; | ||
219 | default: | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | return pmbus_update_fan(client, page, 0, config, PB_FAN_1_RPM, rate); | ||
224 | } | ||
225 | |||
226 | static int max31785_write_word_data(struct i2c_client *client, int page, | ||
227 | int reg, u16 word) | ||
228 | { | ||
229 | switch (reg) { | ||
230 | case PMBUS_VIRT_PWM_1: | ||
231 | return pmbus_update_fan(client, page, 0, 0, PB_FAN_1_RPM, | ||
232 | max31785_scale_pwm(word)); | ||
233 | case PMBUS_VIRT_PWM_ENABLE_1: | ||
234 | return max31785_pwm_enable(client, page, word); | ||
235 | default: | ||
236 | break; | ||
237 | } | ||
238 | |||
239 | return -ENODATA; | ||
240 | } | ||
22 | 241 | ||
23 | #define MAX31785_FAN_FUNCS \ | 242 | #define MAX31785_FAN_FUNCS \ |
24 | (PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12) | 243 | (PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | PMBUS_HAVE_PWM12) |
25 | 244 | ||
26 | #define MAX31785_TEMP_FUNCS \ | 245 | #define MAX31785_TEMP_FUNCS \ |
27 | (PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP) | 246 | (PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP) |
@@ -29,14 +248,26 @@ enum max31785_regs { | |||
29 | #define MAX31785_VOUT_FUNCS \ | 248 | #define MAX31785_VOUT_FUNCS \ |
30 | (PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT) | 249 | (PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT) |
31 | 250 | ||
251 | #define MAX37185_NUM_FAN_PAGES 6 | ||
252 | |||
32 | static const struct pmbus_driver_info max31785_info = { | 253 | static const struct pmbus_driver_info max31785_info = { |
33 | .pages = MAX31785_NR_PAGES, | 254 | .pages = MAX31785_NR_PAGES, |
34 | 255 | ||
256 | .write_word_data = max31785_write_word_data, | ||
257 | .read_byte_data = max31785_read_byte_data, | ||
258 | .read_word_data = max31785_read_word_data, | ||
259 | .write_byte = max31785_write_byte, | ||
260 | |||
35 | /* RPM */ | 261 | /* RPM */ |
36 | .format[PSC_FAN] = direct, | 262 | .format[PSC_FAN] = direct, |
37 | .m[PSC_FAN] = 1, | 263 | .m[PSC_FAN] = 1, |
38 | .b[PSC_FAN] = 0, | 264 | .b[PSC_FAN] = 0, |
39 | .R[PSC_FAN] = 0, | 265 | .R[PSC_FAN] = 0, |
266 | /* PWM */ | ||
267 | .format[PSC_PWM] = direct, | ||
268 | .m[PSC_PWM] = 1, | ||
269 | .b[PSC_PWM] = 0, | ||
270 | .R[PSC_PWM] = 2, | ||
40 | .func[0] = MAX31785_FAN_FUNCS, | 271 | .func[0] = MAX31785_FAN_FUNCS, |
41 | .func[1] = MAX31785_FAN_FUNCS, | 272 | .func[1] = MAX31785_FAN_FUNCS, |
42 | .func[2] = MAX31785_FAN_FUNCS, | 273 | .func[2] = MAX31785_FAN_FUNCS, |
@@ -72,13 +303,46 @@ static const struct pmbus_driver_info max31785_info = { | |||
72 | .func[22] = MAX31785_VOUT_FUNCS, | 303 | .func[22] = MAX31785_VOUT_FUNCS, |
73 | }; | 304 | }; |
74 | 305 | ||
306 | static int max31785_configure_dual_tach(struct i2c_client *client, | ||
307 | struct pmbus_driver_info *info) | ||
308 | { | ||
309 | int ret; | ||
310 | int i; | ||
311 | |||
312 | for (i = 0; i < MAX31785_NR_FAN_PAGES; i++) { | ||
313 | ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i); | ||
314 | if (ret < 0) | ||
315 | return ret; | ||
316 | |||
317 | ret = i2c_smbus_read_word_data(client, MFR_FAN_CONFIG); | ||
318 | if (ret < 0) | ||
319 | return ret; | ||
320 | |||
321 | if (ret & MFR_FAN_CONFIG_DUAL_TACH) { | ||
322 | int virtual = MAX31785_NR_PAGES + i; | ||
323 | |||
324 | info->pages = virtual + 1; | ||
325 | info->func[virtual] |= PMBUS_HAVE_FAN12; | ||
326 | info->func[virtual] |= PMBUS_PAGE_VIRTUAL; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
75 | static int max31785_probe(struct i2c_client *client, | 333 | static int max31785_probe(struct i2c_client *client, |
76 | const struct i2c_device_id *id) | 334 | const struct i2c_device_id *id) |
77 | { | 335 | { |
78 | struct device *dev = &client->dev; | 336 | struct device *dev = &client->dev; |
79 | struct pmbus_driver_info *info; | 337 | struct pmbus_driver_info *info; |
338 | bool dual_tach = false; | ||
80 | s64 ret; | 339 | s64 ret; |
81 | 340 | ||
341 | if (!i2c_check_functionality(client->adapter, | ||
342 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
343 | I2C_FUNC_SMBUS_WORD_DATA)) | ||
344 | return -ENODEV; | ||
345 | |||
82 | info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); | 346 | info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); |
83 | if (!info) | 347 | if (!info) |
84 | return -ENOMEM; | 348 | return -ENOMEM; |
@@ -89,6 +353,25 @@ static int max31785_probe(struct i2c_client *client, | |||
89 | if (ret < 0) | 353 | if (ret < 0) |
90 | return ret; | 354 | return ret; |
91 | 355 | ||
356 | ret = i2c_smbus_read_word_data(client, MFR_REVISION); | ||
357 | if (ret < 0) | ||
358 | return ret; | ||
359 | |||
360 | if (ret == MAX31785A) { | ||
361 | dual_tach = true; | ||
362 | } else if (ret == MAX31785) { | ||
363 | if (!strcmp("max31785a", id->name)) | ||
364 | dev_warn(dev, "Expected max3175a, found max31785: cannot provide secondary tachometer readings\n"); | ||
365 | } else { | ||
366 | return -ENODEV; | ||
367 | } | ||
368 | |||
369 | if (dual_tach) { | ||
370 | ret = max31785_configure_dual_tach(client, info); | ||
371 | if (ret < 0) | ||
372 | return ret; | ||
373 | } | ||
374 | |||
92 | return pmbus_do_probe(client, id, info); | 375 | return pmbus_do_probe(client, id, info); |
93 | } | 376 | } |
94 | 377 | ||
@@ -100,9 +383,18 @@ static const struct i2c_device_id max31785_id[] = { | |||
100 | 383 | ||
101 | MODULE_DEVICE_TABLE(i2c, max31785_id); | 384 | MODULE_DEVICE_TABLE(i2c, max31785_id); |
102 | 385 | ||
386 | static const struct of_device_id max31785_of_match[] = { | ||
387 | { .compatible = "maxim,max31785" }, | ||
388 | { .compatible = "maxim,max31785a" }, | ||
389 | { }, | ||
390 | }; | ||
391 | |||
392 | MODULE_DEVICE_TABLE(of, max31785_of_match); | ||
393 | |||
103 | static struct i2c_driver max31785_driver = { | 394 | static struct i2c_driver max31785_driver = { |
104 | .driver = { | 395 | .driver = { |
105 | .name = "max31785", | 396 | .name = "max31785", |
397 | .of_match_table = max31785_of_match, | ||
106 | }, | 398 | }, |
107 | .probe = max31785_probe, | 399 | .probe = max31785_probe, |
108 | .remove = pmbus_do_remove, | 400 | .remove = pmbus_do_remove, |
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index fa613bd209e3..1d24397d36ec 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h | |||
@@ -190,6 +190,33 @@ enum pmbus_regs { | |||
190 | PMBUS_VIRT_VMON_UV_FAULT_LIMIT, | 190 | PMBUS_VIRT_VMON_UV_FAULT_LIMIT, |
191 | PMBUS_VIRT_VMON_OV_FAULT_LIMIT, | 191 | PMBUS_VIRT_VMON_OV_FAULT_LIMIT, |
192 | PMBUS_VIRT_STATUS_VMON, | 192 | PMBUS_VIRT_STATUS_VMON, |
193 | |||
194 | /* | ||
195 | * RPM and PWM Fan control | ||
196 | * | ||
197 | * Drivers wanting to expose PWM control must define the behaviour of | ||
198 | * PMBUS_VIRT_PWM_[1-4] and PMBUS_VIRT_PWM_ENABLE_[1-4] in the | ||
199 | * {read,write}_word_data callback. | ||
200 | * | ||
201 | * pmbus core provides a default implementation for | ||
202 | * PMBUS_VIRT_FAN_TARGET_[1-4]. | ||
203 | * | ||
204 | * TARGET, PWM and PWM_ENABLE members must be defined sequentially; | ||
205 | * pmbus core uses the difference between the provided register and | ||
206 | * it's _1 counterpart to calculate the FAN/PWM ID. | ||
207 | */ | ||
208 | PMBUS_VIRT_FAN_TARGET_1, | ||
209 | PMBUS_VIRT_FAN_TARGET_2, | ||
210 | PMBUS_VIRT_FAN_TARGET_3, | ||
211 | PMBUS_VIRT_FAN_TARGET_4, | ||
212 | PMBUS_VIRT_PWM_1, | ||
213 | PMBUS_VIRT_PWM_2, | ||
214 | PMBUS_VIRT_PWM_3, | ||
215 | PMBUS_VIRT_PWM_4, | ||
216 | PMBUS_VIRT_PWM_ENABLE_1, | ||
217 | PMBUS_VIRT_PWM_ENABLE_2, | ||
218 | PMBUS_VIRT_PWM_ENABLE_3, | ||
219 | PMBUS_VIRT_PWM_ENABLE_4, | ||
193 | }; | 220 | }; |
194 | 221 | ||
195 | /* | 222 | /* |
@@ -223,6 +250,8 @@ enum pmbus_regs { | |||
223 | #define PB_FAN_1_RPM BIT(6) | 250 | #define PB_FAN_1_RPM BIT(6) |
224 | #define PB_FAN_1_INSTALLED BIT(7) | 251 | #define PB_FAN_1_INSTALLED BIT(7) |
225 | 252 | ||
253 | enum pmbus_fan_mode { percent = 0, rpm }; | ||
254 | |||
226 | /* | 255 | /* |
227 | * STATUS_BYTE, STATUS_WORD (lower) | 256 | * STATUS_BYTE, STATUS_WORD (lower) |
228 | */ | 257 | */ |
@@ -313,6 +342,7 @@ enum pmbus_sensor_classes { | |||
313 | PSC_POWER, | 342 | PSC_POWER, |
314 | PSC_TEMPERATURE, | 343 | PSC_TEMPERATURE, |
315 | PSC_FAN, | 344 | PSC_FAN, |
345 | PSC_PWM, | ||
316 | PSC_NUM_CLASSES /* Number of power sensor classes */ | 346 | PSC_NUM_CLASSES /* Number of power sensor classes */ |
317 | }; | 347 | }; |
318 | 348 | ||
@@ -339,6 +369,10 @@ enum pmbus_sensor_classes { | |||
339 | #define PMBUS_HAVE_STATUS_FAN34 BIT(17) | 369 | #define PMBUS_HAVE_STATUS_FAN34 BIT(17) |
340 | #define PMBUS_HAVE_VMON BIT(18) | 370 | #define PMBUS_HAVE_VMON BIT(18) |
341 | #define PMBUS_HAVE_STATUS_VMON BIT(19) | 371 | #define PMBUS_HAVE_STATUS_VMON BIT(19) |
372 | #define PMBUS_HAVE_PWM12 BIT(20) | ||
373 | #define PMBUS_HAVE_PWM34 BIT(21) | ||
374 | |||
375 | #define PMBUS_PAGE_VIRTUAL BIT(31) | ||
342 | 376 | ||
343 | enum pmbus_data_format { linear = 0, direct, vid }; | 377 | enum pmbus_data_format { linear = 0, direct, vid }; |
344 | enum vrm_version { vr11 = 0, vr12, vr13 }; | 378 | enum vrm_version { vr11 = 0, vr12, vr13 }; |
@@ -421,5 +455,12 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | |||
421 | int pmbus_do_remove(struct i2c_client *client); | 455 | int pmbus_do_remove(struct i2c_client *client); |
422 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client | 456 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client |
423 | *client); | 457 | *client); |
458 | int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, | ||
459 | enum pmbus_fan_mode mode); | ||
460 | int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, | ||
461 | enum pmbus_fan_mode mode); | ||
462 | int pmbus_update_fan(struct i2c_client *client, int page, int id, | ||
463 | u8 config, u8 mask, u16 command); | ||
464 | struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client); | ||
424 | 465 | ||
425 | #endif /* PMBUS_H */ | 466 | #endif /* PMBUS_H */ |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index a139940cd991..f7c47d7994e7 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -65,6 +65,7 @@ struct pmbus_sensor { | |||
65 | u16 reg; /* register */ | 65 | u16 reg; /* register */ |
66 | enum pmbus_sensor_classes class; /* sensor class */ | 66 | enum pmbus_sensor_classes class; /* sensor class */ |
67 | bool update; /* runtime sensor update needed */ | 67 | bool update; /* runtime sensor update needed */ |
68 | bool convert; /* Whether or not to apply linear/vid/direct */ | ||
68 | int data; /* Sensor data. | 69 | int data; /* Sensor data. |
69 | Negative if there was a read error */ | 70 | Negative if there was a read error */ |
70 | }; | 71 | }; |
@@ -129,6 +130,27 @@ struct pmbus_debugfs_entry { | |||
129 | u8 reg; | 130 | u8 reg; |
130 | }; | 131 | }; |
131 | 132 | ||
133 | static const int pmbus_fan_rpm_mask[] = { | ||
134 | PB_FAN_1_RPM, | ||
135 | PB_FAN_2_RPM, | ||
136 | PB_FAN_1_RPM, | ||
137 | PB_FAN_2_RPM, | ||
138 | }; | ||
139 | |||
140 | static const int pmbus_fan_config_registers[] = { | ||
141 | PMBUS_FAN_CONFIG_12, | ||
142 | PMBUS_FAN_CONFIG_12, | ||
143 | PMBUS_FAN_CONFIG_34, | ||
144 | PMBUS_FAN_CONFIG_34 | ||
145 | }; | ||
146 | |||
147 | static const int pmbus_fan_command_registers[] = { | ||
148 | PMBUS_FAN_COMMAND_1, | ||
149 | PMBUS_FAN_COMMAND_2, | ||
150 | PMBUS_FAN_COMMAND_3, | ||
151 | PMBUS_FAN_COMMAND_4, | ||
152 | }; | ||
153 | |||
132 | void pmbus_clear_cache(struct i2c_client *client) | 154 | void pmbus_clear_cache(struct i2c_client *client) |
133 | { | 155 | { |
134 | struct pmbus_data *data = i2c_get_clientdata(client); | 156 | struct pmbus_data *data = i2c_get_clientdata(client); |
@@ -140,18 +162,27 @@ EXPORT_SYMBOL_GPL(pmbus_clear_cache); | |||
140 | int pmbus_set_page(struct i2c_client *client, int page) | 162 | int pmbus_set_page(struct i2c_client *client, int page) |
141 | { | 163 | { |
142 | struct pmbus_data *data = i2c_get_clientdata(client); | 164 | struct pmbus_data *data = i2c_get_clientdata(client); |
143 | int rv = 0; | 165 | int rv; |
144 | int newpage; | ||
145 | 166 | ||
146 | if (page >= 0 && page != data->currpage) { | 167 | if (page < 0 || page == data->currpage) |
168 | return 0; | ||
169 | |||
170 | if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL)) { | ||
147 | rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); | 171 | rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); |
148 | newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); | 172 | if (rv < 0) |
149 | if (newpage != page) | 173 | return rv; |
150 | rv = -EIO; | 174 | |
151 | else | 175 | rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE); |
152 | data->currpage = page; | 176 | if (rv < 0) |
177 | return rv; | ||
178 | |||
179 | if (rv != page) | ||
180 | return -EIO; | ||
153 | } | 181 | } |
154 | return rv; | 182 | |
183 | data->currpage = page; | ||
184 | |||
185 | return 0; | ||
155 | } | 186 | } |
156 | EXPORT_SYMBOL_GPL(pmbus_set_page); | 187 | EXPORT_SYMBOL_GPL(pmbus_set_page); |
157 | 188 | ||
@@ -198,6 +229,28 @@ int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, | |||
198 | } | 229 | } |
199 | EXPORT_SYMBOL_GPL(pmbus_write_word_data); | 230 | EXPORT_SYMBOL_GPL(pmbus_write_word_data); |
200 | 231 | ||
232 | |||
233 | static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg, | ||
234 | u16 word) | ||
235 | { | ||
236 | int bit; | ||
237 | int id; | ||
238 | int rv; | ||
239 | |||
240 | switch (reg) { | ||
241 | case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: | ||
242 | id = reg - PMBUS_VIRT_FAN_TARGET_1; | ||
243 | bit = pmbus_fan_rpm_mask[id]; | ||
244 | rv = pmbus_update_fan(client, page, id, bit, bit, word); | ||
245 | break; | ||
246 | default: | ||
247 | rv = -ENXIO; | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | return rv; | ||
252 | } | ||
253 | |||
201 | /* | 254 | /* |
202 | * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if | 255 | * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if |
203 | * a device specific mapping function exists and calls it if necessary. | 256 | * a device specific mapping function exists and calls it if necessary. |
@@ -214,11 +267,38 @@ static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, | |||
214 | if (status != -ENODATA) | 267 | if (status != -ENODATA) |
215 | return status; | 268 | return status; |
216 | } | 269 | } |
270 | |||
217 | if (reg >= PMBUS_VIRT_BASE) | 271 | if (reg >= PMBUS_VIRT_BASE) |
218 | return -ENXIO; | 272 | return pmbus_write_virt_reg(client, page, reg, word); |
273 | |||
219 | return pmbus_write_word_data(client, page, reg, word); | 274 | return pmbus_write_word_data(client, page, reg, word); |
220 | } | 275 | } |
221 | 276 | ||
277 | int pmbus_update_fan(struct i2c_client *client, int page, int id, | ||
278 | u8 config, u8 mask, u16 command) | ||
279 | { | ||
280 | int from; | ||
281 | int rv; | ||
282 | u8 to; | ||
283 | |||
284 | from = pmbus_read_byte_data(client, page, | ||
285 | pmbus_fan_config_registers[id]); | ||
286 | if (from < 0) | ||
287 | return from; | ||
288 | |||
289 | to = (from & ~mask) | (config & mask); | ||
290 | if (to != from) { | ||
291 | rv = pmbus_write_byte_data(client, page, | ||
292 | pmbus_fan_config_registers[id], to); | ||
293 | if (rv < 0) | ||
294 | return rv; | ||
295 | } | ||
296 | |||
297 | return _pmbus_write_word_data(client, page, | ||
298 | pmbus_fan_command_registers[id], command); | ||
299 | } | ||
300 | EXPORT_SYMBOL_GPL(pmbus_update_fan); | ||
301 | |||
222 | int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg) | 302 | int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg) |
223 | { | 303 | { |
224 | int rv; | 304 | int rv; |
@@ -231,6 +311,24 @@ int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg) | |||
231 | } | 311 | } |
232 | EXPORT_SYMBOL_GPL(pmbus_read_word_data); | 312 | EXPORT_SYMBOL_GPL(pmbus_read_word_data); |
233 | 313 | ||
314 | static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg) | ||
315 | { | ||
316 | int rv; | ||
317 | int id; | ||
318 | |||
319 | switch (reg) { | ||
320 | case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: | ||
321 | id = reg - PMBUS_VIRT_FAN_TARGET_1; | ||
322 | rv = pmbus_get_fan_rate_device(client, page, id, rpm); | ||
323 | break; | ||
324 | default: | ||
325 | rv = -ENXIO; | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | return rv; | ||
330 | } | ||
331 | |||
234 | /* | 332 | /* |
235 | * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if | 333 | * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if |
236 | * a device specific mapping function exists and calls it if necessary. | 334 | * a device specific mapping function exists and calls it if necessary. |
@@ -246,8 +344,10 @@ static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) | |||
246 | if (status != -ENODATA) | 344 | if (status != -ENODATA) |
247 | return status; | 345 | return status; |
248 | } | 346 | } |
347 | |||
249 | if (reg >= PMBUS_VIRT_BASE) | 348 | if (reg >= PMBUS_VIRT_BASE) |
250 | return -ENXIO; | 349 | return pmbus_read_virt_reg(client, page, reg); |
350 | |||
251 | return pmbus_read_word_data(client, page, reg); | 351 | return pmbus_read_word_data(client, page, reg); |
252 | } | 352 | } |
253 | 353 | ||
@@ -312,6 +412,68 @@ static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) | |||
312 | return pmbus_read_byte_data(client, page, reg); | 412 | return pmbus_read_byte_data(client, page, reg); |
313 | } | 413 | } |
314 | 414 | ||
415 | static struct pmbus_sensor *pmbus_find_sensor(struct pmbus_data *data, int page, | ||
416 | int reg) | ||
417 | { | ||
418 | struct pmbus_sensor *sensor; | ||
419 | |||
420 | for (sensor = data->sensors; sensor; sensor = sensor->next) { | ||
421 | if (sensor->page == page && sensor->reg == reg) | ||
422 | return sensor; | ||
423 | } | ||
424 | |||
425 | return ERR_PTR(-EINVAL); | ||
426 | } | ||
427 | |||
428 | static int pmbus_get_fan_rate(struct i2c_client *client, int page, int id, | ||
429 | enum pmbus_fan_mode mode, | ||
430 | bool from_cache) | ||
431 | { | ||
432 | struct pmbus_data *data = i2c_get_clientdata(client); | ||
433 | bool want_rpm, have_rpm; | ||
434 | struct pmbus_sensor *s; | ||
435 | int config; | ||
436 | int reg; | ||
437 | |||
438 | want_rpm = (mode == rpm); | ||
439 | |||
440 | if (from_cache) { | ||
441 | reg = want_rpm ? PMBUS_VIRT_FAN_TARGET_1 : PMBUS_VIRT_PWM_1; | ||
442 | s = pmbus_find_sensor(data, page, reg + id); | ||
443 | if (IS_ERR(s)) | ||
444 | return PTR_ERR(s); | ||
445 | |||
446 | return s->data; | ||
447 | } | ||
448 | |||
449 | config = pmbus_read_byte_data(client, page, | ||
450 | pmbus_fan_config_registers[id]); | ||
451 | if (config < 0) | ||
452 | return config; | ||
453 | |||
454 | have_rpm = !!(config & pmbus_fan_rpm_mask[id]); | ||
455 | if (want_rpm == have_rpm) | ||
456 | return pmbus_read_word_data(client, page, | ||
457 | pmbus_fan_command_registers[id]); | ||
458 | |||
459 | /* Can't sensibly map between RPM and PWM, just return zero */ | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, | ||
464 | enum pmbus_fan_mode mode) | ||
465 | { | ||
466 | return pmbus_get_fan_rate(client, page, id, mode, false); | ||
467 | } | ||
468 | EXPORT_SYMBOL_GPL(pmbus_get_fan_rate_device); | ||
469 | |||
470 | int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, | ||
471 | enum pmbus_fan_mode mode) | ||
472 | { | ||
473 | return pmbus_get_fan_rate(client, page, id, mode, true); | ||
474 | } | ||
475 | EXPORT_SYMBOL_GPL(pmbus_get_fan_rate_cached); | ||
476 | |||
315 | static void pmbus_clear_fault_page(struct i2c_client *client, int page) | 477 | static void pmbus_clear_fault_page(struct i2c_client *client, int page) |
316 | { | 478 | { |
317 | _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); | 479 | _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); |
@@ -513,7 +675,7 @@ static long pmbus_reg2data_direct(struct pmbus_data *data, | |||
513 | /* X = 1/m * (Y * 10^-R - b) */ | 675 | /* X = 1/m * (Y * 10^-R - b) */ |
514 | R = -R; | 676 | R = -R; |
515 | /* scale result to milli-units for everything but fans */ | 677 | /* scale result to milli-units for everything but fans */ |
516 | if (sensor->class != PSC_FAN) { | 678 | if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { |
517 | R += 3; | 679 | R += 3; |
518 | b *= 1000; | 680 | b *= 1000; |
519 | } | 681 | } |
@@ -568,6 +730,9 @@ static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) | |||
568 | { | 730 | { |
569 | long val; | 731 | long val; |
570 | 732 | ||
733 | if (!sensor->convert) | ||
734 | return sensor->data; | ||
735 | |||
571 | switch (data->info->format[sensor->class]) { | 736 | switch (data->info->format[sensor->class]) { |
572 | case direct: | 737 | case direct: |
573 | val = pmbus_reg2data_direct(data, sensor); | 738 | val = pmbus_reg2data_direct(data, sensor); |
@@ -672,7 +837,7 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data, | |||
672 | } | 837 | } |
673 | 838 | ||
674 | /* Calculate Y = (m * X + b) * 10^R */ | 839 | /* Calculate Y = (m * X + b) * 10^R */ |
675 | if (sensor->class != PSC_FAN) { | 840 | if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { |
676 | R -= 3; /* Adjust R and b for data in milli-units */ | 841 | R -= 3; /* Adjust R and b for data in milli-units */ |
677 | b *= 1000; | 842 | b *= 1000; |
678 | } | 843 | } |
@@ -703,6 +868,9 @@ static u16 pmbus_data2reg(struct pmbus_data *data, | |||
703 | { | 868 | { |
704 | u16 regval; | 869 | u16 regval; |
705 | 870 | ||
871 | if (!sensor->convert) | ||
872 | return val; | ||
873 | |||
706 | switch (data->info->format[sensor->class]) { | 874 | switch (data->info->format[sensor->class]) { |
707 | case direct: | 875 | case direct: |
708 | regval = pmbus_data2reg_direct(data, sensor, val); | 876 | regval = pmbus_data2reg_direct(data, sensor, val); |
@@ -915,7 +1083,8 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, | |||
915 | const char *name, const char *type, | 1083 | const char *name, const char *type, |
916 | int seq, int page, int reg, | 1084 | int seq, int page, int reg, |
917 | enum pmbus_sensor_classes class, | 1085 | enum pmbus_sensor_classes class, |
918 | bool update, bool readonly) | 1086 | bool update, bool readonly, |
1087 | bool convert) | ||
919 | { | 1088 | { |
920 | struct pmbus_sensor *sensor; | 1089 | struct pmbus_sensor *sensor; |
921 | struct device_attribute *a; | 1090 | struct device_attribute *a; |
@@ -925,12 +1094,18 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, | |||
925 | return NULL; | 1094 | return NULL; |
926 | a = &sensor->attribute; | 1095 | a = &sensor->attribute; |
927 | 1096 | ||
928 | snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", | 1097 | if (type) |
929 | name, seq, type); | 1098 | snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", |
1099 | name, seq, type); | ||
1100 | else | ||
1101 | snprintf(sensor->name, sizeof(sensor->name), "%s%d", | ||
1102 | name, seq); | ||
1103 | |||
930 | sensor->page = page; | 1104 | sensor->page = page; |
931 | sensor->reg = reg; | 1105 | sensor->reg = reg; |
932 | sensor->class = class; | 1106 | sensor->class = class; |
933 | sensor->update = update; | 1107 | sensor->update = update; |
1108 | sensor->convert = convert; | ||
934 | pmbus_dev_attr_init(a, sensor->name, | 1109 | pmbus_dev_attr_init(a, sensor->name, |
935 | readonly ? S_IRUGO : S_IRUGO | S_IWUSR, | 1110 | readonly ? S_IRUGO : S_IRUGO | S_IWUSR, |
936 | pmbus_show_sensor, pmbus_set_sensor); | 1111 | pmbus_show_sensor, pmbus_set_sensor); |
@@ -1029,7 +1204,7 @@ static int pmbus_add_limit_attrs(struct i2c_client *client, | |||
1029 | curr = pmbus_add_sensor(data, name, l->attr, index, | 1204 | curr = pmbus_add_sensor(data, name, l->attr, index, |
1030 | page, l->reg, attr->class, | 1205 | page, l->reg, attr->class, |
1031 | attr->update || l->update, | 1206 | attr->update || l->update, |
1032 | false); | 1207 | false, true); |
1033 | if (!curr) | 1208 | if (!curr) |
1034 | return -ENOMEM; | 1209 | return -ENOMEM; |
1035 | if (l->sbit && (info->func[page] & attr->sfunc)) { | 1210 | if (l->sbit && (info->func[page] & attr->sfunc)) { |
@@ -1068,7 +1243,7 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, | |||
1068 | return ret; | 1243 | return ret; |
1069 | } | 1244 | } |
1070 | base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, | 1245 | base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, |
1071 | attr->class, true, true); | 1246 | attr->class, true, true, true); |
1072 | if (!base) | 1247 | if (!base) |
1073 | return -ENOMEM; | 1248 | return -ENOMEM; |
1074 | if (attr->sfunc) { | 1249 | if (attr->sfunc) { |
@@ -1592,13 +1767,6 @@ static const int pmbus_fan_registers[] = { | |||
1592 | PMBUS_READ_FAN_SPEED_4 | 1767 | PMBUS_READ_FAN_SPEED_4 |
1593 | }; | 1768 | }; |
1594 | 1769 | ||
1595 | static const int pmbus_fan_config_registers[] = { | ||
1596 | PMBUS_FAN_CONFIG_12, | ||
1597 | PMBUS_FAN_CONFIG_12, | ||
1598 | PMBUS_FAN_CONFIG_34, | ||
1599 | PMBUS_FAN_CONFIG_34 | ||
1600 | }; | ||
1601 | |||
1602 | static const int pmbus_fan_status_registers[] = { | 1770 | static const int pmbus_fan_status_registers[] = { |
1603 | PMBUS_STATUS_FAN_12, | 1771 | PMBUS_STATUS_FAN_12, |
1604 | PMBUS_STATUS_FAN_12, | 1772 | PMBUS_STATUS_FAN_12, |
@@ -1621,6 +1789,42 @@ static const u32 pmbus_fan_status_flags[] = { | |||
1621 | }; | 1789 | }; |
1622 | 1790 | ||
1623 | /* Fans */ | 1791 | /* Fans */ |
1792 | |||
1793 | /* Precondition: FAN_CONFIG_x_y and FAN_COMMAND_x must exist for the fan ID */ | ||
1794 | static int pmbus_add_fan_ctrl(struct i2c_client *client, | ||
1795 | struct pmbus_data *data, int index, int page, int id, | ||
1796 | u8 config) | ||
1797 | { | ||
1798 | struct pmbus_sensor *sensor; | ||
1799 | |||
1800 | sensor = pmbus_add_sensor(data, "fan", "target", index, page, | ||
1801 | PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN, | ||
1802 | false, false, true); | ||
1803 | |||
1804 | if (!sensor) | ||
1805 | return -ENOMEM; | ||
1806 | |||
1807 | if (!((data->info->func[page] & PMBUS_HAVE_PWM12) || | ||
1808 | (data->info->func[page] & PMBUS_HAVE_PWM34))) | ||
1809 | return 0; | ||
1810 | |||
1811 | sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, | ||
1812 | PMBUS_VIRT_PWM_1 + id, PSC_PWM, | ||
1813 | false, false, true); | ||
1814 | |||
1815 | if (!sensor) | ||
1816 | return -ENOMEM; | ||
1817 | |||
1818 | sensor = pmbus_add_sensor(data, "pwm", "enable", index, page, | ||
1819 | PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM, | ||
1820 | true, false, false); | ||
1821 | |||
1822 | if (!sensor) | ||
1823 | return -ENOMEM; | ||
1824 | |||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1624 | static int pmbus_add_fan_attributes(struct i2c_client *client, | 1828 | static int pmbus_add_fan_attributes(struct i2c_client *client, |
1625 | struct pmbus_data *data) | 1829 | struct pmbus_data *data) |
1626 | { | 1830 | { |
@@ -1655,9 +1859,18 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, | |||
1655 | 1859 | ||
1656 | if (pmbus_add_sensor(data, "fan", "input", index, | 1860 | if (pmbus_add_sensor(data, "fan", "input", index, |
1657 | page, pmbus_fan_registers[f], | 1861 | page, pmbus_fan_registers[f], |
1658 | PSC_FAN, true, true) == NULL) | 1862 | PSC_FAN, true, true, true) == NULL) |
1659 | return -ENOMEM; | 1863 | return -ENOMEM; |
1660 | 1864 | ||
1865 | /* Fan control */ | ||
1866 | if (pmbus_check_word_register(client, page, | ||
1867 | pmbus_fan_command_registers[f])) { | ||
1868 | ret = pmbus_add_fan_ctrl(client, data, index, | ||
1869 | page, f, regval); | ||
1870 | if (ret < 0) | ||
1871 | return ret; | ||
1872 | } | ||
1873 | |||
1661 | /* | 1874 | /* |
1662 | * Each fan status register covers multiple fans, | 1875 | * Each fan status register covers multiple fans, |
1663 | * so we have to do some magic. | 1876 | * so we have to do some magic. |
@@ -2168,6 +2381,14 @@ int pmbus_do_remove(struct i2c_client *client) | |||
2168 | } | 2381 | } |
2169 | EXPORT_SYMBOL_GPL(pmbus_do_remove); | 2382 | EXPORT_SYMBOL_GPL(pmbus_do_remove); |
2170 | 2383 | ||
2384 | struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) | ||
2385 | { | ||
2386 | struct pmbus_data *data = i2c_get_clientdata(client); | ||
2387 | |||
2388 | return data->debugfs; | ||
2389 | } | ||
2390 | EXPORT_SYMBOL_GPL(pmbus_get_debugfs_dir); | ||
2391 | |||
2171 | static int __init pmbus_core_init(void) | 2392 | static int __init pmbus_core_init(void) |
2172 | { | 2393 | { |
2173 | pmbus_debugfs_dir = debugfs_create_dir("pmbus", NULL); | 2394 | pmbus_debugfs_dir = debugfs_create_dir("pmbus", NULL); |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 25d28343ba93..2be77752cd56 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
@@ -179,6 +179,7 @@ struct sht15_data { | |||
179 | * sht15_crc8() - compute crc8 | 179 | * sht15_crc8() - compute crc8 |
180 | * @data: sht15 specific data. | 180 | * @data: sht15 specific data. |
181 | * @value: sht15 retrieved data. | 181 | * @value: sht15 retrieved data. |
182 | * @len: Length of retrieved data | ||
182 | * | 183 | * |
183 | * This implements section 2 of the CRC datasheet. | 184 | * This implements section 2 of the CRC datasheet. |
184 | */ | 185 | */ |
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c index 06706d288355..190e7b39ce32 100644 --- a/drivers/hwmon/sht21.c +++ b/drivers/hwmon/sht21.c | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | /** | 42 | /** |
43 | * struct sht21 - SHT21 device specific data | 43 | * struct sht21 - SHT21 device specific data |
44 | * @hwmon_dev: device registered with hwmon | 44 | * @client: I2C client device |
45 | * @lock: mutex to protect measurement values | 45 | * @lock: mutex to protect measurement values |
46 | * @last_update: time of last update (jiffies) | 46 | * @last_update: time of last update (jiffies) |
47 | * @temperature: cached temperature measurement value | 47 | * @temperature: cached temperature measurement value |
diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c index 6ea99cd6ae79..370b57dafab7 100644 --- a/drivers/hwmon/sht3x.c +++ b/drivers/hwmon/sht3x.c | |||
@@ -732,6 +732,13 @@ static int sht3x_probe(struct i2c_client *client, | |||
732 | mutex_init(&data->i2c_lock); | 732 | mutex_init(&data->i2c_lock); |
733 | mutex_init(&data->data_lock); | 733 | mutex_init(&data->data_lock); |
734 | 734 | ||
735 | /* | ||
736 | * An attempt to read limits register too early | ||
737 | * causes a NACK response from the chip. | ||
738 | * Waiting for an empirical delay of 500 us solves the issue. | ||
739 | */ | ||
740 | usleep_range(500, 600); | ||
741 | |||
735 | ret = limits_update(data); | 742 | ret = limits_update(data); |
736 | if (ret) | 743 | if (ret) |
737 | return ret; | 744 | return ret; |
diff --git a/drivers/hwmon/w83773g.c b/drivers/hwmon/w83773g.c new file mode 100644 index 000000000000..e858093ac806 --- /dev/null +++ b/drivers/hwmon/w83773g.c | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * Driver for the Nuvoton W83773G SMBus temperature sensor IC. | ||
10 | * Supported models: W83773G | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/hwmon.h> | ||
17 | #include <linux/hwmon-sysfs.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/regmap.h> | ||
21 | |||
22 | /* W83773 has 3 channels */ | ||
23 | #define W83773_CHANNELS 3 | ||
24 | |||
25 | /* The W83773 registers */ | ||
26 | #define W83773_CONVERSION_RATE_REG_READ 0x04 | ||
27 | #define W83773_CONVERSION_RATE_REG_WRITE 0x0A | ||
28 | #define W83773_MANUFACTURER_ID_REG 0xFE | ||
29 | #define W83773_LOCAL_TEMP 0x00 | ||
30 | |||
31 | static const u8 W83773_STATUS[2] = { 0x02, 0x17 }; | ||
32 | |||
33 | static const u8 W83773_TEMP_LSB[2] = { 0x10, 0x25 }; | ||
34 | static const u8 W83773_TEMP_MSB[2] = { 0x01, 0x24 }; | ||
35 | |||
36 | static const u8 W83773_OFFSET_LSB[2] = { 0x12, 0x16 }; | ||
37 | static const u8 W83773_OFFSET_MSB[2] = { 0x11, 0x15 }; | ||
38 | |||
39 | /* this is the number of sensors in the device */ | ||
40 | static const struct i2c_device_id w83773_id[] = { | ||
41 | { "w83773g" }, | ||
42 | { } | ||
43 | }; | ||
44 | |||
45 | MODULE_DEVICE_TABLE(i2c, w83773_id); | ||
46 | |||
47 | static const struct of_device_id w83773_of_match[] = { | ||
48 | { | ||
49 | .compatible = "nuvoton,w83773g" | ||
50 | }, | ||
51 | { }, | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(of, w83773_of_match); | ||
54 | |||
55 | static inline long temp_of_local(s8 reg) | ||
56 | { | ||
57 | return reg * 1000; | ||
58 | } | ||
59 | |||
60 | static inline long temp_of_remote(s8 hb, u8 lb) | ||
61 | { | ||
62 | return (hb << 3 | lb >> 5) * 125; | ||
63 | } | ||
64 | |||
65 | static int get_local_temp(struct regmap *regmap, long *val) | ||
66 | { | ||
67 | unsigned int regval; | ||
68 | int ret; | ||
69 | |||
70 | ret = regmap_read(regmap, W83773_LOCAL_TEMP, ®val); | ||
71 | if (ret < 0) | ||
72 | return ret; | ||
73 | |||
74 | *val = temp_of_local(regval); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int get_remote_temp(struct regmap *regmap, int index, long *val) | ||
79 | { | ||
80 | unsigned int regval_high; | ||
81 | unsigned int regval_low; | ||
82 | int ret; | ||
83 | |||
84 | ret = regmap_read(regmap, W83773_TEMP_MSB[index], ®val_high); | ||
85 | if (ret < 0) | ||
86 | return ret; | ||
87 | |||
88 | ret = regmap_read(regmap, W83773_TEMP_LSB[index], ®val_low); | ||
89 | if (ret < 0) | ||
90 | return ret; | ||
91 | |||
92 | *val = temp_of_remote(regval_high, regval_low); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int get_fault(struct regmap *regmap, int index, long *val) | ||
97 | { | ||
98 | unsigned int regval; | ||
99 | int ret; | ||
100 | |||
101 | ret = regmap_read(regmap, W83773_STATUS[index], ®val); | ||
102 | if (ret < 0) | ||
103 | return ret; | ||
104 | |||
105 | *val = (regval & 0x04) >> 2; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int get_offset(struct regmap *regmap, int index, long *val) | ||
110 | { | ||
111 | unsigned int regval_high; | ||
112 | unsigned int regval_low; | ||
113 | int ret; | ||
114 | |||
115 | ret = regmap_read(regmap, W83773_OFFSET_MSB[index], ®val_high); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | |||
119 | ret = regmap_read(regmap, W83773_OFFSET_LSB[index], ®val_low); | ||
120 | if (ret < 0) | ||
121 | return ret; | ||
122 | |||
123 | *val = temp_of_remote(regval_high, regval_low); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int set_offset(struct regmap *regmap, int index, long val) | ||
128 | { | ||
129 | int ret; | ||
130 | u8 high_byte; | ||
131 | u8 low_byte; | ||
132 | |||
133 | val = clamp_val(val, -127825, 127825); | ||
134 | /* offset value equals to (high_byte << 3 | low_byte >> 5) * 125 */ | ||
135 | val /= 125; | ||
136 | high_byte = val >> 3; | ||
137 | low_byte = (val & 0x07) << 5; | ||
138 | |||
139 | ret = regmap_write(regmap, W83773_OFFSET_MSB[index], high_byte); | ||
140 | if (ret < 0) | ||
141 | return ret; | ||
142 | |||
143 | return regmap_write(regmap, W83773_OFFSET_LSB[index], low_byte); | ||
144 | } | ||
145 | |||
146 | static int get_update_interval(struct regmap *regmap, long *val) | ||
147 | { | ||
148 | unsigned int regval; | ||
149 | int ret; | ||
150 | |||
151 | ret = regmap_read(regmap, W83773_CONVERSION_RATE_REG_READ, ®val); | ||
152 | if (ret < 0) | ||
153 | return ret; | ||
154 | |||
155 | *val = 16000 >> regval; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int set_update_interval(struct regmap *regmap, long val) | ||
160 | { | ||
161 | int rate; | ||
162 | |||
163 | /* | ||
164 | * For valid rates, interval can be calculated as | ||
165 | * interval = (1 << (8 - rate)) * 62.5; | ||
166 | * Rounded rate is therefore | ||
167 | * rate = 8 - __fls(interval * 8 / (62.5 * 7)); | ||
168 | * Use clamp_val() to avoid overflows, and to ensure valid input | ||
169 | * for __fls. | ||
170 | */ | ||
171 | val = clamp_val(val, 62, 16000) * 10; | ||
172 | rate = 8 - __fls((val * 8 / (625 * 7))); | ||
173 | return regmap_write(regmap, W83773_CONVERSION_RATE_REG_WRITE, rate); | ||
174 | } | ||
175 | |||
176 | static int w83773_read(struct device *dev, enum hwmon_sensor_types type, | ||
177 | u32 attr, int channel, long *val) | ||
178 | { | ||
179 | struct regmap *regmap = dev_get_drvdata(dev); | ||
180 | |||
181 | if (type == hwmon_chip) { | ||
182 | if (attr == hwmon_chip_update_interval) | ||
183 | return get_update_interval(regmap, val); | ||
184 | return -EOPNOTSUPP; | ||
185 | } | ||
186 | |||
187 | switch (attr) { | ||
188 | case hwmon_temp_input: | ||
189 | if (channel == 0) | ||
190 | return get_local_temp(regmap, val); | ||
191 | return get_remote_temp(regmap, channel - 1, val); | ||
192 | case hwmon_temp_fault: | ||
193 | return get_fault(regmap, channel - 1, val); | ||
194 | case hwmon_temp_offset: | ||
195 | return get_offset(regmap, channel - 1, val); | ||
196 | default: | ||
197 | return -EOPNOTSUPP; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static int w83773_write(struct device *dev, enum hwmon_sensor_types type, | ||
202 | u32 attr, int channel, long val) | ||
203 | { | ||
204 | struct regmap *regmap = dev_get_drvdata(dev); | ||
205 | |||
206 | if (type == hwmon_chip && attr == hwmon_chip_update_interval) | ||
207 | return set_update_interval(regmap, val); | ||
208 | |||
209 | if (type == hwmon_temp && attr == hwmon_temp_offset) | ||
210 | return set_offset(regmap, channel - 1, val); | ||
211 | |||
212 | return -EOPNOTSUPP; | ||
213 | } | ||
214 | |||
215 | static umode_t w83773_is_visible(const void *data, enum hwmon_sensor_types type, | ||
216 | u32 attr, int channel) | ||
217 | { | ||
218 | switch (type) { | ||
219 | case hwmon_chip: | ||
220 | switch (attr) { | ||
221 | case hwmon_chip_update_interval: | ||
222 | return 0644; | ||
223 | } | ||
224 | break; | ||
225 | case hwmon_temp: | ||
226 | switch (attr) { | ||
227 | case hwmon_temp_input: | ||
228 | case hwmon_temp_fault: | ||
229 | return 0444; | ||
230 | case hwmon_temp_offset: | ||
231 | return 0644; | ||
232 | } | ||
233 | break; | ||
234 | default: | ||
235 | break; | ||
236 | } | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static const u32 w83773_chip_config[] = { | ||
241 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL, | ||
242 | 0 | ||
243 | }; | ||
244 | |||
245 | static const struct hwmon_channel_info w83773_chip = { | ||
246 | .type = hwmon_chip, | ||
247 | .config = w83773_chip_config, | ||
248 | }; | ||
249 | |||
250 | static const u32 w83773_temp_config[] = { | ||
251 | HWMON_T_INPUT, | ||
252 | HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_OFFSET, | ||
253 | HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_OFFSET, | ||
254 | 0 | ||
255 | }; | ||
256 | |||
257 | static const struct hwmon_channel_info w83773_temp = { | ||
258 | .type = hwmon_temp, | ||
259 | .config = w83773_temp_config, | ||
260 | }; | ||
261 | |||
262 | static const struct hwmon_channel_info *w83773_info[] = { | ||
263 | &w83773_chip, | ||
264 | &w83773_temp, | ||
265 | NULL | ||
266 | }; | ||
267 | |||
268 | static const struct hwmon_ops w83773_ops = { | ||
269 | .is_visible = w83773_is_visible, | ||
270 | .read = w83773_read, | ||
271 | .write = w83773_write, | ||
272 | }; | ||
273 | |||
274 | static const struct hwmon_chip_info w83773_chip_info = { | ||
275 | .ops = &w83773_ops, | ||
276 | .info = w83773_info, | ||
277 | }; | ||
278 | |||
279 | static const struct regmap_config w83773_regmap_config = { | ||
280 | .reg_bits = 8, | ||
281 | .val_bits = 8, | ||
282 | }; | ||
283 | |||
284 | static int w83773_probe(struct i2c_client *client, | ||
285 | const struct i2c_device_id *id) | ||
286 | { | ||
287 | struct device *dev = &client->dev; | ||
288 | struct device *hwmon_dev; | ||
289 | struct regmap *regmap; | ||
290 | int ret; | ||
291 | |||
292 | regmap = devm_regmap_init_i2c(client, &w83773_regmap_config); | ||
293 | if (IS_ERR(regmap)) { | ||
294 | dev_err(dev, "failed to allocate register map\n"); | ||
295 | return PTR_ERR(regmap); | ||
296 | } | ||
297 | |||
298 | /* Set the conversion rate to 2 Hz */ | ||
299 | ret = regmap_write(regmap, W83773_CONVERSION_RATE_REG_WRITE, 0x05); | ||
300 | if (ret < 0) { | ||
301 | dev_err(&client->dev, "error writing config rate register\n"); | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | i2c_set_clientdata(client, regmap); | ||
306 | |||
307 | hwmon_dev = devm_hwmon_device_register_with_info(dev, | ||
308 | client->name, | ||
309 | regmap, | ||
310 | &w83773_chip_info, | ||
311 | NULL); | ||
312 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
313 | } | ||
314 | |||
315 | static struct i2c_driver w83773_driver = { | ||
316 | .class = I2C_CLASS_HWMON, | ||
317 | .driver = { | ||
318 | .name = "w83773g", | ||
319 | .of_match_table = of_match_ptr(w83773_of_match), | ||
320 | }, | ||
321 | .probe = w83773_probe, | ||
322 | .id_table = w83773_id, | ||
323 | }; | ||
324 | |||
325 | module_i2c_driver(w83773_driver); | ||
326 | |||
327 | MODULE_AUTHOR("Lei YU <mine260309@gmail.com>"); | ||
328 | MODULE_DESCRIPTION("W83773G temperature sensor driver"); | ||
329 | MODULE_LICENSE("GPL"); | ||