Commit 22629b6d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hwmon-for-linus-v4.3' of...

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

Pull hwmon updates from Guenter Roeck:
 "Notable changes:

   - added support for LTM4675, LTC3886, LTC2980, LTM2987, LTC2975,
     LTC3887, LTC3882, MAX20751, ADM1293, and ADM1294 to PMBus drivers
   - added support for IT8732F to it87 driver
   - added support for AMD Carrizo to fam15h_power driver
   - added support for various new attributes to nct7802 driver
   - added support for F81866 and F71868 to f71882fg driver"

* tag 'hwmon-for-linus-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (45 commits)
  hwmon: (fam15h_power) Add ratio of Tsample to the PTSC period
  hwmon: (fam15h_power) Add documentation for new processors support
  hwmon: (fam15h_power) Update running_avg_capture bit field to 28
  hwmon: (fam15h_power) Rename fam15h_power_is_internal_node0 function
  hwmon: (fam15h_power) Add support for AMD Carrizo
  hwmon: (ltc2978) Add support for LTM4675
  hwmon: (ltc2978) Add polling for chips requiring it
  hwmon: (pmbus) Enable PEC if the controller supports it
  hwmon: (pmbus) Use BIT macro
  hwmon: (ltc2978) Add support for LTC3886
  hwmon: (ltc2978) Add support for LTC2980 and LTM2987
  hwmon: (ltc2978) Add missing chip IDs for LTC2978 and LTC3882
  hwmon: (ltc2978) Use correct ID mask to detect all chips
  hwmon: (ltc2978) Introduce helper functions for min and max values
  hwmon: (ltc2978) Introduce feature flags
  hwmon: (pmbus) Convert command register definitions to enum
  hwmon: (ltc2978) Add support for LTC2975
  hwmon: (ltc2978) Add support for LTC3887
  hwmon: (ltc2978) Add additional chip IDs for LTM4676 and LTM4676A
  hwmon: (ltc2978) Add support for LTC3882
  ...
parents c8192ba4 1ed32160
* LM70/TMP121/LM71/LM74 thermometer.
Required properties:
- compatible: one of
"ti,lm70"
"ti,tmp121"
"ti,lm71"
"ti,lm74"
See Documentation/devicetree/bindings/spi/spi-bus.txt for more required and
optional properties.
Example:
spi_master {
temperature-sensor@0 {
compatible = "ti,lm70";
reg = <0>;
spi-max-frequency = <1000000>;
};
};
......@@ -3,10 +3,16 @@ ltc2978
Required properties:
- compatible: should contain one of:
* "lltc,ltc2974"
* "lltc,ltc2975"
* "lltc,ltc2977"
* "lltc,ltc2978"
* "lltc,ltc2980"
* "lltc,ltc3880"
* "lltc,ltc3882"
* "lltc,ltc3883"
* "lltc,ltc3886"
* "lltc,ltc3887"
* "lltc,ltm2987"
* "lltc,ltm4676"
- reg: I2C slave address
......@@ -17,10 +23,10 @@ Optional properties:
standard binding for regulators; see regulator.txt.
Valid names of regulators depend on number of supplies supported per device:
* ltc2974 : vout0 - vout3
* ltc2977 : vout0 - vout7
* ltc2974, ltc2975 : vout0 - vout3
* ltc2977, ltc2980, ltm2987 : vout0 - vout7
* ltc2978 : vout0 - vout7
* ltc3880 : vout0 - vout1
* ltc3880, ltc3882, ltc3886 : vout0 - vout1
* ltc3883 : vout0
* ltm4676 : vout0 - vout1
......
......@@ -14,6 +14,10 @@ Supported chips:
Prefix: 'adm1276'
Addresses scanned: -
Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1276.pdf
* Analog Devices ADM1293/ADM1294
Prefix: 'adm1293', 'adm1294'
Addresses scanned: -
Datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/ADM1293_1294.pdf
Author: Guenter Roeck <linux@roeck-us.net>
......@@ -22,12 +26,12 @@ Description
-----------
This driver supports hardware montoring for Analog Devices ADM1075, ADM1275,
and ADM1276 Hot-Swap Controller and Digital Power Monitor.
ADM1276, ADM1293, and ADM1294 Hot-Swap Controller and Digital Power Monitors.
ADM1075, ADM1275, and ADM1276 are hot-swap controllers that allow a circuit
board to be removed from or inserted into a live backplane. They also feature
current and voltage readback via an integrated 12-bit analog-to-digital
converter (ADC), accessed using a PMBus interface.
ADM1075, ADM1275, ADM1276, ADM1293, and ADM1294 are hot-swap controllers that
allow a circuit board to be removed from or inserted into a live backplane.
They also feature current and voltage readback via an integrated 12
bit analog-to-digital converter (ADC), accessed using a PMBus interface.
The driver is a client driver to the core PMBus driver. Please see
Documentation/hwmon/pmbus for details on PMBus client drivers.
......@@ -58,16 +62,16 @@ Sysfs entries
The following attributes are supported. Limits are read-write, history reset
attributes are write-only, all other attributes are read-only.
in1_label "vin1" or "vout1" depending on chip variant and
configuration. On ADM1075, vout1 reports the voltage on
the VAUX pin.
in1_input Measured voltage.
in1_min Minimum Voltage.
in1_max Maximum voltage.
in1_min_alarm Voltage low alarm.
in1_max_alarm Voltage high alarm.
in1_highest Historical maximum voltage.
in1_reset_history Write any value to reset history.
inX_label "vin1" or "vout1" depending on chip variant and
configuration. On ADM1075, ADM1293, and ADM1294,
vout1 reports the voltage on the VAUX pin.
inX_input Measured voltage.
inX_min Minimum Voltage.
inX_max Maximum voltage.
inX_min_alarm Voltage low alarm.
inX_max_alarm Voltage high alarm.
inX_highest Historical maximum voltage.
inX_reset_history Write any value to reset history.
curr1_label "iout1"
curr1_input Measured current.
......@@ -86,7 +90,9 @@ curr1_reset_history Write any value to reset history.
power1_label "pin1"
power1_input Input power.
power1_input_lowest Lowest observed input power. ADM1293 and ADM1294 only.
power1_input_highest Highest observed input power.
power1_reset_history Write any value to reset history.
Power attributes are supported on ADM1075 and ADM1276
only.
Power attributes are supported on ADM1075, ADM1276,
ADM1293, and ADM1294.
......@@ -3,12 +3,13 @@ Kernel driver fam15h_power
Supported chips:
* AMD Family 15h Processors
* AMD Family 16h Processors
Prefix: 'fam15h_power'
Addresses scanned: PCI space
Datasheets:
BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors
(not yet published)
BIOS and Kernel Developer's Guide (BKDG) For AMD Family 16h Processors
Author: Andreas Herrmann <herrmann.der.user@googlemail.com>
......@@ -16,10 +17,11 @@ Description
-----------
This driver permits reading of registers providing power information
of AMD Family 15h processors.
of AMD Family 15h and 16h processors.
For AMD Family 15h processors the following power values can be
calculated using different processor northbridge function registers:
For AMD Family 15h and 16h processors the following power values can
be calculated using different processor northbridge function
registers:
* BasePwrWatts: Specifies in watts the maximum amount of power
consumed by the processor for NB and logic external to the core.
......
......@@ -38,6 +38,10 @@ Supported chips:
Prefix: 'it8728'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not publicly available
* IT8732F
Prefix: 'it8732'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not publicly available
* IT8771E
Prefix: 'it8771'
Addresses scanned: from Super I/O config space (8 I/O ports)
......@@ -111,9 +115,9 @@ Description
-----------
This driver implements support for the IT8603E, IT8620E, IT8623E, IT8705F,
IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E,
IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, and SiS950
chips.
IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F,
IT8758E, IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E, and
SiS950 chips.
These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
joysticks and other miscellaneous stuff. For hardware monitoring, they
......@@ -137,10 +141,10 @@ The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E and later IT8712F revisions
have support for 2 additional fans. The additional fans are supported by the
driver.
The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E, IT8781F, IT8782F, IT8783E/F,
and late IT8712F and IT8705F also have optional 16-bit tachometer counters
for fans 1 to 3. This is better (no more fan clock divider mess) but not
compatible with the older chips and revisions. The 16-bit tachometer mode
The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E, IT8732F, IT8781F, IT8782F,
IT8783E/F, and late IT8712F and IT8705F also have optional 16-bit tachometer
counters for fans 1 to 3. This is better (no more fan clock divider mess) but
not compatible with the older chips and revisions. The 16-bit tachometer mode
is enabled by the driver when one of the above chips is detected.
The IT8726F is just bit enhanced IT8716F with additional hardware
......@@ -159,6 +163,9 @@ IT8728F. It only supports 16-bit fan mode.
The IT8790E supports up to 3 fans. 16-bit fan mode is always enabled.
The IT8732F supports a closed-loop mode for fan control, but this is not
currently implemented by the driver.
Temperatures are measured in degrees Celsius. An alarm is triggered once
when the Overtemperature Shutdown limit is crossed.
......@@ -173,12 +180,14 @@ is done.
Voltage sensors (also known as IN sensors) report their values in volts. An
alarm is triggered if the voltage has crossed a programmable minimum or
maximum limit. Note that minimum in this case always means 'closest to
zero'; this is important for negative voltage measurements. All voltage
inputs can measure voltages between 0 and 4.08 volts, with a resolution of
0.016 volt (except IT8603E, IT8721F/IT8758E and IT8728F: 0.012 volt.) The
battery voltage in8 does not have limit registers.
On the IT8603E, IT8721F/IT8758E, IT8781F, IT8782F, and IT8783E/F, some
zero'; this is important for negative voltage measurements. On most chips, all
voltage inputs can measure voltages between 0 and 4.08 volts, with a resolution
of 0.016 volt. IT8603E, IT8721F/IT8758E and IT8728F can measure between 0 and
3.06 volts, with a resolution of 0.012 volt. IT8732F can measure between 0 and
2.8 volts with a resolution of 0.0109 volt. The battery voltage in8 does not
have limit registers.
On the IT8603E, IT8721F/IT8758E, IT8732F, IT8781F, IT8782F, and IT8783E/F, some
voltage inputs are internal and scaled inside the chip:
* in3 (optional)
* in7 (optional for IT8781F, IT8782F, and IT8783E/F)
......
......@@ -6,6 +6,10 @@ Supported chips:
Prefix: 'ltc2974'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc2974
* Linear Technology LTC2975
Prefix: 'ltc2975'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc2975
* Linear Technology LTC2977
Prefix: 'ltc2977'
Addresses scanned: -
......@@ -15,14 +19,38 @@ Supported chips:
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc2978
http://www.linear.com/product/ltc2978a
* Linear Technology LTC2980
Prefix: 'ltc2980'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc2980
* Linear Technology LTC3880
Prefix: 'ltc3880'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc3880
* Linear Technology LTC3882
Prefix: 'ltc3882'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc3882
* Linear Technology LTC3883
Prefix: 'ltc3883'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc3883
* Linear Technology LTC3886
Prefix: 'ltc3886'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc3886
* Linear Technology LTC3887
Prefix: 'ltc3887'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltc3887
* Linear Technology LTM2987
Prefix: 'ltm2987'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltm2987
* Linear Technology LTM4675
Prefix: 'ltm4675'
Addresses scanned: -
Datasheet: http://www.linear.com/product/ltm4675
* Linear Technology LTM4676
Prefix: 'ltm4676'
Addresses scanned: -
......@@ -34,11 +62,20 @@ Author: Guenter Roeck <linux@roeck-us.net>
Description
-----------
LTC2974 is a quad digital power supply manager. LTC2978 is an octal power supply
monitor. LTC2977 is a pin compatible replacement for LTC2978. LTC3880 is a dual
output poly-phase step-down DC/DC controller. LTC3883 is a single phase
step-down DC/DC controller. LTM4676 is a dual 13A or single 26A uModule
regulator.
LTC2974 and LTC2975 are quad digital power supply managers.
LTC2978 is an octal power supply monitor.
LTC2977 is a pin compatible replacement for LTC2978.
LTC2980 is a 16-channel Power System Manager, consisting of two LTC2977
in a single die. The chip is instantiated and reported as two separate chips
on two different I2C bus addresses.
LTC3880, LTC3882, LTC3886, and LTC3887 are dual output poly-phase step-down
DC/DC controllers.
LTC3883 is a single phase step-down DC/DC controller.
LTM2987 is a 16-channel Power System Manager with two LTC2977 plus
additional components on a single die. The chip is instantiated and reported
as two separate chips on two different I2C bus addresses.
LTM4675 is a dual 9A or single 18A μModule regulator
LTM4676 is a dual 13A or single 26A uModule regulator.
Usage Notes
......@@ -61,26 +98,32 @@ in1_label "vin"
in1_input Measured input voltage.
in1_min Minimum input voltage.
in1_max Maximum input voltage.
LTC2974, LTC2977, and LTC2978 only.
LTC2974, LTC2975, LTC2977, LTC2980, LTC2978, and
LTM2987 only.
in1_lcrit Critical minimum input voltage.
LTC2974, LTC2977, and LTC2978 only.
LTC2974, LTC2975, LTC2977, LTC2980, LTC2978, and
LTM2987 only.
in1_crit Critical maximum input voltage.
in1_min_alarm Input voltage low alarm.
in1_max_alarm Input voltage high alarm.
LTC2974, LTC2977, and LTC2978 only.
LTC2974, LTC2975, LTC2977, LTC2980, LTC2978, and
LTM2987 only.
in1_lcrit_alarm Input voltage critical low alarm.
LTC2974, LTC2977, and LTC2978 only.
LTC2974, LTC2975, LTC2977, LTC2980, LTC2978, and
LTM2987 only.
in1_crit_alarm Input voltage critical high alarm.
in1_lowest Lowest input voltage.
LTC2974, LTC2977, and LTC2978 only.
LTC2974, LTC2975, LTC2977, LTC2980, LTC2978, and
LTM2987 only.
in1_highest Highest input voltage.
in1_reset_history Reset input voltage history.
in[N]_label "vout[1-8]".
LTC2974: N=2-5
LTC2977: N=2-9
LTC2974, LTC2975: N=2-5
LTC2977, LTC2980, LTM2987: N=2-9
LTC2978: N=2-9
LTC3880, LTM4676: N=2-3
LTC3880, LTC3882, LTC23886 LTC3887, LTM4675, LTM4676:
N=2-3
LTC3883: N=2
in[N]_input Measured output voltage.
in[N]_min Minimum output voltage.
......@@ -91,67 +134,78 @@ in[N]_min_alarm Output voltage low alarm.
in[N]_max_alarm Output voltage high alarm.
in[N]_lcrit_alarm Output voltage critical low alarm.
in[N]_crit_alarm Output voltage critical high alarm.
in[N]_lowest Lowest output voltage. LTC2974 and LTC2978 only.
in[N]_lowest Lowest output voltage. LTC2974, LTC2975,
and LTC2978 only.
in[N]_highest Highest output voltage.
in[N]_reset_history Reset output voltage history.
temp[N]_input Measured temperature.
On LTC2974, temp[1-4] report external temperatures,
and temp5 reports the chip temperature.
On LTC2977 and LTC2978, only one temperature measurement
is supported and reports the chip temperature.
On LTC3880 and LTM4676, temp1 and temp2 report external
temperatures, and temp3 reports the chip temperature.
On LTC2974 and LTC2975, temp[1-4] report external
temperatures, and temp5 reports the chip temperature.
On LTC2977, LTC2980, LTC2978, and LTM2987, only one
temperature measurement is supported and reports
the chip temperature.
On LTC3880, LTC3882, LTC3887, LTM4675, and LTM4676,
temp1 and temp2 report external temperatures, and temp3
reports the chip temperature.
On LTC3883, temp1 reports an external temperature,
and temp2 reports the chip temperature.
temp[N]_min Mimimum temperature. LTC2974, LCT2977, and LTC2978 only.
temp[N]_min Mimimum temperature. LTC2974, LCT2977, LTM2980, LTC2978,
and LTM2987 only.
temp[N]_max Maximum temperature.
temp[N]_lcrit Critical low temperature.
temp[N]_crit Critical high temperature.
temp[N]_min_alarm Temperature low alarm.
LTC2974, LTC2977, and LTC2978 only.
LTC2974, LTC2975, LTC2977, LTM2980, LTC2978, and
LTM2987 only.
temp[N]_max_alarm Temperature high alarm.
temp[N]_lcrit_alarm Temperature critical low alarm.
temp[N]_crit_alarm Temperature critical high alarm.
temp[N]_lowest Lowest measured temperature.
LTC2974, LTC2977, and LTC2978 only.
Not supported for chip temperature sensor on LTC2974.
LTC2974, LTC2975, LTC2977, LTM2980, LTC2978, and
LTM2987 only.
Not supported for chip temperature sensor on LTC2974 and
LTC2975.
temp[N]_highest Highest measured temperature. Not supported for chip
temperature sensor on LTC2974.
temperature sensor on LTC2974 and LTC2975.
temp[N]_reset_history Reset temperature history. Not supported for chip
temperature sensor on LTC2974.
temperature sensor on LTC2974 and LTC2975.
power1_label "pin". LTC3883 only.
power1_label "pin". LTC3883 and LTC3886 only.
power1_input Measured input power.
power[N]_label "pout[1-4]".
LTC2974: N=1-4
LTC2977: Not supported
LTC2974, LTC2975: N=1-4
LTC2977, LTC2980, LTM2987: Not supported
LTC2978: Not supported
LTC3880, LTM4676: N=1-2
LTC3880, LTC3882, LTC3886, LTC3887, LTM4675, LTM4676:
N=1-2
LTC3883: N=2
power[N]_input Measured output power.
curr1_label "iin". LTC3880, LTC3883, and LTM4676 only.
curr1_label "iin". LTC3880, LTC3883, LTC3886, LTC3887, LTM4675,
and LTM4676 only.
curr1_input Measured input current.
curr1_max Maximum input current.
curr1_max_alarm Input current high alarm.
curr1_highest Highest input current. LTC3883 only.
curr1_reset_history Reset input current history. LTC3883 only.
curr1_highest Highest input current. LTC3883 and LTC3886 only.
curr1_reset_history Reset input current history. LTC3883 and LTC3886 only.
curr[N]_label "iout[1-4]".
LTC2974: N=1-4
LTC2977: not supported
LTC2974, LTC2975: N=1-4
LTC2977, LTC2980, LTM2987: not supported
LTC2978: not supported
LTC3880, LTM4676: N=2-3
LTC3880, LTC3882, LTC3886, LTC3887, LTM4675, LTM4676:
N=2-3
LTC3883: N=2
curr[N]_input Measured output current.
curr[N]_max Maximum output current.
curr[N]_crit Critical high output current.
curr[N]_lcrit Critical low output current. LTC2974 only.
curr[N]_lcrit Critical low output current. LTC2974 and LTC2975 only.
curr[N]_max_alarm Output current high alarm.
curr[N]_crit_alarm Output current critical high alarm.
curr[N]_lcrit_alarm Output current critical low alarm. LTC2974 only.
curr[N]_lowest Lowest output current. LTC2974 only.
curr[N]_lcrit_alarm Output current critical low alarm.
LTC2974 and LTC2975 only.
curr[N]_lowest Lowest output current. LTC2974 and LTC2975 only.
curr[N]_highest Highest output current.
curr[N]_reset_history Reset output current history.
Kernel driver max20751
======================
Supported chips:
* maxim MAX20751
Prefix: 'max20751'
Addresses scanned: -
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX20751.pdf
Application note: http://pdfserv.maximintegrated.com/en/an/AN5941.pdf
Author: Guenter Roeck <linux@roeck-us.net>
Description
-----------
This driver supports MAX20751 Multiphase Master with PMBus Interface
and Internal Buck Converter.
The driver is a client driver to the core PMBus driver.
Please see Documentation/hwmon/pmbus for details on PMBus client drivers.
Usage Notes
-----------
This driver does not auto-detect devices. You will have to instantiate the
devices explicitly. Please see Documentation/i2c/instantiating-devices for
details.
Platform data support
---------------------
The driver supports standard PMBus driver platform data.
Sysfs entries
-------------
The following attributes are supported.
in1_label "vin1"
in1_input Measured voltage.
in1_min Minimum input voltage.
in1_max Maximum input voltage.
in1_lcrit Critical minimum input voltage.
in1_crit Critical maximum input voltage.
in1_min_alarm Input voltage low alarm.
in1_lcrit_alarm Input voltage critical low alarm.
in1_min_alarm Input voltage low alarm.
in1_max_alarm Input voltage high alarm.
in2_label "vout1"
in2_input Measured voltage.
in2_min Minimum output voltage.
in2_max Maximum output voltage.
in2_lcrit Critical minimum output voltage.
in2_crit Critical maximum output voltage.
in2_min_alarm Output voltage low alarm.
in2_lcrit_alarm Output voltage critical low alarm.
in2_min_alarm Output voltage low alarm.
in2_max_alarm Output voltage high alarm.
curr1_input Measured output current.
curr1_label "iout1"
curr1_max Maximum output current.
curr1_alarm Current high alarm.
temp1_input Measured temperature.
temp1_max Maximum temperature.
temp1_crit Critical high temperature.
temp1_max_alarm Chip temperature high alarm.
temp1_crit_alarm Chip temperature critical high alarm.
power1_input Output power.
power1_label "pout1"
......@@ -17,8 +17,7 @@ This driver implements support for the Nuvoton NCT7802Y hardware monitoring
chip. NCT7802Y supports 6 temperature sensors, 5 voltage sensors, and 3 fan
speed sensors.
The chip also supports intelligent fan speed control. This functionality is
not currently supported by the driver.
Smart Fan™ speed control is available via pwmX_auto_point attributes.
Tested Boards and BIOS Versions
-------------------------------
......
......@@ -23,11 +23,15 @@ Supported chips:
http://www.lineagepower.com/oem/pdf/PDT012A0X.pdf
http://www.lineagepower.com/oem/pdf/UDT020A0X.pdf
http://www.lineagepower.com/oem/pdf/MDT040A0X.pdf
* Texas Instruments TPS40400
Prefixes: 'tps40400'
* Texas Instruments TPS40400, TPS544B20, TPS544B25, TPS544C20, TPS544C25
Prefixes: 'tps40400', 'tps544b20', 'tps544b25', 'tps544c20', 'tps544c25'
Addresses scanned: -
Datasheets:
http://www.ti.com/lit/gpn/tps40400
http://www.ti.com/lit/gpn/tps544b20
http://www.ti.com/lit/gpn/tps544b25
http://www.ti.com/lit/gpn/tps544c20
http://www.ti.com/lit/gpn/tps544c25
* Generic PMBus devices
Prefix: 'pmbus'
Addresses scanned: -
......
......@@ -6549,6 +6549,13 @@ S: Maintained
F: Documentation/hwmon/max16065
F: drivers/hwmon/max16065.c
MAX20751 HARDWARE MONITOR DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: lm-sensors@lm-sensors.org
S: Maintained
F: Documentation/hwmon/max20751
F: drivers/hwmon/max20751.c
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
M: "Hans J. Koch" <hjk@hansjkoch.de>
L: lm-sensors@lm-sensors.org
......
......@@ -609,8 +609,8 @@ config SENSORS_IT87
depends on !PPC
select HWMON_VID
help
If you say yes here you get support for ITE IT8705F, IT8712F,
IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E,
If you say yes here you get support for ITE IT8705F, IT8712F, IT8716F,
IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8732F, IT8758E,
IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, IT8790E,
IT8603E, IT8620E, and IT8623E sensor chips, and the SiS950 clone.
......
......@@ -51,6 +51,7 @@
#define SIO_F71808A_ID 0x1001 /* Chipset ID */
#define SIO_F71858_ID 0x0507 /* Chipset ID */
#define SIO_F71862_ID 0x0601 /* Chipset ID */
#define SIO_F71868_ID 0x1106 /* Chipset ID */
#define SIO_F71869_ID 0x0814 /* Chipset ID */
#define SIO_F71869A_ID 0x1007 /* Chipset ID */
#define SIO_F71882_ID 0x0541 /* Chipset ID */
......@@ -58,7 +59,9 @@
#define SIO_F71889E_ID 0x0909 /* Chipset ID */
#define SIO_F71889A_ID 0x1005 /* Chipset ID */
#define SIO_F8000_ID 0x0581 /* Chipset ID */
#define SIO_F81768D_ID 0x1210 /* Chipset ID */
#define SIO_F81865_ID 0x0704 /* Chipset ID */
#define SIO_F81866_ID 0x1010 /* Chipset ID */
#define REGION_LENGTH 8
#define ADDR_REG_OFFSET 5
......@@ -69,6 +72,10 @@
#define F71882FG_REG_IN(nr) (0x20 + (nr))
#define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */
#define F81866_REG_IN_STATUS 0x16 /* F81866 only */
#define F81866_REG_IN_BEEP 0x17 /* F81866 only */
#define F81866_REG_IN1_HIGH 0x3a /* F81866 only */
#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
......@@ -101,7 +108,7 @@
#define F71882FG_REG_START 0x01
#define F71882FG_MAX_INS 9
#define F71882FG_MAX_INS 11
#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
......@@ -109,14 +116,16 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
f71889fg, f71889ed, f71889a, f8000, f81865f };
enum chips { f71808e, f71808a, f71858fg, f71862fg, f71868a, f71869, f71869a,
f71882fg, f71889fg, f71889ed, f71889a, f8000, f81768d, f81865f,
f81866a};
static const char *const f71882fg_names[] = {
"f71808e",
"f71808a",
"f71858fg",
"f71862fg",
"f71868a",
"f71869", /* Both f71869f and f71869e, reg. compatible and same id */
"f71869a",
"f71882fg",
......@@ -124,22 +133,27 @@ static const char *const f71882fg_names[] = {
"f71889ed",
"f71889a",
"f8000",
"f81768d",
"f81865f",
"f81866a",
};
static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
[f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
[f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
[f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
[f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
[f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0 },
[f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0 },
[f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
[f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71868a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
[f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
[f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
[f81768d] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
[f81866a] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
};
static const char f71882fg_has_in1_alarm[] = {
......@@ -147,6 +161,7 @@ static const char f71882fg_has_in1_alarm[] = {
[f71808a] = 0,
[f71858fg] = 0,
[f71862fg] = 0,
[f71868a] = 0,
[f71869] = 0,
[f71869a] = 0,
[f71882fg] = 1,
......@@ -154,7 +169,9 @@ static const char f71882fg_has_in1_alarm[] = {
[f71889ed] = 1,
[f71889a] = 1,
[f8000] = 0,
[f81768d] = 1,
[f81865f] = 1,
[f81866a] = 1,
};
static const char f71882fg_fan_has_beep[] = {
......@@ -162,6 +179,7 @@ static const char f71882fg_fan_has_beep[] = {
[f71808a] = 0,
[f71858fg] = 0,
[f71862fg] = 1,
[f71868a] = 1,
[f71869] = 1,
[f71869a] = 1,
[f71882fg] = 1,
......@@ -169,7 +187,9 @@ static const char f71882fg_fan_has_beep[] = {
[f71889ed] = 1,
[f71889a] = 1,
[f8000] = 0,
[f81768d] = 1,
[f81865f] = 1,
[f81866a] = 1,
};
static const char f71882fg_nr_fans[] = {
......@@ -177,6 +197,7 @@ static const char f71882fg_nr_fans[] = {
[f71808a] = 2, /* +1 fan which is monitor + simple pwm only */
[f71858fg] = 3,
[f71862fg] = 3,
[f71868a] = 3,
[f71869] = 3,
[f71869a] = 3,
[f71882fg] = 4,
......@@ -184,7 +205,9 @@ static const char f71882fg_nr_fans[] = {
[f71889ed] = 3,
[f71889a] = 3,
[f8000] = 3, /* +1 fan which is monitor only */
[f81768d] = 3,
[f81865f] = 2,
[f81866a] = 3,
};
static const char f71882fg_temp_has_beep[] = {
......@@ -192,6 +215,7 @@ static const char f71882fg_temp_has_beep[] = {
[f71808a] = 1,
[f71858fg] = 0,
[f71862fg] = 1,
[f71868a] = 1,
[f71869] = 1,
[f71869a] = 1,
[f71882fg] = 1,
......@@ -199,7 +223,9 @@ static const char f71882fg_temp_has_beep[] = {
[f71889ed] = 1,
[f71889a] = 1,
[f8000] = 0,
[f81768d] = 1,
[f81865f] = 1,
[f81866a] = 1,
};
static const char f71882fg_nr_temps[] = {
......@@ -207,6 +233,7 @@ static const char f71882fg_nr_temps[] = {
[f71808a] = 2,
[f71858fg] = 3,
[f71862fg] = 3,
[f71868a] = 3,
[f71869] = 3,
[f71869a] = 3,
[f71882fg] = 3,
......@@ -214,7 +241,9 @@ static const char f71882fg_nr_temps[] = {
[f71889ed] = 3,
[f71889a] = 3,
[f8000] = 3,
[f81768d] = 3,
[f81865f] = 2,
[f81866a] = 3,
};
static struct platform_device *f71882fg_pdev;
......@@ -490,6 +519,23 @@ static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
store_temp_beep, 0, 7),
} };
static struct sensor_device_attribute_2 f81866_temp_beep_attr[3][2] = { {
SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
store_temp_beep, 0, 0),
SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
store_temp_beep, 0, 4),
}, {
SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
store_temp_beep, 0, 1),
SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
store_temp_beep, 0, 5),
}, {
SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
store_temp_beep, 0, 2),
SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
store_temp_beep, 0, 6),
} };
/*
* Temp attr for the f8000
* Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
......@@ -531,6 +577,8 @@ static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
SENSOR_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 0, 9),
SENSOR_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 0, 10),
};
/* For models with in1 alarm capability */
......@@ -1170,10 +1218,21 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
if (time_after(jiffies, data->last_limits + 60 * HZ) ||
!data->valid) {
if (f71882fg_has_in1_alarm[data->type]) {
data->in1_max =
f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
data->in_beep =
f71882fg_read8(data, F71882FG_REG_IN_BEEP);
if (data->type == f81866a) {
data->in1_max =
f71882fg_read8(data,
F81866_REG_IN1_HIGH);
data->in_beep =
f71882fg_read8(data,
F81866_REG_IN_BEEP);
} else {
data->in1_max =
f71882fg_read8(data,
F71882FG_REG_IN1_HIGH);
data->in_beep =
f71882fg_read8(data,
F71882FG_REG_IN_BEEP);
}
}
/* Get High & boundary temps*/
......@@ -1297,9 +1356,16 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
data->fan[3] = f71882fg_read16(data,
F71882FG_REG_FAN(3));
if (f71882fg_has_in1_alarm[data->type])
data->in_status = f71882fg_read8(data,
if (f71882fg_has_in1_alarm[data->type]) {
if (data->type == f81866a)
data->in_status = f71882fg_read8(data,
F81866_REG_IN_STATUS);
else
data->in_status = f71882fg_read8(data,
F71882FG_REG_IN_STATUS);
}
for (nr = 0; nr < F71882FG_MAX_INS; nr++)
if (f71882fg_has_in[data->type][nr])
data->in[nr] = f71882fg_read8(data,
......@@ -1440,7 +1506,10 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
if (data->type == f81866a)
f71882fg_write8(data, F81866_REG_IN1_HIGH, val);
else
f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
data->in1_max = val;
mutex_unlock(&data->update_lock);
......@@ -1471,13 +1540,20 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute
return err;
mutex_lock(&data->update_lock);
data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
if (data->type == f81866a)
data->in_beep = f71882fg_read8(data, F81866_REG_IN_BEEP);
else
data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
if (val)
data->in_beep |= 1 << nr;
else
data->in_beep &= ~(1 << nr);
f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
if (data->type == f81866a)
f71882fg_write8(data, F81866_REG_IN_BEEP, data->in_beep);
else
f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
mutex_unlock(&data->update_lock);
return count;
......@@ -2270,6 +2346,7 @@ static int f71882fg_probe(struct platform_device *pdev)
int nr_fans = f71882fg_nr_fans[sio_data->type];
int nr_temps = f71882fg_nr_temps[sio_data->type];
int err, i;
int size;
u8 start_reg, reg;
data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data),
......@@ -2280,7 +2357,8 @@ static int f71882fg_probe(struct platform_device *pdev)
data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
data->type = sio_data->type;
data->temp_start =
(data->type == f71858fg || data->type == f8000) ? 0 : 1;
(data->type == f71858fg || data->type == f8000 ||
data->type == f81866a) ? 0 : 1;
mutex_init(&data->update_lock);
platform_set_drvdata(pdev, data);
......@@ -2322,6 +2400,11 @@ static int f71882fg_probe(struct platform_device *pdev)
f8000_temp_attr,
ARRAY_SIZE(f8000_temp_attr));
break;
case f81866a:
err = f71882fg_create_sysfs_files(pdev,
f71858fg_temp_attr,
ARRAY_SIZE(f71858fg_temp_attr));
break;
default:
err = f71882fg_create_sysfs_files(pdev,
&fxxxx_temp_attr[0][0],
......@@ -2331,10 +2414,18 @@ static int f71882fg_probe(struct platform_device *pdev)
goto exit_unregister_sysfs;
if (f71882fg_temp_has_beep[data->type]) {
err = f71882fg_create_sysfs_files(pdev,
&fxxxx_temp_beep_attr[0][0],
ARRAY_SIZE(fxxxx_temp_beep_attr[0])
* nr_temps);
if (data->type == f81866a) {
size = ARRAY_SIZE(f81866_temp_beep_attr[0]);
err = f71882fg_create_sysfs_files(pdev,
&f81866_temp_beep_attr[0][0],
size * nr_temps);
} else {
size = ARRAY_SIZE(fxxxx_temp_beep_attr[0]);
err = f71882fg_create_sysfs_files(pdev,
&fxxxx_temp_beep_attr[0][0],
size * nr_temps);
}
if (err)
goto exit_unregister_sysfs;
}
......@@ -2451,15 +2542,27 @@ static int f71882fg_remove(struct platform_device *pdev)
f8000_temp_attr,
ARRAY_SIZE(f8000_temp_attr));
break;
case f81866a:
f71882fg_remove_sysfs_files(pdev,
f71858fg_temp_attr,
ARRAY_SIZE(f71858fg_temp_attr));
break;
default:
f71882fg_remove_sysfs_files(pdev,
&fxxxx_temp_attr[0][0],
ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
}
if (f71882fg_temp_has_beep[data->type]) {
f71882fg_remove_sysfs_files(pdev,
&fxxxx_temp_beep_attr[0][0],
ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
if (data->type == f81866a)
f71882fg_remove_sysfs_files(pdev,
&f81866_temp_beep_attr[0][0],
ARRAY_SIZE(f81866_temp_beep_attr[0])
* nr_temps);
else
f71882fg_remove_sysfs_files(pdev,
&fxxxx_temp_beep_attr[0][0],
ARRAY_SIZE(fxxxx_temp_beep_attr[0])
* nr_temps);
}
for (i = 0; i < F71882FG_MAX_INS; i++) {
......@@ -2551,6 +2654,9 @@ static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data)
case SIO_F71862_ID:
sio_data->type = f71862fg;
break;
case SIO_F71868_ID:
sio_data->type = f71868a;
break;
case SIO_F71869_ID:
sio_data->type = f71869;
break;
......@@ -2572,9 +2678,15 @@ static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data)
case SIO_F8000_ID:
sio_data->type = f8000;
break;
case SIO_F81768D_ID:
sio_data->type = f81768d;
break;
case SIO_F81865_ID:
sio_data->type = f81865f;
break;
case SIO_F81866_ID:
sio_data->type = f81866a;
break;
default:
pr_info("Unsupported Fintek device: %04x\n",
(unsigned int)devid);
......
......@@ -46,6 +46,7 @@ struct fam15h_power_data {
unsigned int tdp_to_watts;
unsigned int base_tdp;
unsigned int processor_pwr_watts;
unsigned int cpu_pwr_sample_ratio;
};
static ssize_t show_power(struct device *dev,
......@@ -59,8 +60,19 @@ static ssize_t show_power(struct device *dev,
pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
REG_TDP_RUNNING_AVERAGE, &val);
running_avg_capture = (val >> 4) & 0x3fffff;
running_avg_capture = sign_extend32(running_avg_capture, 21);
/*
* On Carrizo and later platforms, TdpRunAvgAccCap bit field
* is extended to 4:31 from 4:25.
*/
if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model >= 0x60) {
running_avg_capture = val >> 4;
running_avg_capture = sign_extend32(running_avg_capture, 27);
} else {
running_avg_capture = (val >> 4) & 0x3fffff;
running_avg_capture = sign_extend32(running_avg_capture, 21);
}
running_avg_range = (val & 0xf) + 1;
pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
......@@ -117,7 +129,7 @@ static const struct attribute_group fam15h_power_group = {
};
__ATTRIBUTE_GROUPS(fam15h_power);
static bool fam15h_power_is_internal_node0(struct pci_dev *f4)
static bool should_load_on_this_node(struct pci_dev *f4)
{
u32 val;
......@@ -177,7 +189,7 @@ static int fam15h_power_resume(struct pci_dev *pdev)
static void fam15h_power_init_data(struct pci_dev *f4,
struct fam15h_power_data *data)
{
u32 val;
u32 val, eax, ebx, ecx, edx;
u64 tmp;
pci_read_config_dword(f4, REG_PROCESSOR_TDP, &val);
......@@ -198,6 +210,19 @@ static void fam15h_power_init_data(struct pci_dev *f4,
/* convert to microWatt */
data->processor_pwr_watts = (tmp * 15625) >> 10;
cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
/* CPUID Fn8000_0007:EDX[12] indicates to support accumulated power */
if (!(edx & BIT(12)))
return;
/*
* determine the ratio of the compute unit power accumulator
* sample period to the PTSC counter period by executing CPUID
* Fn8000_0007:ECX
*/
data->cpu_pwr_sample_ratio = ecx;
}
static int fam15h_power_probe(struct pci_dev *pdev,
......@@ -214,7 +239,7 @@ static int fam15h_power_probe(struct pci_dev *pdev,
*/
tweak_runavg_range(pdev);
if (!fam15h_power_is_internal_node0(pdev))
if (!should_load_on_this_node(pdev))
return -ENODEV;
data = devm_kzalloc(dev, sizeof(struct fam15h_power_data), GFP_KERNEL);
......@@ -233,6 +258,7 @@ static int fam15h_power_probe(struct pci_dev *pdev,
static const struct pci_device_id fam15h_power_id_table[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F4) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
{}
......
......@@ -1113,7 +1113,6 @@ static int g762_remove(struct i2c_client *client)
static struct i2c_driver g762_driver = {
.driver = {
.name = DRVNAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(g762_dt_match),
},
.probe = g762_probe,
......
......@@ -21,6 +21,7 @@
* IT8721F Super I/O chip w/LPC interface
* IT8726F Super I/O chip w/LPC interface
* IT8728F Super I/O chip w/LPC interface
* IT8732F Super I/O chip w/LPC interface
* IT8758E Super I/O chip w/LPC interface
* IT8771E Super I/O chip w/LPC interface
* IT8772E Super I/O chip w/LPC interface
......@@ -69,8 +70,9 @@
#define DRVNAME "it87"
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8771,
it8772, it8781, it8782, it8783, it8786, it8790, it8603, it8620 };
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790, it8603,
it8620 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
......@@ -148,6 +150,7 @@ static inline void superio_exit(void)
#define IT8721F_DEVID 0x8721
#define IT8726F_DEVID 0x8726
#define IT8728F_DEVID 0x8728
#define IT8732F_DEVID 0x8732
#define IT8771E_DEVID 0x8771
#define IT8772E_DEVID 0x8772
#define IT8781F_DEVID 0x8781
......@@ -265,6 +268,7 @@ struct it87_devices {
#define FEAT_VID (1 << 9) /* Set if chip supports VID */
#define FEAT_IN7_INTERNAL (1 << 10) /* Set if in7 is internal */
#define FEAT_SIX_FANS (1 << 11) /* Supports six fans */
#define FEAT_10_9MV_ADC (1 << 12)
static const struct it87_devices it87_devices[] = {
[it87] = {
......@@ -315,6 +319,15 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL,
.peci_mask = 0x07,
},
[it8732] = {
.name = "it8732",
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
[it8771] = {
.name = "it8771",
.suffix = "E",
......@@ -391,6 +404,7 @@ static const struct it87_devices it87_devices[] = {
#define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS)
#define has_12mv_adc(data) ((data)->features & FEAT_12MV_ADC)
#define has_10_9mv_adc(data) ((data)->features & FEAT_10_9MV_ADC)
#define has_newer_autopwm(data) ((data)->features & FEAT_NEWER_AUTOPWM)
#define has_old_autopwm(data) ((data)->features & FEAT_OLD_AUTOPWM)
#define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET)
......@@ -475,7 +489,14 @@ struct it87_data {
static int adc_lsb(const struct it87_data *data, int nr)
{
int lsb = has_12mv_adc(data) ? 12 : 16;
int lsb;
if (has_12mv_adc(data))
lsb = 120;
else if (has_10_9mv_adc(data))
lsb = 109;
else
lsb = 160;
if (data->in_scaled & (1 << nr))
lsb <<= 1;
return lsb;
......@@ -483,13 +504,13 @@ static int adc_lsb(const struct it87_data *data, int nr)
static u8 in_to_reg(const struct it87_data *data, int nr, long val)
{
val = DIV_ROUND_CLOSEST(val, adc_lsb(data, nr));
val = DIV_ROUND_CLOSEST(val * 10, adc_lsb(data, nr));
return clamp_val(val, 0, 255);
}
static int in_from_reg(const struct it87_data *data, int nr, int val)
{
return val * adc_lsb(data, nr);
return DIV_ROUND_CLOSEST(val * adc_lsb(data, nr), 10);
}
static inline u8 FAN_TO_REG(long rpm, int div)
......@@ -1515,9 +1536,14 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
};
struct it87_data *data = dev_get_drvdata(dev);
int nr = to_sensor_dev_attr(attr)->index;
const char *label;
return sprintf(buf, "%s\n", has_12mv_adc(data) ? labels_it8721[nr]
: labels[nr]);
if (has_12mv_adc(data) || has_10_9mv_adc(data))
label = labels_it8721[nr];
else
label = labels[nr];
return sprintf(buf, "%s\n", label);
}
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
......@@ -1853,6 +1879,9 @@ static int __init it87_find(unsigned short *address,
case IT8728F_DEVID:
sio_data->type = it8728;
break;
case IT8732F_DEVID:
sio_data->type = it8732;
break;
case IT8771E_DEVID:
sio_data->type = it8771;
break;
......
......@@ -37,6 +37,7 @@
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#define DRVNAME "lm70"
......@@ -130,11 +131,41 @@ ATTRIBUTE_GROUPS(lm70);
/*----------------------------------------------------------------------*/
#ifdef CONFIG_OF
static const struct of_device_id lm70_of_ids[] = {
{
.compatible = "ti,lm70",
.data = (void *) LM70_CHIP_LM70,
},
{
.compatible = "ti,tmp121",
.data = (void *) LM70_CHIP_TMP121,
},
{
.compatible = "ti,lm71",
.data = (void *) LM70_CHIP_LM71,
},
{
.compatible = "ti,lm74",
.data = (void *) LM70_CHIP_LM74,
},
{},
};
MODULE_DEVICE_TABLE(of, lm70_of_ids);
#endif
static int lm70_probe(struct spi_device *spi)
{
int chip = spi_get_device_id(spi)->driver_data;
const struct of_device_id *match;
struct device *hwmon_dev;
struct lm70 *p_lm70;
int chip;
match = of_match_device(lm70_of_ids, &spi->dev);
if (match)
chip = (int)(uintptr_t)match->data;
else
chip = spi_get_device_id(spi)->driver_data;
/* signaling is SPI_MODE_0 */
if (spi->mode & (SPI_CPOL | SPI_CPHA))
......@@ -169,6 +200,7 @@ static struct spi_driver lm70_driver = {
.driver = {
.name = "lm70",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(lm70_of_ids),
},
.id_table = lm70_ids,
.probe = lm70_probe,
......
......@@ -49,10 +49,13 @@ static const u8 REG_VOLTAGE_LIMIT_MSB_SHIFT[2][5] = {
#define REG_VOLTAGE_LOW 0x0f
#define REG_FANCOUNT_LOW 0x13
#define REG_START 0x21
#define REG_MODE 0x22
#define REG_MODE 0x22 /* 7.2.32 Mode Selection Register */
#define REG_PECI_ENABLE 0x23
#define REG_FAN_ENABLE 0x24
#define REG_VMON_ENABLE 0x25
#define REG_PWM(x) (0x60 + (x))
#define REG_SMARTFAN_EN(x) (0x64 + (x) / 2)
#define SMARTFAN_EN_SHIFT(x) ((x) % 2 * 4)
#define REG_VENDOR_ID 0xfd
#define REG_CHIP_ID 0xfe
#define REG_VERSION_ID 0xff
......@@ -66,6 +69,129 @@ struct nct7802_data {
struct mutex access_lock; /* for multi-byte read and write operations */
};
static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct nct7802_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
unsigned int mode;
int ret;
ret = regmap_read(data->regmap, REG_MODE, &mode);
if (ret < 0)
return ret;
return sprintf(buf, "%u\n", (mode >> (2 * sattr->index) & 3) + 2);
}
static ssize_t store_temp_type(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct nct7802_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
unsigned int type;
int err;
err = kstrtouint(buf, 0, &type);
if (err < 0)
return err;
if (sattr->index == 2 && type != 4) /* RD3 */
return -EINVAL;
if (type < 3 || type > 4)
return -EINVAL;
err = regmap_update_bits(data->regmap, REG_MODE,
3 << 2 * sattr->index, (type - 2) << 2 * sattr->index);
return err ? : count;
}
static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
struct nct7802_data *data = dev_get_drvdata(dev);
unsigned int regval;
int ret;
if (sattr->index > 1)
return sprintf(buf, "1\n");
ret = regmap_read(data->regmap, 0x5E, &regval);
if (ret < 0)
return ret;
return sprintf(buf, "%u\n", !(regval & (1 << sattr->index)));
}
static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct nct7802_data *data = dev_get_drvdata(dev);
unsigned int val;
int ret;
if (!attr->index)
return sprintf(buf, "255\n");
ret = regmap_read(data->regmap, attr->index, &val);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", val);
}
static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct nct7802_data *data = dev_get_drvdata(dev);
int err;
u8 val;
err = kstrtou8(buf, 0, &val);
if (err < 0)
return err;
err = regmap_write(data->regmap, attr->index, val);
return err ? : count;
}
static ssize_t show_pwm_enable(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct nct7802_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
unsigned int reg, enabled;
int ret;
ret = regmap_read(data->regmap, REG_SMARTFAN_EN(sattr->index), &reg);
if (ret < 0)
return ret;
enabled = reg >> SMARTFAN_EN_SHIFT(sattr->index) & 1;
return sprintf(buf, "%u\n", enabled + 1);
}
static ssize_t store_pwm_enable(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct nct7802_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
u8 val;
int ret;
ret = kstrtou8(buf, 0, &val);
if (ret < 0)
return ret;
if (val < 1 || val > 2)
return -EINVAL;
ret = regmap_update_bits(data->regmap, REG_SMARTFAN_EN(sattr->index),
1 << SMARTFAN_EN_SHIFT(sattr->index),
(val - 1) << SMARTFAN_EN_SHIFT(sattr->index));
return ret ? : count;
}
static int nct7802_read_temp(struct nct7802_data *data,
u8 reg_temp, u8 reg_temp_low, int *temp)
{
......@@ -377,6 +503,8 @@ store_beep(struct device *dev, struct device_attribute *attr, const char *buf,
return err ? : count;
}
static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR,
show_temp_type, store_temp_type, 0);
static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0x01,
REG_TEMP_LSB);
static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp,
......@@ -386,6 +514,8 @@ static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp,
static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp,
store_temp, 0x3a, 0);
static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR,
show_temp_type, store_temp_type, 1);
static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0x02,
REG_TEMP_LSB);
static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp,
......@@ -395,6 +525,8 @@ static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp,
static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp,
store_temp, 0x3b, 0);
static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR,
show_temp_type, store_temp_type, 2);
static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0x03,
REG_TEMP_LSB);
static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp,
......@@ -475,6 +607,7 @@ static SENSOR_DEVICE_ATTR_2(temp6_beep, S_IRUGO | S_IWUSR, show_beep,
store_beep, 0x5c, 5);
static struct attribute *nct7802_temp_attrs[] = {
&sensor_dev_attr_temp1_type.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
......@@ -485,7 +618,8 @@ static struct attribute *nct7802_temp_attrs[] = {
&sensor_dev_attr_temp1_fault.dev_attr.attr,
&sensor_dev_attr_temp1_beep.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr, /* 9 */
&sensor_dev_attr_temp2_type.dev_attr.attr, /* 10 */
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_min.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
&sensor_dev_attr_temp2_crit.dev_attr.attr,
......@@ -495,7 +629,8 @@ static struct attribute *nct7802_temp_attrs[] = {
&sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp2_beep.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr, /* 18 */
&sensor_dev_attr_temp3_type.dev_attr.attr, /* 20 */
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp3_min.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
&sensor_dev_attr_temp3_crit.dev_attr.attr,
......@@ -505,7 +640,7 @@ static struct attribute *nct7802_temp_attrs[] = {
&sensor_dev_attr_temp3_fault.dev_attr.attr,
&sensor_dev_attr_temp3_beep.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr, /* 27 */
&sensor_dev_attr_temp4_input.dev_attr.attr, /* 30 */
&sensor_dev_attr_temp4_min.dev_attr.attr,
&sensor_dev_attr_temp4_max.dev_attr.attr,
&sensor_dev_attr_temp4_crit.dev_attr.attr,
......@@ -514,7 +649,7 @@ static struct attribute *nct7802_temp_attrs[] = {
&sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
&sensor_dev_attr_temp4_beep.dev_attr.attr,
&sensor_dev_attr_temp5_input.dev_attr.attr, /* 35 */
&sensor_dev_attr_temp5_input.dev_attr.attr, /* 38 */
&sensor_dev_attr_temp5_min.dev_attr.attr,
&sensor_dev_attr_temp5_max.dev_attr.attr,
&sensor_dev_attr_temp5_crit.dev_attr.attr,
......@@ -523,7 +658,7 @@ static struct attribute *nct7802_temp_attrs[] = {
&sensor_dev_attr_temp5_crit_alarm.dev_attr.attr,
&sensor_dev_attr_temp5_beep.dev_attr.attr,
&sensor_dev_attr_temp6_input.dev_attr.attr, /* 43 */
&sensor_dev_attr_temp6_input.dev_attr.attr, /* 46 */
&sensor_dev_attr_temp6_beep.dev_attr.attr,
NULL
......@@ -541,25 +676,27 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj,
if (err < 0)
return 0;
if (index < 9 &&
if (index < 10 &&
(reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */
return 0;
if (index >= 9 && index < 18 &&
if (index >= 10 && index < 20 &&
(reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */
return 0;
if (index >= 18 && index < 27 && (reg & 0x30) != 0x20) /* RD3 */
if (index >= 20 && index < 30 && (reg & 0x30) != 0x20) /* RD3 */
return 0;
if (index >= 27 && index < 35) /* local */
if (index >= 30 && index < 38) /* local */
return attr->mode;
err = regmap_read(data->regmap, REG_PECI_ENABLE, &reg);
if (err < 0)
return 0;
if (index >= 35 && index < 43 && !(reg & 0x01)) /* PECI 0 */
if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */
return 0;
if (index >= 0x43 && (!(reg & 0x02))) /* PECI 1 */
if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */
return 0;
return attr->mode;
......@@ -687,6 +824,27 @@ static SENSOR_DEVICE_ATTR_2(fan3_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 2);
static SENSOR_DEVICE_ATTR_2(fan3_beep, S_IRUGO | S_IWUSR, show_beep, store_beep,
0x5b, 2);
/* 7.2.89 Fan Control Output Type */
static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, show_pwm_mode, NULL, 1);
static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2);
/* 7.2.91... Fan Control Output Value */
static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm,
REG_PWM(0));
static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, store_pwm,
REG_PWM(1));
static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, store_pwm,
REG_PWM(2));
/* 7.2.95... Temperature to Fan mapping Relationships Register */
static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
store_pwm_enable, 0);
static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
store_pwm_enable, 1);
static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
store_pwm_enable, 2);
static struct attribute *nct7802_fan_attrs[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan1_min.dev_attr.attr,
......@@ -725,10 +883,142 @@ static struct attribute_group nct7802_fan_group = {
.is_visible = nct7802_fan_is_visible,
};
static struct attribute *nct7802_pwm_attrs[] = {
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_pwm1_mode.dev_attr.attr,
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
&sensor_dev_attr_pwm2_mode.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm3_mode.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
NULL
};
static struct attribute_group nct7802_pwm_group = {
.attrs = nct7802_pwm_attrs,
};
/* 7.2.115... 0x80-0x83, 0x84 Temperature (X-axis) transition */
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x80, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x81, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x82, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x83, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point5_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x84, 0);
/* 7.2.120... 0x85-0x88 PWM (Y-axis) transition */
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x85);
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x86);
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x87);
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x88);
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0);
/* 7.2.124 Table 2 X-axis Transition Point 1 Register */
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x90, 0);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x91, 0);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x92, 0);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x93, 0);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point5_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x94, 0);
/* 7.2.129 Table 2 Y-axis Transition Point 1 Register */
static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x95);
static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x96);
static SENSOR_DEVICE_ATTR(pwm2_auto_point3_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x97);
static SENSOR_DEVICE_ATTR(pwm2_auto_point4_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0x98);
static SENSOR_DEVICE_ATTR(pwm2_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0);
/* 7.2.133 Table 3 X-axis Transition Point 1 Register */
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0xA0, 0);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0xA1, 0);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0xA2, 0);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0xA3, 0);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point5_temp, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0xA4, 0);
/* 7.2.138 Table 3 Y-axis Transition Point 1 Register */
static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0xA5);
static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0xA6);
static SENSOR_DEVICE_ATTR(pwm3_auto_point3_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0xA7);
static SENSOR_DEVICE_ATTR(pwm3_auto_point4_pwm, S_IRUGO | S_IWUSR,
show_pwm, store_pwm, 0xA8);
static SENSOR_DEVICE_ATTR(pwm3_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0);
static struct attribute *nct7802_auto_point_attrs[] = {
&sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point5_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point5_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point5_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point5_pwm.dev_attr.attr,
NULL
};
static struct attribute_group nct7802_auto_point_group = {
.attrs = nct7802_auto_point_attrs,
};
static const struct attribute_group *nct7802_groups[] = {
&nct7802_temp_group,
&nct7802_in_group,
&nct7802_fan_group,
&nct7802_pwm_group,
&nct7802_auto_point_group,
NULL
};
......@@ -776,7 +1066,8 @@ static int nct7802_detect(struct i2c_client *client,
static bool nct7802_regmap_is_volatile(struct device *dev, unsigned int reg)
{
return reg != REG_BANK && reg <= 0x20;
return (reg != REG_BANK && reg <= 0x20) ||
(reg >= REG_PWM(0) && reg <= REG_PWM(2));
}
static const struct regmap_config nct7802_regmap_config = {
......
......@@ -20,7 +20,8 @@ config SENSORS_PMBUS
help
If you say yes here you get hardware monitoring support for generic
PMBus devices, including but not limited to ADP4000, BMR453, BMR454,
MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, and TPS40400.
MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, TPS40400, TPS544B20,
TPS544B25, TPS544C20, TPS544C25, and UDT020.
This driver can also be built as a module. If so, the module will
be called pmbus.
......@@ -30,8 +31,8 @@ config SENSORS_ADM1275
default n
help
If you say yes here you get hardware monitoring support for Analog
Devices ADM1075, ADM1275, and ADM1276 Hot-Swap Controller and Digital
Power Monitors.
Devices ADM1075, ADM1275, ADM1276, ADM1293, and ADM1294 Hot-Swap
Controller and Digital Power Monitors.
This driver can also be built as a module. If so, the module will
be called adm1275.
......@@ -51,7 +52,8 @@ config SENSORS_LTC2978
default n
help
If you say yes here you get hardware monitoring support for Linear
Technology LTC2974, LTC2977, LTC2978, LTC3880, LTC3883, and LTM4676.
Technology LTC2974, LTC2975, LTC2977, LTC2978, LTC2980, LTC3880,
LTC3883, LTC3886, LTC3887, LTCM2987, LTM4675, and LTM4676.
This driver can also be built as a module. If so, the module will
be called ltc2978.
......@@ -73,6 +75,16 @@ config SENSORS_MAX16064
This driver can also be built as a module. If so, the module will
be called max16064.
config SENSORS_MAX20751
tristate "Maxim MAX20751"
default n
help
If you say yes here you get hardware monitoring support for Maxim
MAX20751.
This driver can also be built as a module. If so, the module will
be called max20751.
config SENSORS_MAX34440
tristate "Maxim MAX34440 and compatibles"
default n
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o
obj-$(CONFIG_SENSORS_LM25066) += lm25066.o
obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
obj-$(CONFIG_SENSORS_MAX16064) += max16064.o
obj-$(CONFIG_SENSORS_MAX20751) += max20751.o
obj-$(CONFIG_SENSORS_MAX34440) += max34440.o
obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o
......
......@@ -21,46 +21,120 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/bitops.h>
#include "pmbus.h"
enum chips { adm1075, adm1275, adm1276 };
enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 };
#define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0)
#define ADM1293_MFR_STATUS_VAUX_UV_WARN BIT(5)
#define ADM1293_MFR_STATUS_VAUX_OV_WARN BIT(6)
#define ADM1275_PEAK_IOUT 0xd0
#define ADM1275_PEAK_VIN 0xd1
#define ADM1275_PEAK_VOUT 0xd2
#define ADM1275_PMON_CONFIG 0xd4
#define ADM1275_VIN_VOUT_SELECT (1 << 6)
#define ADM1275_VRANGE (1 << 5)
#define ADM1075_IRANGE_50 (1 << 4)
#define ADM1075_IRANGE_25 (1 << 3)
#define ADM1075_IRANGE_MASK ((1 << 3) | (1 << 4))
#define ADM1275_VIN_VOUT_SELECT BIT(6)
#define ADM1275_VRANGE BIT(5)
#define ADM1075_IRANGE_50 BIT(4)
#define ADM1075_IRANGE_25 BIT(3)
#define ADM1075_IRANGE_MASK (BIT(3) | BIT(4))
#define ADM1293_IRANGE_25 0
#define ADM1293_IRANGE_50 BIT(6)
#define ADM1293_IRANGE_100 BIT(7)
#define ADM1293_IRANGE_200 (BIT(6) | BIT(7))
#define ADM1293_IRANGE_MASK (BIT(6) | BIT(7))
#define ADM1293_VIN_SEL_012 BIT(2)
#define ADM1293_VIN_SEL_074 BIT(3)
#define ADM1293_VIN_SEL_210 (BIT(2) | BIT(3))
#define ADM1293_VIN_SEL_MASK (BIT(2) | BIT(3))
#define ADM1293_VAUX_EN BIT(1)
#define ADM1275_IOUT_WARN2_LIMIT 0xd7
#define ADM1275_DEVICE_CONFIG 0xd8
#define ADM1275_IOUT_WARN2_SELECT (1 << 4)
#define ADM1275_IOUT_WARN2_SELECT BIT(4)
#define ADM1276_PEAK_PIN 0xda
#define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0)
#define ADM1075_READ_VAUX 0xdd
#define ADM1075_VAUX_OV_WARN_LIMIT 0xde
#define ADM1075_VAUX_UV_WARN_LIMIT 0xdf
#define ADM1293_IOUT_MIN 0xe3
#define ADM1293_PIN_MIN 0xe4
#define ADM1075_VAUX_STATUS 0xf6
#define ADM1075_VAUX_OV_WARN (1<<7)
#define ADM1075_VAUX_UV_WARN (1<<6)
#define ADM1075_VAUX_OV_WARN BIT(7)
#define ADM1075_VAUX_UV_WARN BIT(6)
struct adm1275_data {
int id;
bool have_oc_fault;
bool have_uc_fault;
bool have_vout;
bool have_vaux_status;
bool have_mfr_vaux_status;
bool have_iout_min;
bool have_pin_min;
bool have_pin_max;
struct pmbus_driver_info info;
};
#define to_adm1275_data(x) container_of(x, struct adm1275_data, info)
struct coefficients {
s16 m;
s16 b;
s16 R;
};
static const struct coefficients adm1075_coefficients[] = {
[0] = { 27169, 0, -1 }, /* voltage */
[1] = { 806, 20475, -1 }, /* current, irange25 */
[2] = { 404, 20475, -1 }, /* current, irange50 */
[3] = { 0, -1, 8549 }, /* power, irange25 */
[4] = { 0, -1, 4279 }, /* power, irange50 */
};
static const struct coefficients adm1275_coefficients[] = {
[0] = { 19199, 0, -2 }, /* voltage, vrange set */
[1] = { 6720, 0, -1 }, /* voltage, vrange not set */
[2] = { 807, 20475, -1 }, /* current */
};
static const struct coefficients adm1276_coefficients[] = {
[0] = { 19199, 0, -2 }, /* voltage, vrange set */
[1] = { 6720, 0, -1 }, /* voltage, vrange not set */
[2] = { 807, 20475, -1 }, /* current */
[3] = { 6043, 0, -2 }, /* power, vrange set */
[4] = { 2115, 0, -1 }, /* power, vrange not set */
};
static const struct coefficients adm1293_coefficients[] = {
[0] = { 3333, -1, 0 }, /* voltage, vrange 1.2V */
[1] = { 5552, -5, -1 }, /* voltage, vrange 7.4V */
[2] = { 19604, -50, -2 }, /* voltage, vrange 21V */
[3] = { 8000, -100, -2 }, /* current, irange25 */
[4] = { 4000, -100, -2 }, /* current, irange50 */
[5] = { 20000, -1000, -3 }, /* current, irange100 */
[6] = { 10000, -1000, -3 }, /* current, irange200 */
[7] = { 10417, 0, -1 }, /* power, 1.2V, irange25 */
[8] = { 5208, 0, -1 }, /* power, 1.2V, irange50 */
[9] = { 26042, 0, -2 }, /* power, 1.2V, irange100 */
[10] = { 13021, 0, -2 }, /* power, 1.2V, irange200 */
[11] = { 17351, 0, -2 }, /* power, 7.4V, irange25 */
[12] = { 8676, 0, -2 }, /* power, 7.4V, irange50 */
[13] = { 4338, 0, -2 }, /* power, 7.4V, irange100 */
[14] = { 21689, 0, -3 }, /* power, 7.4V, irange200 */
[15] = { 6126, 0, -2 }, /* power, 21V, irange25 */
[16] = { 30631, 0, -3 }, /* power, 21V, irange50 */
[17] = { 15316, 0, -3 }, /* power, 21V, irange100 */
[18] = { 7658, 0, -3 }, /* power, 21V, irange200 */
};
static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
{
const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
......@@ -72,42 +146,37 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
switch (reg) {
case PMBUS_IOUT_UC_FAULT_LIMIT:
if (data->have_oc_fault) {
ret = -ENXIO;
break;
}
if (!data->have_uc_fault)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
break;
case PMBUS_IOUT_OC_FAULT_LIMIT:
if (!data->have_oc_fault) {
ret = -ENXIO;
break;
}
if (!data->have_oc_fault)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
break;
case PMBUS_VOUT_OV_WARN_LIMIT:
if (data->id != adm1075) {
ret = -ENODATA;
break;
}
if (data->have_vout)
return -ENODATA;
ret = pmbus_read_word_data(client, 0,
ADM1075_VAUX_OV_WARN_LIMIT);
break;
case PMBUS_VOUT_UV_WARN_LIMIT:
if (data->id != adm1075) {
ret = -ENODATA;
break;
}
if (data->have_vout)
return -ENODATA;
ret = pmbus_read_word_data(client, 0,
ADM1075_VAUX_UV_WARN_LIMIT);
break;
case PMBUS_READ_VOUT:
if (data->id != adm1075) {
ret = -ENODATA;
break;
}
if (data->have_vout)
return -ENODATA;
ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX);
break;
case PMBUS_VIRT_READ_IOUT_MIN:
if (!data->have_iout_min)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1293_IOUT_MIN);
break;
case PMBUS_VIRT_READ_IOUT_MAX:
ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT);
break;
......@@ -117,11 +186,14 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
case PMBUS_VIRT_READ_VIN_MAX:
ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN);
break;
case PMBUS_VIRT_READ_PIN_MIN:
if (!data->have_pin_min)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1293_PIN_MIN);
break;
case PMBUS_VIRT_READ_PIN_MAX:
if (data->id == adm1275) {
ret = -ENXIO;
break;
}
if (!data->have_pin_max)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN);
break;
case PMBUS_VIRT_RESET_IOUT_HISTORY:
......@@ -129,8 +201,8 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
case PMBUS_VIRT_RESET_VIN_HISTORY:
break;
case PMBUS_VIRT_RESET_PIN_HISTORY:
if (data->id == adm1275)
ret = -ENXIO;
if (!data->have_pin_max)
return -ENXIO;
break;
default:
ret = -ENODATA;
......@@ -142,6 +214,8 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
u16 word)
{
const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
const struct adm1275_data *data = to_adm1275_data(info);
int ret;
if (page)
......@@ -155,6 +229,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
break;
case PMBUS_VIRT_RESET_IOUT_HISTORY:
ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0);
if (!ret && data->have_iout_min)
ret = pmbus_write_word_data(client, 0,
ADM1293_IOUT_MIN, 0);
break;
case PMBUS_VIRT_RESET_VOUT_HISTORY:
ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VOUT, 0);
......@@ -164,6 +241,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
break;
case PMBUS_VIRT_RESET_PIN_HISTORY:
ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0);
if (!ret && data->have_pin_min)
ret = pmbus_write_word_data(client, 0,
ADM1293_PIN_MIN, 0);
break;
default:
ret = -ENODATA;
......@@ -186,29 +266,40 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg)
ret = pmbus_read_byte_data(client, page, PMBUS_STATUS_IOUT);
if (ret < 0)
break;
if (!data->have_oc_fault && !data->have_uc_fault)
break;
mfr_status = pmbus_read_byte_data(client, page,
PMBUS_STATUS_MFR_SPECIFIC);
if (mfr_status < 0) {
ret = mfr_status;
break;
}
if (mfr_status < 0)
return mfr_status;
if (mfr_status & ADM1275_MFR_STATUS_IOUT_WARN2) {
ret |= data->have_oc_fault ?
PB_IOUT_OC_FAULT : PB_IOUT_UC_FAULT;
}
break;
case PMBUS_STATUS_VOUT:
if (data->id != adm1075) {
ret = -ENODATA;
break;
}
if (data->have_vout)
return -ENODATA;
ret = 0;
mfr_status = pmbus_read_byte_data(client, 0,
ADM1075_VAUX_STATUS);
if (mfr_status & ADM1075_VAUX_OV_WARN)
ret |= PB_VOLTAGE_OV_WARNING;
if (mfr_status & ADM1075_VAUX_UV_WARN)
ret |= PB_VOLTAGE_UV_WARNING;
if (data->have_vaux_status) {
mfr_status = pmbus_read_byte_data(client, 0,
ADM1075_VAUX_STATUS);
if (mfr_status < 0)
return mfr_status;
if (mfr_status & ADM1075_VAUX_OV_WARN)
ret |= PB_VOLTAGE_OV_WARNING;
if (mfr_status & ADM1075_VAUX_UV_WARN)
ret |= PB_VOLTAGE_UV_WARNING;
} else if (data->have_mfr_vaux_status) {
mfr_status = pmbus_read_byte_data(client, page,
PMBUS_STATUS_MFR_SPECIFIC);
if (mfr_status < 0)
return mfr_status;
if (mfr_status & ADM1293_MFR_STATUS_VAUX_OV_WARN)
ret |= PB_VOLTAGE_OV_WARNING;
if (mfr_status & ADM1293_MFR_STATUS_VAUX_UV_WARN)
ret |= PB_VOLTAGE_UV_WARNING;
}
break;
default:
ret = -ENODATA;
......@@ -221,6 +312,8 @@ static const struct i2c_device_id adm1275_id[] = {
{ "adm1075", adm1075 },
{ "adm1275", adm1275 },
{ "adm1276", adm1276 },
{ "adm1293", adm1293 },
{ "adm1294", adm1294 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1275_id);
......@@ -234,6 +327,8 @@ static int adm1275_probe(struct i2c_client *client,
struct pmbus_driver_info *info;
struct adm1275_data *data;
const struct i2c_device_id *mid;
const struct coefficients *coefficients;
int vindex = -1, voindex = -1, cindex = -1, pindex = -1;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA
......@@ -290,61 +385,38 @@ static int adm1275_probe(struct i2c_client *client,
info->format[PSC_VOLTAGE_IN] = direct;
info->format[PSC_VOLTAGE_OUT] = direct;
info->format[PSC_CURRENT_OUT] = direct;
info->m[PSC_CURRENT_OUT] = 807;
info->b[PSC_CURRENT_OUT] = 20475;
info->R[PSC_CURRENT_OUT] = -1;
info->format[PSC_POWER] = direct;
info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
info->read_word_data = adm1275_read_word_data;
info->read_byte_data = adm1275_read_byte_data;
info->write_word_data = adm1275_write_word_data;
if (data->id == adm1075) {
info->m[PSC_VOLTAGE_IN] = 27169;
info->b[PSC_VOLTAGE_IN] = 0;
info->R[PSC_VOLTAGE_IN] = -1;
info->m[PSC_VOLTAGE_OUT] = 27169;
info->b[PSC_VOLTAGE_OUT] = 0;
info->R[PSC_VOLTAGE_OUT] = -1;
} else if (config & ADM1275_VRANGE) {
info->m[PSC_VOLTAGE_IN] = 19199;
info->b[PSC_VOLTAGE_IN] = 0;
info->R[PSC_VOLTAGE_IN] = -2;
info->m[PSC_VOLTAGE_OUT] = 19199;
info->b[PSC_VOLTAGE_OUT] = 0;
info->R[PSC_VOLTAGE_OUT] = -2;
} else {
info->m[PSC_VOLTAGE_IN] = 6720;
info->b[PSC_VOLTAGE_IN] = 0;
info->R[PSC_VOLTAGE_IN] = -1;
info->m[PSC_VOLTAGE_OUT] = 6720;
info->b[PSC_VOLTAGE_OUT] = 0;
info->R[PSC_VOLTAGE_OUT] = -1;
}
if (device_config & ADM1275_IOUT_WARN2_SELECT)
data->have_oc_fault = true;
switch (data->id) {
case adm1075:
info->format[PSC_POWER] = direct;
info->b[PSC_POWER] = 0;
info->R[PSC_POWER] = -1;
if (device_config & ADM1275_IOUT_WARN2_SELECT)
data->have_oc_fault = true;
else
data->have_uc_fault = true;
data->have_pin_max = true;
data->have_vaux_status = true;
coefficients = adm1075_coefficients;
vindex = 0;
switch (config & ADM1075_IRANGE_MASK) {
case ADM1075_IRANGE_25:
info->m[PSC_POWER] = 8549;
info->m[PSC_CURRENT_OUT] = 806;
cindex = 1;
pindex = 3;
break;
case ADM1075_IRANGE_50:
info->m[PSC_POWER] = 4279;
info->m[PSC_CURRENT_OUT] = 404;
cindex = 2;
pindex = 4;
break;
default:
dev_err(&client->dev, "Invalid input current range");
info->m[PSC_POWER] = 0;
info->m[PSC_CURRENT_OUT] = 0;
break;
}
info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
| PMBUS_HAVE_STATUS_INPUT;
if (config & ADM1275_VIN_VOUT_SELECT)
......@@ -352,6 +424,16 @@ static int adm1275_probe(struct i2c_client *client,
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
break;
case adm1275:
if (device_config & ADM1275_IOUT_WARN2_SELECT)
data->have_oc_fault = true;
else
data->have_uc_fault = true;
data->have_vout = true;
coefficients = adm1275_coefficients;
vindex = (config & ADM1275_VRANGE) ? 0 : 1;
cindex = 2;
if (config & ADM1275_VIN_VOUT_SELECT)
info->func[0] |=
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
......@@ -360,22 +442,100 @@ static int adm1275_probe(struct i2c_client *client,
PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
break;
case adm1276:
info->format[PSC_POWER] = direct;
if (device_config & ADM1275_IOUT_WARN2_SELECT)
data->have_oc_fault = true;
else
data->have_uc_fault = true;
data->have_vout = true;
data->have_pin_max = true;
coefficients = adm1276_coefficients;
vindex = (config & ADM1275_VRANGE) ? 0 : 1;
cindex = 2;
pindex = (config & ADM1275_VRANGE) ? 3 : 4;
info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
| PMBUS_HAVE_STATUS_INPUT;
if (config & ADM1275_VIN_VOUT_SELECT)
info->func[0] |=
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
if (config & ADM1275_VRANGE) {
info->m[PSC_POWER] = 6043;
info->b[PSC_POWER] = 0;
info->R[PSC_POWER] = -2;
} else {
info->m[PSC_POWER] = 2115;
info->b[PSC_POWER] = 0;
info->R[PSC_POWER] = -1;
break;
case adm1293:
case adm1294:
data->have_iout_min = true;
data->have_pin_min = true;
data->have_pin_max = true;
data->have_mfr_vaux_status = true;
coefficients = adm1293_coefficients;
voindex = 0;
switch (config & ADM1293_VIN_SEL_MASK) {
case ADM1293_VIN_SEL_012: /* 1.2V */
vindex = 0;
break;
case ADM1293_VIN_SEL_074: /* 7.4V */
vindex = 1;
break;
case ADM1293_VIN_SEL_210: /* 21V */
vindex = 2;
break;
default: /* disabled */
break;
}
switch (config & ADM1293_IRANGE_MASK) {
case ADM1293_IRANGE_25:
cindex = 3;
break;
case ADM1293_IRANGE_50:
cindex = 4;
break;
case ADM1293_IRANGE_100:
cindex = 5;
break;
case ADM1293_IRANGE_200:
cindex = 6;
break;
}
if (vindex >= 0)
pindex = 7 + vindex * 4 + (cindex - 3);
if (config & ADM1293_VAUX_EN)
info->func[0] |=
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
info->func[0] |= PMBUS_HAVE_PIN |
PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
break;
default:
dev_err(&client->dev, "Unsupported device\n");
return -ENODEV;
}
if (voindex < 0)
voindex = vindex;
if (vindex >= 0) {
info->m[PSC_VOLTAGE_IN] = coefficients[vindex].m;
info->b[PSC_VOLTAGE_IN] = coefficients[vindex].b;
info->R[PSC_VOLTAGE_IN] = coefficients[vindex].R;
}
if (voindex >= 0) {
info->m[PSC_VOLTAGE_OUT] = coefficients[voindex].m;
info->b[PSC_VOLTAGE_OUT] = coefficients[voindex].b;
info->R[PSC_VOLTAGE_OUT] = coefficients[voindex].R;
}
if (cindex >= 0) {
info->m[PSC_CURRENT_OUT] = coefficients[cindex].m;
info->b[PSC_CURRENT_OUT] = coefficients[cindex].b;
info->R[PSC_CURRENT_OUT] = coefficients[cindex].R;
}
if (pindex >= 0) {
info->m[PSC_POWER] = coefficients[pindex].m;
info->b[PSC_POWER] = coefficients[pindex].b;
info->R[PSC_POWER] = coefficients[pindex].R;
}
return pmbus_do_probe(client, id, info);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment