提交 c560dc87 编写于 作者: L Linus Torvalds

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

Pull hwmon updates from Guenter Roeck:

 - New drivers for MAX6697 and compatibles and for INA209.

 - Added support for IT8771E, IT8772E, MAX34460, MAX34461, MCP98244, and
   ADT7420 to existing drivers.

 - Added support for additional attributes to various drivers.

 - Replaced SENSORS_LIMIT with clamp_val; retire SENSORS_LIMIT;

 - Clean up PMBus code to reduce its size; clean up adt7410 driver.

 - A couple of minor bug fixes as well as documentation cleanup.

 - Out-of-tree change: Replace SENSORS_LIMIT with clamp_val in
   platform/x86/eeepc-laptop driver.

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (32 commits)
  hwmon: (ntc_thermistor): Fix sparse warnings
  hwmon: (adt7410) Add device table entry for the adt7420
  hwmon: (adt7410) Use I2C_ADDRS helper macro
  hwmon: (adt7410) Use the SIMPLE_DEV_PM_OPS helper macro
  hwmon: (adt7410) Let suspend/resume depend on CONFIG_PM_SLEEP
  hwmon: (adt7410) Clear unwanted bits in the config register
  hwmon: (jc42) Add support for MCP98244
  hwmon: (pmbus) Clean up for code size reduction
  hwmon: (pmbus/max34440) Add support for MAX34460 and MAX34461
  hwmon: (pmbus) Add support for word status register
  hwmon: (pmbus/zl6100) Add support for VMON/VDRV
  hwmon: (pmbus) Add function to clear sensor cache
  hwmon: (pmbus) Add support for additional voltage sensor
  hwmon: (pmbus) Use krealloc to allocate attribute memory
  hwmon: (pmbus) Simplify memory allocation for sensor attributes
  hwmon: (pmbus) Improve boolean handling
  hwmon: (pmbus) Simplify memory allocation for labels and booleans
  hwmon: (pmbus) Use dev variable to represent client->dev
  hwmon: (pmbus) Fix 'Macros with multiple statements' checkpatch error
  hwmon: (pmbus) Drop unnecessary error messages in probe error path
  ...
ina209 properties
Required properties:
- compatible: Must be "ti,ina209"
- reg: I2C address
Optional properties:
- shunt-resistor
Shunt resistor value in micro-Ohm
Example:
temp-sensor@4c {
compatible = "ti,ina209";
reg = <0x4c>;
shunt-resistor = <5000>;
};
max6697 properties
Required properties:
- compatible:
Should be one of
maxim,max6581
maxim,max6602
maxim,max6622
maxim,max6636
maxim,max6689
maxim,max6693
maxim,max6694
maxim,max6697
maxim,max6698
maxim,max6699
- reg: I2C address
Optional properties:
- smbus-timeout-disable
Set to disable SMBus timeout. If not specified, SMBus timeout will be
enabled.
- extended-range-enable
Only valid for MAX6581. Set to enable extended temperature range.
Extended temperature will be disabled if not specified.
- beta-compensation-enable
Only valid for MAX6693 and MX6694. Set to enable beta compensation on
remote temperature channel 1.
Beta compensation will be disabled if not specified.
- alert-mask
Alert bit mask. Alert disabled for bits set.
Select bit 0 for local temperature, bit 1..7 for remote temperatures.
If not specified, alert will be enabled for all channels.
- over-temperature-mask
Over-temperature bit mask. Over-temperature reporting disabled for
bits set.
Select bit 0 for local temperature, bit 1..7 for remote temperatures.
If not specified, over-temperature reporting will be enabled for all
channels.
- resistance-cancellation
Boolean for all chips other than MAX6581. Set to enable resistance
cancellation on remote temperature channel 1.
For MAX6581, resistance cancellation enabled for all channels if
specified as boolean, otherwise as per bit mask specified.
Only supported for remote temperatures (bit 1..7).
If not specified, resistance cancellation will be disabled for all
channels.
- transistor-ideality
For MAX6581 only. Two values; first is bit mask, second is ideality
select value as per MAX6581 data sheet. Select bit 1..7 for remote
channels.
Transistor ideality will be initialized to default (1.008) if not
specified.
Example:
temp-sensor@1a {
compatible = "maxim,max6697";
reg = <0x1a>;
smbus-timeout-disable;
resistance-cancellation;
alert-mask = <0x72>;
over-temperature-mask = <0x7f>;
};
......@@ -66,6 +66,7 @@ Process Processor TjMax(C)
i5 3470T 91
32nm Core i3/i5/i7 Processors
i7 2600 98
i7 660UM/640/620, 640LM/620, 620M, 610E 105
i5 540UM/520/430, 540M/520/450/430 105
i3 330E, 370M/350/330 90 rPGA, 105 BGA
......@@ -79,7 +80,10 @@ Process Processor TjMax(C)
P4505/P4500 90
32nm Atom Processors
S1260/1220 95
S1240 102
Z2460 90
Z2760 90
D2700/2550/2500 100
N2850/2800/2650/2600 100
......@@ -98,6 +102,7 @@ Process Processor TjMax(C)
45nm Atom Processors
D525/510/425/410 100
K525/510/425/410 100
Z670/650 90
Z560/550/540/530P/530/520PT/520/515/510PT/510P 90
Z510/500 90
......@@ -107,7 +112,11 @@ Process Processor TjMax(C)
330/230 125
E680/660/640/620 90
E680T/660T/640T/620T 110
E665C/645C 90
E665CT/645CT 110
CE4170/4150/4110 110
CE4200 series unknown
CE5300 series unknown
45nm Core2 Processors
Solo ULV SU3500/3300 100
......
Kernel driver ina209
=====================
Supported chips:
* Burr-Brown / Texas Instruments INA209
Prefix: 'ina209'
Addresses scanned: -
Datasheet:
http://www.ti.com/lit/gpn/ina209
Author: Paul Hays <Paul.Hays@cattail.ca>
Author: Ira W. Snyder <iws@ovro.caltech.edu>
Author: Guenter Roeck <linux@roeck-us.net>
Description
-----------
The TI / Burr-Brown INA209 monitors voltage, current, and power on the high side
of a D.C. power supply. It can perform measurements and calculations in the
background to supply readings at any time. It includes a programmable
calibration multiplier to scale the displayed current and power values.
Sysfs entries
-------------
The INA209 chip is highly configurable both via hardwiring and via
the I2C bus. See the datasheet for details.
This tries to expose most monitoring features of the hardware via
sysfs. It does not support every feature of this chip.
in0_input shunt voltage (mV)
in0_input_highest shunt voltage historical maximum reading (mV)
in0_input_lowest shunt voltage historical minimum reading (mV)
in0_reset_history reset shunt voltage history
in0_max shunt voltage max alarm limit (mV)
in0_min shunt voltage min alarm limit (mV)
in0_crit_max shunt voltage crit max alarm limit (mV)
in0_crit_min shunt voltage crit min alarm limit (mV)
in0_max_alarm shunt voltage max alarm limit exceeded
in0_min_alarm shunt voltage min alarm limit exceeded
in0_crit_max_alarm shunt voltage crit max alarm limit exceeded
in0_crit_min_alarm shunt voltage crit min alarm limit exceeded
in1_input bus voltage (mV)
in1_input_highest bus voltage historical maximum reading (mV)
in1_input_lowest bus voltage historical minimum reading (mV)
in1_reset_history reset bus voltage history
in1_max bus voltage max alarm limit (mV)
in1_min bus voltage min alarm limit (mV)
in1_crit_max bus voltage crit max alarm limit (mV)
in1_crit_min bus voltage crit min alarm limit (mV)
in1_max_alarm bus voltage max alarm limit exceeded
in1_min_alarm bus voltage min alarm limit exceeded
in1_crit_max_alarm bus voltage crit max alarm limit exceeded
in1_crit_min_alarm bus voltage crit min alarm limit exceeded
power1_input power measurement (uW)
power1_input_highest power historical maximum reading (uW)
power1_reset_history reset power history
power1_max power max alarm limit (uW)
power1_crit power crit alarm limit (uW)
power1_max_alarm power max alarm limit exceeded
power1_crit_alarm power crit alarm limit exceeded
curr1_input current measurement (mA)
update_interval data conversion time; affects number of samples used
to average results for shunt and bus voltages.
General Remarks
---------------
The power and current registers in this chip require that the calibration
register is programmed correctly before they are used. Normally this is expected
to be done in the BIOS. In the absence of BIOS programming, the shunt resistor
voltage can be provided using platform data. The driver uses platform data from
the ina2xx driver for this purpose. If calibration register data is not provided
via platform data, the driver checks if the calibration register has been
programmed (ie has a value not equal to zero). If so, this value is retained.
Otherwise, a default value reflecting a shunt resistor value of 10 mOhm is
programmed into the calibration register.
Output Pins
-----------
Output pin programming is a board feature which depends on the BIOS. It is
outside the scope of a hardware monitoring driver to enable or disable output
pins.
......@@ -30,6 +30,14 @@ Supported chips:
Prefix: 'it8728'
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)
Datasheet: Not publicly available
* IT8772E
Prefix: 'it8772'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not publicly available
* IT8782F
Prefix: 'it8782'
Addresses scanned: from Super I/O config space (8 I/O ports)
......@@ -83,8 +91,8 @@ Description
-----------
This driver implements support for the IT8705F, IT8712F, IT8716F,
IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8781F, IT8782F,
IT8783E/F, and SiS950 chips.
IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8771E, IT8772E,
IT8782F, IT8783E/F, and SiS950 chips.
These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
joysticks and other miscellaneous stuff. For hardware monitoring, they
......@@ -118,8 +126,8 @@ The IT8726F is just bit enhanced IT8716F with additional hardware
for AMD power sequencing. Therefore the chip will appear as IT8716F
to userspace applications.
The IT8728F is considered compatible with the IT8721F, until a datasheet
becomes available (hopefully.)
The IT8728F, IT8771E, and IT8772E are considered compatible with the IT8721F,
until a datasheet becomes available (hopefully.)
Temperatures are measured in degrees Celsius. An alarm is triggered once
when the Overtemperature Shutdown limit is crossed.
......
......@@ -17,12 +17,13 @@ Supported chips:
* Maxim MAX6604
Datasheets:
http://datasheets.maxim-ic.com/en/ds/MAX6604.pdf
* Microchip MCP9804, MCP9805, MCP98242, MCP98243, MCP9843
* Microchip MCP9804, MCP9805, MCP98242, MCP98243, MCP98244, MCP9843
Datasheets:
http://ww1.microchip.com/downloads/en/DeviceDoc/22203C.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/21977b.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/21996a.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/22153c.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/22327A.pdf
* NXP Semiconductors SE97, SE97B, SE98, SE98A
Datasheets:
http://www.nxp.com/documents/data_sheet/SE97.pdf
......
Kernel driver lm73
==================
Supported chips:
* Texas Instruments LM73
Prefix: 'lm73'
Addresses scanned: I2C 0x48, 0x49, 0x4a, 0x4c, 0x4d, and 0x4e
Datasheet: Publicly available at the Texas Instruments website
http://www.ti.com/product/lm73
Author: Guillaume Ligneul <guillaume.ligneul@gmail.com>
Documentation: Chris Verges <kg4ysn@gmail.com>
Description
-----------
The LM73 is a digital temperature sensor. All temperature values are
given in degrees Celsius.
Measurement Resolution Support
------------------------------
The LM73 supports four resolutions, defined in terms of degrees C per
LSB: 0.25, 0.125, 0.0625, and 0.3125. Changing the resolution mode
affects the conversion time of the LM73's analog-to-digital converter.
From userspace, the desired resolution can be specified as a function of
conversion time via the 'update_interval' sysfs attribute for the
device. This attribute will normalize ranges of input values to the
maximum times defined for the resolution in the datasheet.
Resolution Conv. Time Input Range
(C/LSB) (msec) (msec)
--------------------------------------
0.25 14 0..14
0.125 28 15..28
0.0625 56 29..56
0.03125 112 57..infinity
--------------------------------------
The following examples show how the 'update_interval' attribute can be
used to change the conversion time:
$ echo 0 > update_interval
$ cat update_interval
14
$ cat temp1_input
24250
$ echo 22 > update_interval
$ cat update_interval
28
$ cat temp1_input
24125
$ echo 56 > update_interval
$ cat update_interval
56
$ cat temp1_input
24062
$ echo 85 > update_interval
$ cat update_interval
112
$ cat temp1_input
24031
As shown here, the lm73 driver automatically adjusts any user input for
'update_interval' via a step function. Reading back the
'update_interval' value after a write operation will confirm the
conversion time actively in use.
Mathematically, the resolution can be derived from the conversion time
via the following function:
g(x) = 0.250 * [log(x/14) / log(2)]
where 'x' is the output from 'update_interval' and 'g(x)' is the
resolution in degrees C per LSB.
Alarm Support
-------------
The LM73 features a simple over-temperature alarm mechanism. This
feature is exposed via the sysfs attributes.
The attributes 'temp1_max_alarm' and 'temp1_min_alarm' are flags
provided by the LM73 that indicate whether the measured temperature has
passed the 'temp1_max' and 'temp1_min' thresholds, respectively. These
values _must_ be read to clear the registers on the LM73.
......@@ -16,6 +16,16 @@ Supported chips:
Prefixes: 'max34446'
Addresses scanned: -
Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34446.pdf
* Maxim MAX34460
PMBus 12-Channel Voltage Monitor & Sequencer
Prefix: 'max34460'
Addresses scanned: -
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34460.pdf
* Maxim MAX34461
PMBus 16-Channel Voltage Monitor & Sequencer
Prefix: 'max34461'
Addresses scanned: -
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34461.pdf
Author: Guenter Roeck <guenter.roeck@ericsson.com>
......@@ -26,6 +36,9 @@ Description
This driver supports hardware montoring for Maxim MAX34440 PMBus 6-Channel
Power-Supply Manager, MAX34441 PMBus 5-Channel Power-Supply Manager
and Intelligent Fan Controller, and MAX34446 PMBus Power-Supply Data Logger.
It also supports the MAX34460 and MAX34461 PMBus Voltage Monitor & Sequencers.
The MAX34460 supports 12 voltage channels, and the MAX34461 supports 16 voltage
channels.
The driver is a client driver to the core PMBus driver. Please see
Documentation/hwmon/pmbus for details on PMBus client drivers.
......@@ -109,3 +122,6 @@ temp[1-8]_reset_history Write any value to reset history.
temp7 and temp8 attributes only exist for MAX34440.
MAX34446 only supports temp[1-3].
MAX34460 supports attribute groups in[1-12] and temp[1-5].
MAX34461 supports attribute groups in[1-16] and temp[1-5].
Kernel driver max6697
=====================
Supported chips:
* Maxim MAX6581
Prefix: 'max6581'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6581.pdf
* Maxim MAX6602
Prefix: 'max6602'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6602.pdf
* Maxim MAX6622
Prefix: 'max6622'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6622.pdf
* Maxim MAX6636
Prefix: 'max6636'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6636.pdf
* Maxim MAX6689
Prefix: 'max6689'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6689.pdf
* Maxim MAX6693
Prefix: 'max6693'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6693.pdf
* Maxim MAX6694
Prefix: 'max6694'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6694.pdf
* Maxim MAX6697
Prefix: 'max6697'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6697.pdf
* Maxim MAX6698
Prefix: 'max6698'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6698.pdf
* Maxim MAX6699
Prefix: 'max6699'
Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6699.pdf
Author:
Guenter Roeck <linux@roeck-us.net>
Description
-----------
This driver implements support for several MAX6697 compatible temperature sensor
chips. The chips support one local temperature sensor plus four, six, or seven
remote temperature sensors. Remote temperature sensors are diode-connected
thermal transitors, except for MAX6698 which supports three diode-connected
thermal transistors plus three thermistors in addition to the local temperature
sensor.
The driver provides the following sysfs attributes. temp1 is the local (chip)
temperature, temp[2..n] are remote temperatures. The actually supported
per-channel attributes are chip type and channel dependent.
tempX_input RO temperature
tempX_max RW temperature maximum threshold
tempX_max_alarm RO temperature maximum threshold alarm
tempX_crit RW temperature critical threshold
tempX_crit_alarm RO temperature critical threshold alarm
tempX_fault RO temperature diode fault (remote sensors only)
......@@ -722,14 +722,14 @@ add/subtract if it has been divided before the add/subtract.
What to do if a value is found to be invalid, depends on the type of the
sysfs attribute that is being set. If it is a continuous setting like a
tempX_max or inX_max attribute, then the value should be clamped to its
limits using SENSORS_LIMIT(value, min_limit, max_limit). If it is not
continuous like for example a tempX_type, then when an invalid value is
written, -EINVAL should be returned.
limits using clamp_val(value, min_limit, max_limit). If it is not continuous
like for example a tempX_type, then when an invalid value is written,
-EINVAL should be returned.
Example1, temp1_max, register is a signed 8 bit value (-128 - 127 degrees):
long v = simple_strtol(buf, NULL, 10) / 1000;
v = SENSORS_LIMIT(v, -128, 127);
v = clamp_val(v, -128, 127);
/* write v to register */
Example2, fan divider setting, valid values 2, 4 and 8:
......
......@@ -121,12 +121,26 @@ in1_max_alarm Input voltage high alarm.
in1_lcrit_alarm Input voltage critical low alarm.
in1_crit_alarm Input voltage critical high alarm.
in2_label "vout1"
in2_input Measured output voltage.
in2_lcrit Critical minimum output Voltage.
in2_crit Critical maximum output voltage.
in2_lcrit_alarm Critical output voltage critical low alarm.
in2_crit_alarm Critical output voltage critical high alarm.
in2_label "vmon"
in2_input Measured voltage on VMON (ZL2004) or VDRV (ZL9101M,
ZL9117M) pin. Reported voltage is 16x the voltage on the
pin (adjusted internally by the chip).
in2_lcrit Critical minumum VMON/VDRV Voltage.
in2_crit Critical maximum VMON/VDRV voltage.
in2_lcrit_alarm VMON/VDRV voltage critical low alarm.
in2_crit_alarm VMON/VDRV voltage critical high alarm.
vmon attributes are supported on ZL2004, ZL9101M,
and ZL9117M only.
inX_label "vout1"
inX_input Measured output voltage.
inX_lcrit Critical minimum output Voltage.
inX_crit Critical maximum output voltage.
inX_lcrit_alarm Critical output voltage critical low alarm.
inX_crit_alarm Critical output voltage critical high alarm.
X is 3 for ZL2004, ZL9101M, and ZL9117M, 2 otherwise.
curr1_label "iout1"
curr1_input Measured output current.
......
......@@ -180,11 +180,11 @@ config SENSORS_ADM9240
will be called adm9240.
config SENSORS_ADT7410
tristate "Analog Devices ADT7410"
tristate "Analog Devices ADT7410/ADT7420"
depends on I2C
help
If you say yes here you get support for the Analog Devices
ADT7410 temperature monitoring chip.
ADT7410 and ADT7420 temperature monitoring chips.
This driver can also be built as a module. If so, the module
will be called adt7410.
......@@ -506,7 +506,8 @@ config SENSORS_IT87
help
If you say yes here you get support for ITE IT8705F, IT8712F,
IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E,
IT8782F, and IT8783E/F sensor chips, and the SiS950 clone.
IT8771E, IT8772E, IT8782F, and IT8783E/F sensor chips, and the
SiS950 clone.
This driver can also be built as a module. If so, the module
will be called it87.
......@@ -529,8 +530,8 @@ config SENSORS_JC42
temperature sensors, which are used on many DDR3 memory modules for
mobile devices and servers. Support will include, but not be limited
to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805,
MCP98242, MCP98243, MCP9843, SE97, SE98, STTS424(E), STTS2002,
STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2.
MCP98242, MCP98243, MCP98244, MCP9843, SE97, SE98, STTS424(E),
STTS2002, STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2.
This driver can also be built as a module. If so, the module
will be called jc42.
......@@ -854,6 +855,17 @@ config SENSORS_MAX6650
This driver can also be built as a module. If so, the module
will be called max6650.
config SENSORS_MAX6697
tristate "Maxim MAX6697 and compatibles"
depends on I2C
help
If you say yes here you get support for MAX6581, MAX6602, MAX6622,
MAX6636, MAX6689, MAX6693, MAX6694, MAX6697, MAX6698, and MAX6699
temperature sensor chips.
This driver can also be built as a module. If so, the module
will be called max6697.
config SENSORS_MCP3021
tristate "Microchip MCP3021 and compatibles"
depends on I2C
......@@ -1145,6 +1157,16 @@ config SENSORS_AMC6821
This driver can also be build as a module. If so, the module
will be called amc6821.
config SENSORS_INA209
tristate "TI / Burr Brown INA209"
depends on I2C
help
If you say yes here you get support for the TI / Burr Brown INA209
voltage / current / power monitor I2C interface.
This driver can also be built as a module. If so, the module will
be called ina209.
config SENSORS_INA2XX
tristate "Texas Instruments INA219 and compatibles"
depends on I2C
......
......@@ -65,6 +65,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
obj-$(CONFIG_SENSORS_INA209) += ina209.o
obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_JC42) += jc42.o
......@@ -99,6 +100,7 @@ obj-$(CONFIG_SENSORS_MAX197) += max197.o
obj-$(CONFIG_SENSORS_MAX6639) += max6639.o
obj-$(CONFIG_SENSORS_MAX6642) += max6642.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_MAX6697) += max6697.o
obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o
obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
......
......@@ -137,7 +137,7 @@ static ssize_t set_max_min(struct device *dev,
if (ret < 0)
return ret;
temp = SENSORS_LIMIT(temp, -40000, 85000);
temp = clamp_val(temp, -40000, 85000);
temp = (temp + (temp < 0 ? -500 : 500)) / 1000;
mutex_lock(&data->lock);
......
......@@ -193,7 +193,7 @@ static ssize_t set_temp_max(struct device *dev,
temp /= 1000;
mutex_lock(&data->update_lock);
data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127);
data->temp_max[index] = clamp_val(temp, -128, 127);
if (!read_only)
i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index),
data->temp_max[index]);
......@@ -218,7 +218,7 @@ static ssize_t set_temp_min(struct device *dev,
temp /= 1000;
mutex_lock(&data->update_lock);
data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127);
data->temp_min[index] = clamp_val(temp, -128, 127);
if (!read_only)
i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index),
data->temp_min[index]);
......
......@@ -197,7 +197,7 @@ static int adm1026_scaling[] = { /* .001 Volts */
};
#define NEG12_OFFSET 16000
#define SCALE(val, from, to) (((val)*(to) + ((from)/2))/(from))
#define INS_TO_REG(n, val) (SENSORS_LIMIT(SCALE(val, adm1026_scaling[n], 192),\
#define INS_TO_REG(n, val) (clamp_val(SCALE(val, adm1026_scaling[n], 192),\
0, 255))
#define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n]))
......@@ -207,7 +207,7 @@ static int adm1026_scaling[] = { /* .001 Volts */
* 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000
*/
#define FAN_TO_REG(val, div) ((val) <= 0 ? 0xff : \
SENSORS_LIMIT(1350000 / ((val) * (div)), \
clamp_val(1350000 / ((val) * (div)), \
1, 254))
#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 0xff ? 0 : \
1350000 / ((val) * (div)))
......@@ -215,14 +215,14 @@ static int adm1026_scaling[] = { /* .001 Volts */
#define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0)
/* Temperature is reported in 1 degC increments */
#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \
#define TEMP_TO_REG(val) (clamp_val(((val) + ((val) < 0 ? -500 : 500)) \
/ 1000, -127, 127))
#define TEMP_FROM_REG(val) ((val) * 1000)
#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \
#define OFFSET_TO_REG(val) (clamp_val(((val) + ((val) < 0 ? -500 : 500)) \
/ 1000, -127, 127))
#define OFFSET_FROM_REG(val) ((val) * 1000)
#define PWM_TO_REG(val) (SENSORS_LIMIT(val, 0, 255))
#define PWM_TO_REG(val) (clamp_val(val, 0, 255))
#define PWM_FROM_REG(val) (val)
#define PWM_MIN_TO_REG(val) ((val) & 0xf0)
......@@ -233,7 +233,7 @@ static int adm1026_scaling[] = { /* .001 Volts */
* indicates that the DAC could be used to drive the fans, but in our
* example board (Arima HDAMA) it isn't connected to the fans at all.
*/
#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val) * 255) + 500) / 2500), 0, 255))
#define DAC_TO_REG(val) (clamp_val(((((val) * 255) + 500) / 2500), 0, 255))
#define DAC_FROM_REG(val) (((val) * 2500) / 255)
/*
......@@ -933,7 +933,7 @@ static void fixup_fan_min(struct device *dev, int fan, int old_div)
return;
new_min = data->fan_min[fan] * old_div / new_div;
new_min = SENSORS_LIMIT(new_min, 1, 254);
new_min = clamp_val(new_min, 1, 254);
data->fan_min[fan] = new_min;
adm1026_write_value(client, ADM1026_REG_FAN_MIN(fan), new_min);
}
......@@ -1527,7 +1527,7 @@ static ssize_t set_auto_pwm_min(struct device *dev,
return err;
mutex_lock(&data->update_lock);
data->pwm1.auto_pwm_min = SENSORS_LIMIT(val, 0, 255);
data->pwm1.auto_pwm_min = clamp_val(val, 0, 255);
if (data->pwm1.enable == 2) { /* apply immediately */
data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
PWM_MIN_TO_REG(data->pwm1.auto_pwm_min));
......
......@@ -162,13 +162,13 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
static int FAN_TO_REG(int reg, int div)
{
int tmp;
tmp = FAN_FROM_REG(SENSORS_LIMIT(reg, 0, 65535), div);
tmp = FAN_FROM_REG(clamp_val(reg, 0, 65535), div);
return tmp > 255 ? 255 : tmp;
}
#define FAN_DIV_FROM_REG(reg) (1<<(((reg)&0xc0)>>6))
#define PWM_TO_REG(val) (SENSORS_LIMIT((val), 0, 255) >> 4)
#define PWM_TO_REG(val) (clamp_val((val), 0, 255) >> 4)
#define PWM_FROM_REG(val) ((val) << 4)
#define FAN_CHAN_FROM_REG(reg) (((reg) >> 5) & 7)
......@@ -675,7 +675,7 @@ static ssize_t set_temp_offset(struct device *dev,
if (ret)
return ret;
val = SENSORS_LIMIT(val, -15000, 15000);
val = clamp_val(val, -15000, 15000);
mutex_lock(&data->update_lock);
data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr),
......@@ -696,7 +696,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
mutex_lock(&data->update_lock);
data->temp_min[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
......@@ -717,7 +717,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
mutex_lock(&data->update_lock);
data->temp_max[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
......@@ -738,7 +738,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
mutex_lock(&data->update_lock);
data->temp_crit[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
......
......@@ -98,13 +98,13 @@ static inline unsigned int IN_FROM_REG(u8 reg, int n)
static inline u8 IN_TO_REG(unsigned long val, int n)
{
return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255);
return clamp_val(SCALE(val, 192, nom_mv[n]), 0, 255);
}
/* temperature range: -40..125, 127 disables temperature alarm */
static inline s8 TEMP_TO_REG(long val)
{
return SENSORS_LIMIT(SCALE(val, 1, 1000), -40, 127);
return clamp_val(SCALE(val, 1, 1000), -40, 127);
}
/* two fans, each with low fan speed limit */
......@@ -122,7 +122,7 @@ static inline unsigned int FAN_FROM_REG(u8 reg, u8 div)
/* analog out 0..1250mV */
static inline u8 AOUT_TO_REG(unsigned long val)
{
return SENSORS_LIMIT(SCALE(val, 255, 1250), 0, 255);
return clamp_val(SCALE(val, 255, 1250), 0, 255);
}
static inline unsigned int AOUT_FROM_REG(u8 reg)
......
......@@ -163,9 +163,9 @@ static int ads7828_probe(struct i2c_client *client,
/* Bound Vref with min/max values if it was provided */
if (data->vref_mv)
data->vref_mv = SENSORS_LIMIT(data->vref_mv,
ADS7828_EXT_VREF_MV_MIN,
ADS7828_EXT_VREF_MV_MAX);
data->vref_mv = clamp_val(data->vref_mv,
ADS7828_EXT_VREF_MV_MIN,
ADS7828_EXT_VREF_MV_MAX);
else
data->vref_mv = ADS7828_INT_VREF_MV;
......
......@@ -78,10 +78,6 @@ enum adt7410_type { /* keep sorted in alphabetical order */
adt7410,
};
/* Addresses scanned */
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
I2C_CLIENT_END };
static const u8 ADT7410_REG_TEMP[4] = {
ADT7410_TEMPERATURE, /* input */
ADT7410_T_ALARM_HIGH, /* high */
......@@ -173,8 +169,8 @@ static struct adt7410_data *adt7410_update_device(struct device *dev)
static s16 ADT7410_TEMP_TO_REG(long temp)
{
return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, ADT7410_TEMP_MIN,
ADT7410_TEMP_MAX) * 128, 1000);
return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN,
ADT7410_TEMP_MAX) * 128, 1000);
}
static int ADT7410_REG_TO_TEMP(struct adt7410_data *data, s16 reg)
......@@ -269,9 +265,9 @@ static ssize_t adt7410_set_t_hyst(struct device *dev,
return ret;
/* convert absolute hysteresis value to a 4 bit delta value */
limit = ADT7410_REG_TO_TEMP(data, data->temp[1]);
hyst = SENSORS_LIMIT(hyst, ADT7410_TEMP_MIN, ADT7410_TEMP_MAX);
data->hyst = SENSORS_LIMIT(DIV_ROUND_CLOSEST(limit - hyst, 1000),
0, ADT7410_T_HYST_MASK);
hyst = clamp_val(hyst, ADT7410_TEMP_MIN, ADT7410_TEMP_MAX);
data->hyst = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), 0,
ADT7410_T_HYST_MASK);
ret = i2c_smbus_write_byte_data(client, ADT7410_T_HYST, data->hyst);
if (ret)
return ret;
......@@ -364,6 +360,7 @@ static int adt7410_probe(struct i2c_client *client,
/*
* Set to 16 bit resolution, continous conversion and comparator mode.
*/
ret &= ~ADT7410_MODE_MASK;
data->config = ret | ADT7410_FULL | ADT7410_RESOLUTION |
ADT7410_EVENT_MODE;
if (data->config != data->oldconfig) {
......@@ -410,11 +407,12 @@ static int adt7410_remove(struct i2c_client *client)
static const struct i2c_device_id adt7410_ids[] = {
{ "adt7410", adt7410, },
{ "adt7420", adt7410, },
{ /* LIST END */ }
};
MODULE_DEVICE_TABLE(i2c, adt7410_ids);
#ifdef CONFIG_PM
#ifdef CONFIG_PM_SLEEP
static int adt7410_suspend(struct device *dev)
{
int ret;
......@@ -436,10 +434,8 @@ static int adt7410_resume(struct device *dev)
return ret;
}
static const struct dev_pm_ops adt7410_dev_pm_ops = {
.suspend = adt7410_suspend,
.resume = adt7410_resume,
};
static SIMPLE_DEV_PM_OPS(adt7410_dev_pm_ops, adt7410_suspend, adt7410_resume);
#define ADT7410_DEV_PM_OPS (&adt7410_dev_pm_ops)
#else
#define ADT7410_DEV_PM_OPS NULL
......@@ -454,11 +450,11 @@ static struct i2c_driver adt7410_driver = {
.probe = adt7410_probe,
.remove = adt7410_remove,
.id_table = adt7410_ids,
.address_list = normal_i2c,
.address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b),
};
module_i2c_driver(adt7410_driver);
MODULE_AUTHOR("Hartmut Knaack");
MODULE_DESCRIPTION("ADT7410 driver");
MODULE_DESCRIPTION("ADT7410/ADT7420 driver");
MODULE_LICENSE("GPL");
......@@ -836,7 +836,7 @@ static ssize_t set_temp_min(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000) + 64;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->temp_min[attr->index] = temp;
......@@ -874,7 +874,7 @@ static ssize_t set_temp_max(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000) + 64;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->temp_max[attr->index] = temp;
......@@ -939,7 +939,7 @@ static ssize_t set_volt_max(struct device *dev,
temp *= 1000; /* convert mV to uV */
temp = DIV_ROUND_CLOSEST(temp, x);
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->volt_max[attr->index] = temp;
......@@ -981,7 +981,7 @@ static ssize_t set_volt_min(struct device *dev,
temp *= 1000; /* convert mV to uV */
temp = DIV_ROUND_CLOSEST(temp, x);
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->volt_min[attr->index] = temp;
......@@ -1071,7 +1071,7 @@ static ssize_t set_fan_min(struct device *dev,
temp = FAN_RPM_TO_PERIOD(temp);
temp >>= 8;
temp = SENSORS_LIMIT(temp, 1, 255);
temp = clamp_val(temp, 1, 255);
mutex_lock(&data->lock);
data->fan_min[attr->index] = temp;
......@@ -1149,7 +1149,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm[attr->index] = temp;
......@@ -1179,7 +1179,7 @@ static ssize_t set_pwm_max(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm_max = temp;
......@@ -1211,7 +1211,7 @@ static ssize_t set_pwm_min(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm_min[attr->index] = temp;
......@@ -1246,7 +1246,7 @@ static ssize_t set_pwm_hyst(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 15);
temp = clamp_val(temp, 0, 15);
/* package things up */
temp &= ADT7462_PWM_HYST_MASK;
......@@ -1333,7 +1333,7 @@ static ssize_t set_pwm_tmin(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000) + 64;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm_tmin[attr->index] = temp;
......
......@@ -452,7 +452,7 @@ static ssize_t set_auto_update_interval(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 60000);
temp = clamp_val(temp, 0, 60000);
mutex_lock(&data->lock);
data->auto_update_interval = temp;
......@@ -481,7 +481,7 @@ static ssize_t set_num_temp_sensors(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, -1, 10);
temp = clamp_val(temp, -1, 10);
mutex_lock(&data->lock);
data->num_temp_sensors = temp;
......@@ -515,7 +515,7 @@ static ssize_t set_temp_min(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->temp_min[attr->index] = temp;
......@@ -549,7 +549,7 @@ static ssize_t set_temp_max(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->temp_max[attr->index] = temp;
......@@ -604,7 +604,7 @@ static ssize_t set_fan_max(struct device *dev,
return -EINVAL;
temp = FAN_RPM_TO_PERIOD(temp);
temp = SENSORS_LIMIT(temp, 1, 65534);
temp = clamp_val(temp, 1, 65534);
mutex_lock(&data->lock);
data->fan_max[attr->index] = temp;
......@@ -641,7 +641,7 @@ static ssize_t set_fan_min(struct device *dev,
return -EINVAL;
temp = FAN_RPM_TO_PERIOD(temp);
temp = SENSORS_LIMIT(temp, 1, 65534);
temp = clamp_val(temp, 1, 65534);
mutex_lock(&data->lock);
data->fan_min[attr->index] = temp;
......@@ -717,7 +717,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm[attr->index] = temp;
......@@ -749,7 +749,7 @@ static ssize_t set_pwm_max(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm_max[attr->index] = temp;
......@@ -782,7 +782,7 @@ static ssize_t set_pwm_min(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm_min[attr->index] = temp;
......@@ -826,7 +826,7 @@ static ssize_t set_pwm_tmin(struct device *dev,
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 255);
temp = clamp_val(temp, 0, 255);
mutex_lock(&data->lock);
data->pwm_tmin[attr->index] = temp;
......
......@@ -201,10 +201,10 @@ static inline u16 temp2reg(struct adt7475_data *data, long val)
u16 ret;
if (!(data->config5 & CONFIG5_TWOSCOMP)) {
val = SENSORS_LIMIT(val, -64000, 191000);
val = clamp_val(val, -64000, 191000);
ret = (val + 64500) / 1000;
} else {
val = SENSORS_LIMIT(val, -128000, 127000);
val = clamp_val(val, -128000, 127000);
if (val < -500)
ret = (256500 + val) / 1000;
else
......@@ -240,7 +240,7 @@ static inline u16 rpm2tach(unsigned long rpm)
if (rpm == 0)
return 0;
return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF);
return clamp_val((90000 * 60) / rpm, 1, 0xFFFF);
}
/* Scaling factors for voltage inputs, taken from the ADT7490 datasheet */
......@@ -271,7 +271,7 @@ static inline u16 volt2reg(int channel, long volt, u8 bypass_attn)
reg = (volt * 1024) / 2250;
else
reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250);
return SENSORS_LIMIT(reg, 0, 1023) & (0xff << 2);
return clamp_val(reg, 0, 1023) & (0xff << 2);
}
static u16 adt7475_read_word(struct i2c_client *client, int reg)
......@@ -451,10 +451,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
switch (sattr->nr) {
case OFFSET:
if (data->config5 & CONFIG5_TEMPOFFSET) {
val = SENSORS_LIMIT(val, -63000, 127000);
val = clamp_val(val, -63000, 127000);
out = data->temp[OFFSET][sattr->index] = val / 1000;
} else {
val = SENSORS_LIMIT(val, -63000, 64000);
val = clamp_val(val, -63000, 64000);
out = data->temp[OFFSET][sattr->index] = val / 500;
}
break;
......@@ -471,7 +471,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
adt7475_read_hystersis(client);
temp = reg2temp(data, data->temp[THERM][sattr->index]);
val = SENSORS_LIMIT(val, temp - 15000, temp);
val = clamp_val(val, temp - 15000, temp);
val = (temp - val) / 1000;
if (sattr->index != 1) {
......@@ -577,7 +577,7 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr,
* to figure the range
*/
temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]);
val = SENSORS_LIMIT(val, temp + autorange_table[0],
val = clamp_val(val, temp + autorange_table[0],
temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]);
val -= temp;
......@@ -701,7 +701,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
break;
}
data->pwm[sattr->nr][sattr->index] = SENSORS_LIMIT(val, 0, 0xFF);
data->pwm[sattr->nr][sattr->index] = clamp_val(val, 0, 0xFF);
i2c_smbus_write_byte_data(client, reg,
data->pwm[sattr->nr][sattr->index]);
......
......@@ -241,7 +241,7 @@ static ssize_t set_temp(
int ret = kstrtol(buf, 10, &val);
if (ret)
return ret;
val = SENSORS_LIMIT(val / 1000, -128, 127);
val = clamp_val(val / 1000, -128, 127);
mutex_lock(&data->update_lock);
data->temp[ix] = val;
......@@ -332,7 +332,7 @@ static ssize_t set_pwm1(
return ret;
mutex_lock(&data->update_lock);
data->pwm1 = SENSORS_LIMIT(val , 0, 255);
data->pwm1 = clamp_val(val , 0, 255);
i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1);
mutex_unlock(&data->update_lock);
return count;
......@@ -499,11 +499,11 @@ static ssize_t set_temp_auto_point_temp(
mutex_lock(&data->update_lock);
switch (ix) {
case 0:
ptemp[0] = SENSORS_LIMIT(val / 1000, 0,
data->temp1_auto_point_temp[1]);
ptemp[0] = SENSORS_LIMIT(ptemp[0], 0,
data->temp2_auto_point_temp[1]);
ptemp[0] = SENSORS_LIMIT(ptemp[0], 0, 63);
ptemp[0] = clamp_val(val / 1000, 0,
data->temp1_auto_point_temp[1]);
ptemp[0] = clamp_val(ptemp[0], 0,
data->temp2_auto_point_temp[1]);
ptemp[0] = clamp_val(ptemp[0], 0, 63);
if (i2c_smbus_write_byte_data(
client,
AMC6821_REG_PSV_TEMP,
......@@ -515,20 +515,12 @@ static ssize_t set_temp_auto_point_temp(
goto EXIT;
break;
case 1:
ptemp[1] = SENSORS_LIMIT(
val / 1000,
(ptemp[0] & 0x7C) + 4,
124);
ptemp[1] = clamp_val(val / 1000, (ptemp[0] & 0x7C) + 4, 124);
ptemp[1] &= 0x7C;
ptemp[2] = SENSORS_LIMIT(
ptemp[2], ptemp[1] + 1,
255);
ptemp[2] = clamp_val(ptemp[2], ptemp[1] + 1, 255);
break;
case 2:
ptemp[2] = SENSORS_LIMIT(
val / 1000,
ptemp[1]+1,
255);
ptemp[2] = clamp_val(val / 1000, ptemp[1]+1, 255);
break;
default:
dev_dbg(dev, "Unknown attr->index (%d).\n", ix);
......@@ -561,7 +553,7 @@ static ssize_t set_pwm1_auto_point_pwm(
return ret;
mutex_lock(&data->update_lock);
data->pwm1_auto_point_pwm[1] = SENSORS_LIMIT(val, 0, 254);
data->pwm1_auto_point_pwm[1] = clamp_val(val, 0, 254);
if (i2c_smbus_write_byte_data(client, AMC6821_REG_DCY_LOW_TEMP,
data->pwm1_auto_point_pwm[1])) {
dev_err(&client->dev, "Register write error, aborting.\n");
......@@ -629,7 +621,7 @@ static ssize_t set_fan(
val = 1 > val ? 0xFFFF : 6000000/val;
mutex_lock(&data->update_lock);
data->fan[ix] = (u16) SENSORS_LIMIT(val, 1, 0xFFFF);
data->fan[ix] = (u16) clamp_val(val, 1, 0xFFFF);
if (i2c_smbus_write_byte_data(client, fan_reg_low[ix],
data->fan[ix] & 0xFF)) {
dev_err(&client->dev, "Register write error, aborting.\n");
......
......@@ -114,7 +114,7 @@ static const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19};
*/
static u8 IN_TO_REG(unsigned val)
{
unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX);
unsigned nval = clamp_val(val, ASB100_IN_MIN, ASB100_IN_MAX);
return (nval + 8) / 16;
}
......@@ -129,8 +129,8 @@ static u8 FAN_TO_REG(long rpm, int div)
return 0;
if (rpm == 0)
return 255;
rpm = SENSORS_LIMIT(rpm, 1, 1000000);
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
rpm = clamp_val(rpm, 1, 1000000);
return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
}
static int FAN_FROM_REG(u8 val, int div)
......@@ -148,7 +148,7 @@ static int FAN_FROM_REG(u8 val, int div)
*/
static u8 TEMP_TO_REG(long temp)
{
int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX);
int ntemp = clamp_val(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX);
ntemp += (ntemp < 0 ? -500 : 500);
return (u8)(ntemp / 1000);
}
......@@ -164,7 +164,7 @@ static int TEMP_FROM_REG(u8 reg)
*/
static u8 ASB100_PWM_TO_REG(int pwm)
{
pwm = SENSORS_LIMIT(pwm, 0, 255);
pwm = clamp_val(pwm, 0, 255);
return (u8)(pwm / 16);
}
......
......@@ -191,7 +191,7 @@ static ssize_t store_u8(struct device *dev, struct device_attribute *attr,
if (kstrtol(buf, 10, &reqval))
return -EINVAL;
reqval = SENSORS_LIMIT(reqval, 0, 255);
reqval = clamp_val(reqval, 0, 255);
mutex_lock(&data->update_lock);
data->reg[param->msb[0]] = reqval;
......@@ -224,7 +224,7 @@ static ssize_t store_bitmask(struct device *dev,
if (kstrtol(buf, 10, &reqval))
return -EINVAL;
reqval = SENSORS_LIMIT(reqval, 0, param->mask[0]);
reqval = clamp_val(reqval, 0, param->mask[0]);
reqval = (reqval & param->mask[0]) << param->shift[0];
......@@ -274,7 +274,7 @@ static ssize_t store_fan16(struct device *dev,
* generating an alarm.
*/
reqval =
(reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe));
(reqval <= 0 ? 0xffff : clamp_val(5400000 / reqval, 0, 0xfffe));
mutex_lock(&data->update_lock);
data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
......@@ -343,11 +343,11 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
if (kstrtol(buf, 10, &reqval))
return -EINVAL;
reqval = SENSORS_LIMIT(reqval, 0, 0xffff);
reqval = clamp_val(reqval, 0, 0xffff);
reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
reqval = SENSORS_LIMIT(reqval, 0, 0xff);
reqval = clamp_val(reqval, 0, 0xff);
mutex_lock(&data->update_lock);
data->reg[param->msb[0]] = reqval;
......@@ -376,7 +376,7 @@ static ssize_t store_temp8(struct device *dev,
if (kstrtol(buf, 10, &reqval))
return -EINVAL;
reqval = SENSORS_LIMIT(reqval, -127000, 127000);
reqval = clamp_val(reqval, -127000, 127000);
temp = reqval / 1000;
......@@ -432,7 +432,7 @@ static ssize_t store_temp62(struct device *dev,
if (kstrtol(buf, 10, &reqval))
return -EINVAL;
reqval = SENSORS_LIMIT(reqval, -32000, 31750);
reqval = clamp_val(reqval, -32000, 31750);
i = reqval / 1000;
f = reqval - (i * 1000);
temp = i << 2;
......@@ -468,7 +468,7 @@ static ssize_t show_ap2_temp(struct device *dev,
auto_point1 = ((s8) data->reg[param->msb[1]]) * 1000;
regval =
((data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]);
temp = auto_point1 + asc7621_range_map[SENSORS_LIMIT(regval, 0, 15)];
temp = auto_point1 + asc7621_range_map[clamp_val(regval, 0, 15)];
mutex_unlock(&data->update_lock);
return sprintf(buf, "%d\n", temp);
......@@ -489,7 +489,7 @@ static ssize_t store_ap2_temp(struct device *dev,
mutex_lock(&data->update_lock);
auto_point1 = data->reg[param->msb[1]] * 1000;
reqval = SENSORS_LIMIT(reqval, auto_point1 + 2000, auto_point1 + 80000);
reqval = clamp_val(reqval, auto_point1 + 2000, auto_point1 + 80000);
for (i = ARRAY_SIZE(asc7621_range_map) - 1; i >= 0; i--) {
if (reqval >= auto_point1 + asc7621_range_map[i]) {
......@@ -523,7 +523,7 @@ static ssize_t show_pwm_ac(struct device *dev,
regval = config | (altbit << 3);
mutex_unlock(&data->update_lock);
return sprintf(buf, "%u\n", map[SENSORS_LIMIT(regval, 0, 15)]);
return sprintf(buf, "%u\n", map[clamp_val(regval, 0, 15)]);
}
static ssize_t store_pwm_ac(struct device *dev,
......@@ -663,7 +663,7 @@ static ssize_t show_pwm_freq(struct device *dev,
u8 regval =
(data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
regval = SENSORS_LIMIT(regval, 0, 15);
regval = clamp_val(regval, 0, 15);
return sprintf(buf, "%u\n", asc7621_pwm_freq_map[regval]);
}
......@@ -711,7 +711,7 @@ static ssize_t show_pwm_ast(struct device *dev,
u8 regval =
(data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
regval = SENSORS_LIMIT(regval, 0, 7);
regval = clamp_val(regval, 0, 7);
return sprintf(buf, "%u\n", asc7621_pwm_auto_spinup_map[regval]);
......@@ -759,7 +759,7 @@ static ssize_t show_temp_st(struct device *dev,
SETUP_SHOW_data_param(dev, attr);
u8 regval =
(data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
regval = SENSORS_LIMIT(regval, 0, 7);
regval = clamp_val(regval, 0, 7);
return sprintf(buf, "%u\n", asc7621_temp_smoothing_time_map[regval]);
}
......
......@@ -198,7 +198,7 @@ struct tjmax {
static const struct tjmax __cpuinitconst tjmax_table[] = {
{ "CPU 230", 100000 }, /* Model 0x1c, stepping 2 */
{ "CPU 330", 125000 }, /* Model 0x1c, stepping 2 */
{ "CPU CE4110", 110000 }, /* Model 0x1c, stepping 10 */
{ "CPU CE4110", 110000 }, /* Model 0x1c, stepping 10 Sodaville */
{ "CPU CE4150", 110000 }, /* Model 0x1c, stepping 10 */
{ "CPU CE4170", 110000 }, /* Model 0x1c, stepping 10 */
};
......@@ -212,7 +212,7 @@ struct tjmax_model {
#define ANY 0xff
static const struct tjmax_model __cpuinitconst tjmax_model_table[] = {
{ 0x1c, 10, 100000 }, /* D4xx, N4xx, D5xx, N5xx */
{ 0x1c, 10, 100000 }, /* D4xx, K4xx, N4xx, D5xx, K5xx, N5xx */
{ 0x1c, ANY, 90000 }, /* Z5xx, N2xx, possibly others
* Note: Also matches 230 and 330,
* which are covered by tjmax_table
......@@ -222,6 +222,7 @@ static const struct tjmax_model __cpuinitconst tjmax_model_table[] = {
* is undetectable by software
*/
{ 0x27, ANY, 90000 }, /* Atom Medfield (Z2460) */
{ 0x35, ANY, 90000 }, /* Atom Clover Trail/Cloverview (Z2760) */
{ 0x36, ANY, 100000 }, /* Atom Cedar Trail/Cedarview (N2xxx, D2xxx) */
};
......
......@@ -277,7 +277,7 @@ static inline int IN_FROM_REG(int reg, int nominal, int res)
static inline int IN_TO_REG(int val, int nominal)
{
return SENSORS_LIMIT((val * 192 + nominal / 2) / nominal, 0, 255);
return clamp_val((val * 192 + nominal / 2) / nominal, 0, 255);
}
/*
......@@ -293,8 +293,7 @@ static inline int TEMP_FROM_REG(int reg, int res)
static inline int TEMP_TO_REG(int val)
{
return SENSORS_LIMIT((val < 0 ? val - 500 : val + 500) / 1000,
-128, 127);
return clamp_val((val < 0 ? val - 500 : val + 500) / 1000, -128, 127);
}
/* Temperature range */
......@@ -332,7 +331,7 @@ static inline int TEMP_HYST_FROM_REG(int reg, int ix)
static inline int TEMP_HYST_TO_REG(int val, int ix, int reg)
{
int hyst = SENSORS_LIMIT((val + 500) / 1000, 0, 15);
int hyst = clamp_val((val + 500) / 1000, 0, 15);
return (ix == 1) ? (reg & 0xf0) | hyst : (reg & 0x0f) | (hyst << 4);
}
......@@ -349,10 +348,10 @@ static inline int FAN_FROM_REG(int reg, int tpc)
static inline int FAN_TO_REG(int val, int tpc)
{
if (tpc) {
return SENSORS_LIMIT(val / tpc, 0, 0xffff);
return clamp_val(val / tpc, 0, 0xffff);
} else {
return (val <= 0) ? 0xffff :
SENSORS_LIMIT(90000 * 60 / val, 0, 0xfffe);
clamp_val(90000 * 60 / val, 0, 0xfffe);
}
}
......@@ -1282,7 +1281,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->update_lock);
switch (fn) {
case SYS_PWM:
data->pwm[ix] = SENSORS_LIMIT(val, 0, 255);
data->pwm[ix] = clamp_val(val, 0, 255);
dme1737_write(data, DME1737_REG_PWM(ix), data->pwm[ix]);
break;
case SYS_PWM_FREQ:
......@@ -1450,7 +1449,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
break;
case SYS_PWM_AUTO_POINT1_PWM:
/* Only valid for pwm[1-3] */
data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255);
data->pwm_min[ix] = clamp_val(val, 0, 255);
dme1737_write(data, DME1737_REG_PWM_MIN(ix),
data->pwm_min[ix]);
break;
......
......@@ -405,7 +405,7 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
if (rpm_target == 0)
data->fan_target = 0x1fff;
else
data->fan_target = SENSORS_LIMIT(
data->fan_target = clamp_val(
(FAN_RPM_FACTOR * data->fan_multiplier) / rpm_target,
0, 0x1fff);
......
......@@ -220,7 +220,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
: EMC6W201_REG_IN_HIGH(nr);
mutex_lock(&data->update_lock);
data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
data->in[sf][nr] = clamp_val(val, 0, 255);
err = emc6w201_write8(client, reg, data->in[sf][nr]);
mutex_unlock(&data->update_lock);
......@@ -257,7 +257,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
: EMC6W201_REG_TEMP_HIGH(nr);
mutex_lock(&data->update_lock);
data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
data->temp[sf][nr] = clamp_val(val, -127, 128);
err = emc6w201_write8(client, reg, data->temp[sf][nr]);
mutex_unlock(&data->update_lock);
......@@ -298,7 +298,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
val = 0xFFFF;
} else {
val = DIV_ROUND_CLOSEST(5400000U, val);
val = SENSORS_LIMIT(val, 0, 0xFFFE);
val = clamp_val(val, 0, 0xFFFE);
}
mutex_lock(&data->update_lock);
......
......@@ -1350,7 +1350,7 @@ static ssize_t store_fan_full_speed(struct device *dev,
if (err)
return err;
val = SENSORS_LIMIT(val, 23, 1500000);
val = clamp_val(val, 23, 1500000);
val = fan_to_reg(val);
mutex_lock(&data->update_lock);
......@@ -1438,7 +1438,7 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute
return err;
val /= 8;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
......@@ -1542,7 +1542,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
return err;
val /= 1000;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
......@@ -1589,8 +1589,7 @@ static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
/* convert abs to relative and check */
data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
data->temp_high[nr]);
val = clamp_val(val, data->temp_high[nr] - 15, data->temp_high[nr]);
val = data->temp_high[nr] - val;
/* convert value to register contents */
......@@ -1627,7 +1626,7 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute
return err;
val /= 1000;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
......@@ -1754,7 +1753,7 @@ static ssize_t store_pwm(struct device *dev,
if (err)
return err;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
......@@ -1805,7 +1804,7 @@ static ssize_t store_simple_pwm(struct device *dev,
if (err)
return err;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
......@@ -1932,7 +1931,7 @@ static ssize_t store_pwm_auto_point_pwm(struct device *dev,
if (err)
return err;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
......@@ -1991,8 +1990,8 @@ static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
mutex_lock(&data->update_lock);
data->pwm_auto_point_temp[nr][point] =
f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
data->pwm_auto_point_temp[nr][point]);
val = clamp_val(val, data->pwm_auto_point_temp[nr][point] - 15,
data->pwm_auto_point_temp[nr][point]);
val = data->pwm_auto_point_temp[nr][point] - val;
reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
......@@ -2126,9 +2125,9 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
val /= 1000;
if (data->auto_point_temp_signed)
val = SENSORS_LIMIT(val, -128, 127);
val = clamp_val(val, -128, 127);
else
val = SENSORS_LIMIT(val, 0, 127);
val = clamp_val(val, 0, 127);
mutex_lock(&data->update_lock);
f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
......
......@@ -359,7 +359,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
return -EINVAL;
mutex_lock(&data->update_lock);
data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
data->pwm[nr] = clamp_val(val, 0, 255);
f75375_write_pwm(client, nr);
mutex_unlock(&data->update_lock);
return count;
......@@ -556,7 +556,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
if (err < 0)
return err;
val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff);
val = clamp_val(VOLT_TO_REG(val), 0, 0xff);
mutex_lock(&data->update_lock);
data->in_max[nr] = val;
f75375_write8(client, F75375_REG_VOLT_HIGH(nr), data->in_max[nr]);
......@@ -577,7 +577,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
if (err < 0)
return err;
val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff);
val = clamp_val(VOLT_TO_REG(val), 0, 0xff);
mutex_lock(&data->update_lock);
data->in_min[nr] = val;
f75375_write8(client, F75375_REG_VOLT_LOW(nr), data->in_min[nr]);
......@@ -625,7 +625,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
if (err < 0)
return err;
val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127);
val = clamp_val(TEMP_TO_REG(val), 0, 127);
mutex_lock(&data->update_lock);
data->temp_high[nr] = val;
f75375_write8(client, F75375_REG_TEMP_HIGH(nr), data->temp_high[nr]);
......@@ -646,7 +646,7 @@ static ssize_t set_temp_max_hyst(struct device *dev,
if (err < 0)
return err;
val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127);
val = clamp_val(TEMP_TO_REG(val), 0, 127);
mutex_lock(&data->update_lock);
data->temp_max_hyst[nr] = val;
f75375_write8(client, F75375_REG_TEMP_HYST(nr),
......@@ -822,7 +822,7 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) ||
!duty_mode_enabled(f75375s_pdata->pwm_enable[nr]))
continue;
data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
data->pwm[nr] = clamp_val(f75375s_pdata->pwm[nr], 0, 255);
f75375_write_pwm(client, nr);
}
......
......@@ -379,7 +379,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
if (err)
return err;
v = SENSORS_LIMIT(v / 1000, -128, 127) + 128;
v = clamp_val(v / 1000, -128, 127) + 128;
mutex_lock(&data->update_lock);
i2c_smbus_write_byte_data(to_i2c_client(dev),
......@@ -540,7 +540,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
/* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
if (v || data->kind == fscsyl) {
v = SENSORS_LIMIT(v, 128, 255);
v = clamp_val(v, 128, 255);
v = (v - 128) * 2 + 1;
}
......
......@@ -171,7 +171,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
return -EINVAL;
mutex_lock(&data->update_lock);
data->set_cnt = PWM_TO_CNT(SENSORS_LIMIT(val, 0, 255));
data->set_cnt = PWM_TO_CNT(clamp_val(val, 0, 255));
g760a_write_value(client, G760A_REG_SET_CNT, data->set_cnt);
mutex_unlock(&data->update_lock);
......
......@@ -86,7 +86,7 @@ enum chips { gl518sm_r00, gl518sm_r80 };
#define BOOL_FROM_REG(val) ((val) ? 0 : 1)
#define BOOL_TO_REG(val) ((val) ? 0 : 1)
#define TEMP_TO_REG(val) SENSORS_LIMIT(((((val) < 0 ? \
#define TEMP_TO_REG(val) clamp_val(((((val) < 0 ? \
(val) - 500 : \
(val) + 500) / 1000) + 119), 0, 255)
#define TEMP_FROM_REG(val) (((val) - 119) * 1000)
......@@ -96,15 +96,15 @@ static inline u8 FAN_TO_REG(long rpm, int div)
long rpmdiv;
if (rpm == 0)
return 0;
rpmdiv = SENSORS_LIMIT(rpm, 1, 960000) * div;
return SENSORS_LIMIT((480000 + rpmdiv / 2) / rpmdiv, 1, 255);
rpmdiv = clamp_val(rpm, 1, 960000) * div;
return clamp_val((480000 + rpmdiv / 2) / rpmdiv, 1, 255);
}
#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) * (div))))
#define IN_TO_REG(val) SENSORS_LIMIT((((val) + 9) / 19), 0, 255)
#define IN_TO_REG(val) clamp_val((((val) + 9) / 19), 0, 255)
#define IN_FROM_REG(val) ((val) * 19)
#define VDD_TO_REG(val) SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255)
#define VDD_TO_REG(val) clamp_val((((val) * 4 + 47) / 95), 0, 255)
#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4)
#define DIV_FROM_REG(val) (1 << (val))
......
......@@ -144,10 +144,10 @@ static ssize_t get_cpu_vid(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL);
#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4)
#define VDD_TO_REG(val) SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255)
#define VDD_TO_REG(val) clamp_val((((val) * 4 + 47) / 95), 0, 255)
#define IN_FROM_REG(val) ((val) * 19)
#define IN_TO_REG(val) SENSORS_LIMIT((((val) + 9) / 19), 0, 255)
#define IN_TO_REG(val) clamp_val((((val) + 9) / 19), 0, 255)
static ssize_t get_in_input(struct device *dev, struct device_attribute *attr,
char *buf)
......@@ -285,8 +285,7 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
#define DIV_FROM_REG(val) (1 << (val))
#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) << (div))))
#define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \
SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, \
255))
clamp_val((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255))
static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr,
char *buf)
......@@ -450,7 +449,7 @@ static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR,
get_fan_off, set_fan_off);
#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
#define TEMP_TO_REG(val) SENSORS_LIMIT(((((val) < 0 ? \
#define TEMP_TO_REG(val) clamp_val(((((val) < 0 ? \
(val) - 500 : (val) + 500) / 1000) + 130), 0, 255)
static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr,
......
/*
* Driver for the Texas Instruments / Burr Brown INA209
* Bidirectional Current/Power Monitor
*
* Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
*
* Derived from Ira W. Snyder's original driver submission
* Copyright (C) 2008 Paul Hays <Paul.Hays@cattail.ca>
* Copyright (C) 2008-2009 Ira W. Snyder <iws@ovro.caltech.edu>
*
* Aligned with ina2xx driver
* Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
* Thanks to Jan Volkering
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* Datasheet:
* http://www.ti.com/lit/gpn/ina209
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/bug.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/platform_data/ina2xx.h>
/* register definitions */
#define INA209_CONFIGURATION 0x00
#define INA209_STATUS 0x01
#define INA209_STATUS_MASK 0x02
#define INA209_SHUNT_VOLTAGE 0x03
#define INA209_BUS_VOLTAGE 0x04
#define INA209_POWER 0x05
#define INA209_CURRENT 0x06
#define INA209_SHUNT_VOLTAGE_POS_PEAK 0x07
#define INA209_SHUNT_VOLTAGE_NEG_PEAK 0x08
#define INA209_BUS_VOLTAGE_MAX_PEAK 0x09
#define INA209_BUS_VOLTAGE_MIN_PEAK 0x0a
#define INA209_POWER_PEAK 0x0b
#define INA209_SHUNT_VOLTAGE_POS_WARN 0x0c
#define INA209_SHUNT_VOLTAGE_NEG_WARN 0x0d
#define INA209_POWER_WARN 0x0e
#define INA209_BUS_VOLTAGE_OVER_WARN 0x0f
#define INA209_BUS_VOLTAGE_UNDER_WARN 0x10
#define INA209_POWER_OVER_LIMIT 0x11
#define INA209_BUS_VOLTAGE_OVER_LIMIT 0x12
#define INA209_BUS_VOLTAGE_UNDER_LIMIT 0x13
#define INA209_CRITICAL_DAC_POS 0x14
#define INA209_CRITICAL_DAC_NEG 0x15
#define INA209_CALIBRATION 0x16
#define INA209_REGISTERS 0x17
#define INA209_CONFIG_DEFAULT 0x3c47 /* PGA=8, full range */
#define INA209_SHUNT_DEFAULT 10000 /* uOhm */
struct ina209_data {
struct device *hwmon_dev;
struct mutex update_lock;
bool valid;
unsigned long last_updated; /* in jiffies */
u16 regs[INA209_REGISTERS]; /* All chip registers */
u16 config_orig; /* Original configuration */
u16 calibration_orig; /* Original calibration */
u16 update_interval;
};
static struct ina209_data *ina209_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = i2c_get_clientdata(client);
struct ina209_data *ret = data;
s32 val;
int i;
mutex_lock(&data->update_lock);
if (!data->valid ||
time_after(jiffies, data->last_updated + data->update_interval)) {
for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
val = i2c_smbus_read_word_swapped(client, i);
if (val < 0) {
ret = ERR_PTR(val);
goto abort;
}
data->regs[i] = val;
}
data->last_updated = jiffies;
data->valid = true;
}
abort:
mutex_unlock(&data->update_lock);
return ret;
}
/*
* Read a value from a device register and convert it to the
* appropriate sysfs units
*/
static long ina209_from_reg(const u8 reg, const u16 val)
{
switch (reg) {
case INA209_SHUNT_VOLTAGE:
case INA209_SHUNT_VOLTAGE_POS_PEAK:
case INA209_SHUNT_VOLTAGE_NEG_PEAK:
case INA209_SHUNT_VOLTAGE_POS_WARN:
case INA209_SHUNT_VOLTAGE_NEG_WARN:
/* LSB=10 uV. Convert to mV. */
return DIV_ROUND_CLOSEST(val, 100);
case INA209_BUS_VOLTAGE:
case INA209_BUS_VOLTAGE_MAX_PEAK:
case INA209_BUS_VOLTAGE_MIN_PEAK:
case INA209_BUS_VOLTAGE_OVER_WARN:
case INA209_BUS_VOLTAGE_UNDER_WARN:
case INA209_BUS_VOLTAGE_OVER_LIMIT:
case INA209_BUS_VOLTAGE_UNDER_LIMIT:
/* LSB=4 mV, last 3 bits unused */
return (val >> 3) * 4;
case INA209_CRITICAL_DAC_POS:
/* LSB=1 mV, in the upper 8 bits */
return val >> 8;
case INA209_CRITICAL_DAC_NEG:
/* LSB=1 mV, in the upper 8 bits */
return -1 * (val >> 8);
case INA209_POWER:
case INA209_POWER_PEAK:
case INA209_POWER_WARN:
case INA209_POWER_OVER_LIMIT:
/* LSB=20 mW. Convert to uW */
return val * 20 * 1000L;
case INA209_CURRENT:
/* LSB=1 mA (selected). Is in mA */
return val;
}
/* programmer goofed */
WARN_ON_ONCE(1);
return 0;
}
/*
* Take a value and convert it to register format, clamping the value
* to the appropriate range.
*/
static int ina209_to_reg(u8 reg, u16 old, long val)
{
switch (reg) {
case INA209_SHUNT_VOLTAGE_POS_WARN:
case INA209_SHUNT_VOLTAGE_NEG_WARN:
/* Limit to +- 320 mV, 10 uV LSB */
return clamp_val(val, -320, 320) * 100;
case INA209_BUS_VOLTAGE_OVER_WARN:
case INA209_BUS_VOLTAGE_UNDER_WARN:
case INA209_BUS_VOLTAGE_OVER_LIMIT:
case INA209_BUS_VOLTAGE_UNDER_LIMIT:
/*
* Limit to 0-32000 mV, 4 mV LSB
*
* The last three bits aren't part of the value, but we'll
* preserve them in their original state.
*/
return (DIV_ROUND_CLOSEST(clamp_val(val, 0, 32000), 4) << 3)
| (old & 0x7);
case INA209_CRITICAL_DAC_NEG:
/*
* Limit to -255-0 mV, 1 mV LSB
* Convert the value to a positive value for the register
*
* The value lives in the top 8 bits only, be careful
* and keep original value of other bits.
*/
return (clamp_val(-val, 0, 255) << 8) | (old & 0xff);
case INA209_CRITICAL_DAC_POS:
/*
* Limit to 0-255 mV, 1 mV LSB
*
* The value lives in the top 8 bits only, be careful
* and keep original value of other bits.
*/
return (clamp_val(val, 0, 255) << 8) | (old & 0xff);
case INA209_POWER_WARN:
case INA209_POWER_OVER_LIMIT:
/* 20 mW LSB */
return DIV_ROUND_CLOSEST(val, 20 * 1000);
}
/* Other registers are read-only, return access error */
return -EACCES;
}
static int ina209_interval_from_reg(u16 reg)
{
return 68 >> (15 - ((reg >> 3) & 0x0f));
}
static u16 ina209_reg_from_interval(u16 config, long interval)
{
int i, adc;
if (interval <= 0) {
adc = 8;
} else {
adc = 15;
for (i = 34 + 34 / 2; i; i >>= 1) {
if (i < interval)
break;
adc--;
}
}
return (config & 0xf807) | (adc << 3) | (adc << 7);
}
static ssize_t ina209_set_interval(struct device *dev,
struct device_attribute *da,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = ina209_update_device(dev);
long val;
u16 regval;
int ret;
if (IS_ERR(data))
return PTR_ERR(data);
ret = kstrtol(buf, 10, &val);
if (ret < 0)
return ret;
mutex_lock(&data->update_lock);
regval = ina209_reg_from_interval(data->regs[INA209_CONFIGURATION],
val);
i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION, regval);
data->regs[INA209_CONFIGURATION] = regval;
data->update_interval = ina209_interval_from_reg(regval);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t ina209_show_interval(struct device *dev,
struct device_attribute *da, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = i2c_get_clientdata(client);
return snprintf(buf, PAGE_SIZE, "%d\n", data->update_interval);
}
/*
* History is reset by writing 1 into bit 0 of the respective peak register.
* Since more than one peak register may be affected by the scope of a
* reset_history attribute write, use a bit mask in attr->index to identify
* which registers are affected.
*/
static u16 ina209_reset_history_regs[] = {
INA209_SHUNT_VOLTAGE_POS_PEAK,
INA209_SHUNT_VOLTAGE_NEG_PEAK,
INA209_BUS_VOLTAGE_MAX_PEAK,
INA209_BUS_VOLTAGE_MIN_PEAK,
INA209_POWER_PEAK
};
static ssize_t ina209_reset_history(struct device *dev,
struct device_attribute *da,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = i2c_get_clientdata(client);
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u32 mask = attr->index;
long val;
int i, ret;
ret = kstrtol(buf, 10, &val);
if (ret < 0)
return ret;
mutex_lock(&data->update_lock);
for (i = 0; i < ARRAY_SIZE(ina209_reset_history_regs); i++) {
if (mask & (1 << i))
i2c_smbus_write_word_swapped(client,
ina209_reset_history_regs[i], 1);
}
data->valid = false;
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t ina209_set_value(struct device *dev,
struct device_attribute *da,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = ina209_update_device(dev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
int reg = attr->index;
long val;
int ret;
if (IS_ERR(data))
return PTR_ERR(data);
ret = kstrtol(buf, 10, &val);
if (ret < 0)
return ret;
mutex_lock(&data->update_lock);
ret = ina209_to_reg(reg, data->regs[reg], val);
if (ret < 0) {
count = ret;
goto abort;
}
i2c_smbus_write_word_swapped(client, reg, ret);
data->regs[reg] = ret;
abort:
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t ina209_show_value(struct device *dev,
struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ina209_data *data = ina209_update_device(dev);
long val;
if (IS_ERR(data))
return PTR_ERR(data);
val = ina209_from_reg(attr->index, data->regs[attr->index]);
return snprintf(buf, PAGE_SIZE, "%ld\n", val);
}
static ssize_t ina209_show_alarm(struct device *dev,
struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ina209_data *data = ina209_update_device(dev);
const unsigned int mask = attr->index;
u16 status;
if (IS_ERR(data))
return PTR_ERR(data);
status = data->regs[INA209_STATUS];
/*
* All alarms are in the INA209_STATUS register. To avoid a long
* switch statement, the mask is passed in attr->index
*/
return snprintf(buf, PAGE_SIZE, "%u\n", !!(status & mask));
}
/* Shunt voltage, history, limits, alarms */
static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina209_show_value, NULL,
INA209_SHUNT_VOLTAGE);
static SENSOR_DEVICE_ATTR(in0_input_highest, S_IRUGO, ina209_show_value, NULL,
INA209_SHUNT_VOLTAGE_POS_PEAK);
static SENSOR_DEVICE_ATTR(in0_input_lowest, S_IRUGO, ina209_show_value, NULL,
INA209_SHUNT_VOLTAGE_NEG_PEAK);
static SENSOR_DEVICE_ATTR(in0_reset_history, S_IWUSR, NULL,
ina209_reset_history, (1 << 0) | (1 << 1));
static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_SHUNT_VOLTAGE_POS_WARN);
static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_SHUNT_VOLTAGE_NEG_WARN);
static SENSOR_DEVICE_ATTR(in0_crit_max, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_CRITICAL_DAC_POS);
static SENSOR_DEVICE_ATTR(in0_crit_min, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_CRITICAL_DAC_NEG);
static SENSOR_DEVICE_ATTR(in0_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 11);
static SENSOR_DEVICE_ATTR(in0_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 12);
static SENSOR_DEVICE_ATTR(in0_crit_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 6);
static SENSOR_DEVICE_ATTR(in0_crit_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 7);
/* Bus voltage, history, limits, alarms */
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ina209_show_value, NULL,
INA209_BUS_VOLTAGE);
static SENSOR_DEVICE_ATTR(in1_input_highest, S_IRUGO, ina209_show_value, NULL,
INA209_BUS_VOLTAGE_MAX_PEAK);
static SENSOR_DEVICE_ATTR(in1_input_lowest, S_IRUGO, ina209_show_value, NULL,
INA209_BUS_VOLTAGE_MIN_PEAK);
static SENSOR_DEVICE_ATTR(in1_reset_history, S_IWUSR, NULL,
ina209_reset_history, (1 << 2) | (1 << 3));
static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_BUS_VOLTAGE_OVER_WARN);
static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_BUS_VOLTAGE_UNDER_WARN);
static SENSOR_DEVICE_ATTR(in1_crit_max, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_BUS_VOLTAGE_OVER_LIMIT);
static SENSOR_DEVICE_ATTR(in1_crit_min, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_BUS_VOLTAGE_UNDER_LIMIT);
static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 14);
static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 15);
static SENSOR_DEVICE_ATTR(in1_crit_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 9);
static SENSOR_DEVICE_ATTR(in1_crit_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 10);
/* Power */
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina209_show_value, NULL,
INA209_POWER);
static SENSOR_DEVICE_ATTR(power1_input_highest, S_IRUGO, ina209_show_value,
NULL, INA209_POWER_PEAK);
static SENSOR_DEVICE_ATTR(power1_reset_history, S_IWUSR, NULL,
ina209_reset_history, 1 << 4);
static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_POWER_WARN);
static SENSOR_DEVICE_ATTR(power1_crit, S_IRUGO | S_IWUSR, ina209_show_value,
ina209_set_value, INA209_POWER_OVER_LIMIT);
static SENSOR_DEVICE_ATTR(power1_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 13);
static SENSOR_DEVICE_ATTR(power1_crit_alarm, S_IRUGO, ina209_show_alarm, NULL,
1 << 8);
/* Current */
static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina209_show_value, NULL,
INA209_CURRENT);
static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR,
ina209_show_interval, ina209_set_interval, 0);
/*
* Finally, construct an array of pointers to members of the above objects,
* as required for sysfs_create_group()
*/
static struct attribute *ina209_attributes[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_input_highest.dev_attr.attr,
&sensor_dev_attr_in0_input_lowest.dev_attr.attr,
&sensor_dev_attr_in0_reset_history.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_crit_max.dev_attr.attr,
&sensor_dev_attr_in0_crit_min.dev_attr.attr,
&sensor_dev_attr_in0_max_alarm.dev_attr.attr,
&sensor_dev_attr_in0_min_alarm.dev_attr.attr,
&sensor_dev_attr_in0_crit_max_alarm.dev_attr.attr,
&sensor_dev_attr_in0_crit_min_alarm.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_input_highest.dev_attr.attr,
&sensor_dev_attr_in1_input_lowest.dev_attr.attr,
&sensor_dev_attr_in1_reset_history.dev_attr.attr,
&sensor_dev_attr_in1_max.dev_attr.attr,
&sensor_dev_attr_in1_min.dev_attr.attr,
&sensor_dev_attr_in1_crit_max.dev_attr.attr,
&sensor_dev_attr_in1_crit_min.dev_attr.attr,
&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
&sensor_dev_attr_in1_crit_max_alarm.dev_attr.attr,
&sensor_dev_attr_in1_crit_min_alarm.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
&sensor_dev_attr_power1_input_highest.dev_attr.attr,
&sensor_dev_attr_power1_reset_history.dev_attr.attr,
&sensor_dev_attr_power1_max.dev_attr.attr,
&sensor_dev_attr_power1_crit.dev_attr.attr,
&sensor_dev_attr_power1_max_alarm.dev_attr.attr,
&sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_update_interval.dev_attr.attr,
NULL,
};
static const struct attribute_group ina209_group = {
.attrs = ina209_attributes,
};
static void ina209_restore_conf(struct i2c_client *client,
struct ina209_data *data)
{
/* Restore initial configuration */
i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
data->config_orig);
i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
data->calibration_orig);
}
static int ina209_init_client(struct i2c_client *client,
struct ina209_data *data)
{
struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev);
u32 shunt;
int reg;
reg = i2c_smbus_read_word_swapped(client, INA209_CALIBRATION);
if (reg < 0)
return reg;
data->calibration_orig = reg;
reg = i2c_smbus_read_word_swapped(client, INA209_CONFIGURATION);
if (reg < 0)
return reg;
data->config_orig = reg;
if (pdata) {
if (pdata->shunt_uohms <= 0)
return -EINVAL;
shunt = pdata->shunt_uohms;
} else if (!of_property_read_u32(client->dev.of_node, "shunt-resistor",
&shunt)) {
if (shunt == 0)
return -EINVAL;
} else {
shunt = data->calibration_orig ?
40960000 / data->calibration_orig : INA209_SHUNT_DEFAULT;
}
i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
INA209_CONFIG_DEFAULT);
data->update_interval = ina209_interval_from_reg(INA209_CONFIG_DEFAULT);
/*
* Calibrate current LSB to 1mA. Shunt is in uOhms.
* See equation 13 in datasheet.
*/
i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
clamp_val(40960000 / shunt, 1, 65535));
/* Clear status register */
i2c_smbus_read_word_swapped(client, INA209_STATUS);
return 0;
}
static int ina209_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
struct ina209_data *data;
int ret;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
ret = ina209_init_client(client, data);
if (ret)
return ret;
/* Register sysfs hooks */
ret = sysfs_create_group(&client->dev.kobj, &ina209_group);
if (ret)
goto out_restore_conf;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
ret = PTR_ERR(data->hwmon_dev);
goto out_hwmon_device_register;
}
return 0;
out_hwmon_device_register:
sysfs_remove_group(&client->dev.kobj, &ina209_group);
out_restore_conf:
ina209_restore_conf(client, data);
return ret;
}
static int ina209_remove(struct i2c_client *client)
{
struct ina209_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ina209_group);
ina209_restore_conf(client, data);
return 0;
}
static const struct i2c_device_id ina209_id[] = {
{ "ina209", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ina209_id);
/* This is the driver that will be inserted */
static struct i2c_driver ina209_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ina209",
},
.probe = ina209_probe,
.remove = ina209_remove,
.id_table = ina209_id,
};
module_i2c_driver(ina209_driver);
MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>, Paul Hays <Paul.Hays@cattail.ca>, Guenter Roeck <linux@roeck-us.net>");
MODULE_DESCRIPTION("INA209 driver");
MODULE_LICENSE("GPL");
......@@ -19,6 +19,8 @@
* IT8726F Super I/O chip w/LPC interface
* IT8728F 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
* IT8782F Super I/O chip w/LPC interface
* IT8783E/F Super I/O chip w/LPC interface
* Sis950 A clone of the IT8705F
......@@ -61,8 +63,8 @@
#define DRVNAME "it87"
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8782,
it8783 };
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8771,
it8772, it8782, it8783 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
......@@ -140,6 +142,8 @@ static inline void superio_exit(void)
#define IT8721F_DEVID 0x8721
#define IT8726F_DEVID 0x8726
#define IT8728F_DEVID 0x8728
#define IT8771E_DEVID 0x8771
#define IT8772E_DEVID 0x8772
#define IT8782F_DEVID 0x8782
#define IT8783E_DEVID 0x8783
#define IT87_ACT_REG 0x30
......@@ -281,6 +285,24 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
.peci_mask = 0x07,
},
[it8771] = {
.name = "it8771",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
/* PECI: guesswork */
/* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */
.peci_mask = 0x07,
},
[it8772] = {
.name = "it8772",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
/* PECI (coreboot) */
/* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */
.peci_mask = 0x07,
},
[it8782] = {
.name = "it8782",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
......@@ -384,7 +406,7 @@ 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));
return SENSORS_LIMIT(val, 0, 255);
return clamp_val(val, 0, 255);
}
static int in_from_reg(const struct it87_data *data, int nr, int val)
......@@ -396,16 +418,15 @@ static inline u8 FAN_TO_REG(long rpm, int div)
{
if (rpm == 0)
return 255;
rpm = SENSORS_LIMIT(rpm, 1, 1000000);
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
254);
rpm = clamp_val(rpm, 1, 1000000);
return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
}
static inline u16 FAN16_TO_REG(long rpm)
{
if (rpm == 0)
return 0xffff;
return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
return clamp_val((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
}
#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 255 ? 0 : \
......@@ -414,8 +435,8 @@ static inline u16 FAN16_TO_REG(long rpm)
#define FAN16_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
1350000 / ((val) * 2))
#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (((val) - 500) / 1000) : \
((val) + 500) / 1000), -128, 127))
#define TEMP_TO_REG(val) (clamp_val(((val) < 0 ? (((val) - 500) / 1000) : \
((val) + 500) / 1000), -128, 127))
#define TEMP_FROM_REG(val) ((val) * 1000)
static u8 pwm_to_reg(const struct it87_data *data, long val)
......@@ -1709,6 +1730,12 @@ static int __init it87_find(unsigned short *address,
case IT8728F_DEVID:
sio_data->type = it8728;
break;
case IT8771E_DEVID:
sio_data->type = it8771;
break;
case IT8772E_DEVID:
sio_data->type = it8772;
break;
case IT8782F_DEVID:
sio_data->type = it8782;
break;
......@@ -1826,10 +1853,11 @@ static int __init it87_find(unsigned short *address,
reg = superio_inb(IT87_SIO_GPIO3_REG);
if (sio_data->type == it8721 || sio_data->type == it8728 ||
sio_data->type == it8771 || sio_data->type == it8772 ||
sio_data->type == it8782) {
/*
* IT8721F/IT8758E, and IT8782F don't have VID pins
* at all, not sure about the IT8728F.
* at all, not sure about the IT8728F and compatibles.
*/
sio_data->skip_vid = 1;
} else {
......@@ -1883,7 +1911,9 @@ static int __init it87_find(unsigned short *address,
if (reg & (1 << 0))
sio_data->internal |= (1 << 0);
if ((reg & (1 << 1)) || sio_data->type == it8721 ||
sio_data->type == it8728)
sio_data->type == it8728 ||
sio_data->type == it8771 ||
sio_data->type == it8772)
sio_data->internal |= (1 << 1);
/*
......
......@@ -103,6 +103,9 @@ static const unsigned short normal_i2c[] = {
#define MCP98243_DEVID 0x2100
#define MCP98243_DEVID_MASK 0xfffc
#define MCP98244_DEVID 0x2200
#define MCP98244_DEVID_MASK 0xfffc
#define MCP9843_DEVID 0x0000 /* Also matches mcp9805 */
#define MCP9843_DEVID_MASK 0xfffe
......@@ -147,6 +150,7 @@ static struct jc42_chips jc42_chips[] = {
{ MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK },
{ MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK },
{ MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK },
{ MCP_MANID, MCP98244_DEVID, MCP98244_DEVID_MASK },
{ MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK },
{ NXP_MANID, SE97_DEVID, SE97_DEVID_MASK },
{ ONS_MANID, CAT6095_DEVID, CAT6095_DEVID_MASK },
......@@ -237,9 +241,9 @@ static struct i2c_driver jc42_driver = {
static u16 jc42_temp_to_reg(int temp, bool extended)
{
int ntemp = SENSORS_LIMIT(temp,
extended ? JC42_TEMP_MIN_EXTENDED :
JC42_TEMP_MIN, JC42_TEMP_MAX);
int ntemp = clamp_val(temp,
extended ? JC42_TEMP_MIN_EXTENDED :
JC42_TEMP_MIN, JC42_TEMP_MAX);
/* convert from 0.001 to 0.0625 resolution */
return (ntemp * 2 / 125) & 0x1fff;
......
......@@ -209,9 +209,9 @@ static inline int lut_temp_to_reg(struct lm63_data *data, long val)
{
val -= data->temp2_offset;
if (data->lut_temp_highres)
return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127500), 500);
return DIV_ROUND_CLOSEST(clamp_val(val, 0, 127500), 500);
else
return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127000), 1000);
return DIV_ROUND_CLOSEST(clamp_val(val, 0, 127000), 1000);
}
/*
......@@ -415,7 +415,7 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr,
return err;
reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
data->pwm1[nr] = data->pwm_highres ? val :
......@@ -700,7 +700,7 @@ static ssize_t set_update_interval(struct device *dev,
return err;
mutex_lock(&data->update_lock);
lm63_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000));
lm63_set_convrate(client, data, clamp_val(val, 0, 100000));
mutex_unlock(&data->update_lock);
return count;
......
......@@ -8,6 +8,7 @@
* Guillaume Ligneul <guillaume.ligneul@gmail.com>
* Adrien Demarez <adrien.demarez@bolloretelecom.eu>
* Jeremy Laine <jeremy.laine@bolloretelecom.eu>
* Chris Verges <kg4ysn@gmail.com>
*
* This software program is licensed subject to the GNU General Public License
* (GPL).Version 2,June 1991, available at
......@@ -36,11 +37,30 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c,
#define LM73_ID 0x9001 /* 0x0190, byte-swapped */
#define DRVNAME "lm73"
#define LM73_TEMP_MIN (-40)
#define LM73_TEMP_MAX 150
#define LM73_TEMP_MIN (-256000 / 250)
#define LM73_TEMP_MAX (255750 / 250)
/*-----------------------------------------------------------------------*/
#define LM73_CTRL_RES_SHIFT 5
#define LM73_CTRL_RES_MASK (BIT(5) | BIT(6))
#define LM73_CTRL_TO_MASK BIT(7)
#define LM73_CTRL_HI_SHIFT 2
#define LM73_CTRL_LO_SHIFT 1
static const unsigned short lm73_convrates[] = {
14, /* 11-bits (0.25000 C/LSB): RES1 Bit = 0, RES0 Bit = 0 */
28, /* 12-bits (0.12500 C/LSB): RES1 Bit = 0, RES0 Bit = 1 */
56, /* 13-bits (0.06250 C/LSB): RES1 Bit = 1, RES0 Bit = 0 */
112, /* 14-bits (0.03125 C/LSB): RES1 Bit = 1, RES0 Bit = 1 */
};
struct lm73_data {
struct device *hwmon_dev;
struct mutex lock;
u8 ctrl; /* control register value */
};
/*-----------------------------------------------------------------------*/
static ssize_t set_temp(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
......@@ -56,8 +76,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
return status;
/* Write value */
value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
(LM73_TEMP_MAX*4)) << 5;
value = clamp_val(temp / 250, LM73_TEMP_MIN, LM73_TEMP_MAX) << 5;
err = i2c_smbus_write_word_swapped(client, attr->index, value);
return (err < 0) ? err : count;
}
......@@ -79,6 +98,73 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da,
return scnprintf(buf, PAGE_SIZE, "%d\n", temp);
}
static ssize_t set_convrate(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm73_data *data = i2c_get_clientdata(client);
unsigned long convrate;
s32 err;
int res = 0;
err = kstrtoul(buf, 10, &convrate);
if (err < 0)
return err;
/*
* Convert the desired conversion rate into register bits.
* res is already initialized, and everything past the second-to-last
* value in the array is treated as belonging to the last value
* in the array.
*/
while (res < (ARRAY_SIZE(lm73_convrates) - 1) &&
convrate > lm73_convrates[res])
res++;
mutex_lock(&data->lock);
data->ctrl &= LM73_CTRL_TO_MASK;
data->ctrl |= res << LM73_CTRL_RES_SHIFT;
err = i2c_smbus_write_byte_data(client, LM73_REG_CTRL, data->ctrl);
mutex_unlock(&data->lock);
if (err < 0)
return err;
return count;
}
static ssize_t show_convrate(struct device *dev, struct device_attribute *da,
char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm73_data *data = i2c_get_clientdata(client);
int res;
res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT;
return scnprintf(buf, PAGE_SIZE, "%hu\n", lm73_convrates[res]);
}
static ssize_t show_maxmin_alarm(struct device *dev,
struct device_attribute *da, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm73_data *data = i2c_get_clientdata(client);
s32 ctrl;
mutex_lock(&data->lock);
ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL);
if (ctrl < 0)
goto abort;
data->ctrl = ctrl;
mutex_unlock(&data->lock);
return scnprintf(buf, PAGE_SIZE, "%d\n", (ctrl >> attr->index) & 1);
abort:
mutex_unlock(&data->lock);
return ctrl;
}
/*-----------------------------------------------------------------------*/
......@@ -90,13 +176,20 @@ static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
show_temp, set_temp, LM73_REG_MIN);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
show_temp, NULL, LM73_REG_INPUT);
static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO,
show_convrate, set_convrate, 0);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
show_maxmin_alarm, NULL, LM73_CTRL_HI_SHIFT);
static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO,
show_maxmin_alarm, NULL, LM73_CTRL_LO_SHIFT);
static struct attribute *lm73_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_update_interval.dev_attr.attr,
&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
NULL
};
......@@ -111,23 +204,36 @@ static const struct attribute_group lm73_group = {
static int
lm73_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct device *hwmon_dev;
int status;
struct lm73_data *data;
int ctrl;
data = devm_kzalloc(&client->dev, sizeof(struct lm73_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL);
if (ctrl < 0)
return ctrl;
data->ctrl = ctrl;
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &lm73_group);
if (status)
return status;
hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(hwmon_dev)) {
status = PTR_ERR(hwmon_dev);
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
i2c_set_clientdata(client, hwmon_dev);
dev_info(&client->dev, "%s: sensor '%s'\n",
dev_name(hwmon_dev), client->name);
dev_name(data->hwmon_dev), client->name);
return 0;
......@@ -138,9 +244,9 @@ lm73_probe(struct i2c_client *client, const struct i2c_device_id *id)
static int lm73_remove(struct i2c_client *client)
{
struct device *hwmon_dev = i2c_get_clientdata(client);
struct lm73_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(hwmon_dev);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm73_group);
return 0;
}
......
......@@ -36,7 +36,7 @@
REG: (0.5C/bit, two's complement) << 7 */
static inline u16 LM75_TEMP_TO_REG(long temp)
{
int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
ntemp += (ntemp < 0 ? -250 : 250);
return (u16)((ntemp / 500) << 7);
}
......
......@@ -101,7 +101,7 @@ static struct i2c_driver lm77_driver = {
*/
static inline s16 LM77_TEMP_TO_REG(int temp)
{
int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
int ntemp = clamp_val(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
return (ntemp / 500) * 8;
}
......
......@@ -85,7 +85,7 @@ enum chips { lm78, lm79 };
*/
static inline u8 IN_TO_REG(unsigned long val)
{
unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
unsigned long nval = clamp_val(val, 0, 4080);
return (nval + 8) / 16;
}
#define IN_FROM_REG(val) ((val) * 16)
......@@ -94,7 +94,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
{
if (rpm <= 0)
return 255;
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
}
static inline int FAN_FROM_REG(u8 val, int div)
......@@ -108,7 +108,7 @@ static inline int FAN_FROM_REG(u8 val, int div)
*/
static inline s8 TEMP_TO_REG(int val)
{
int nval = SENSORS_LIMIT(val, -128000, 127000) ;
int nval = clamp_val(val, -128000, 127000) ;
return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000;
}
......
......@@ -72,15 +72,15 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
* Fixing this is just not worth it.
*/
#define IN_TO_REG(val) (SENSORS_LIMIT(((val) + 5) / 10, 0, 255))
#define IN_TO_REG(val) (clamp_val(((val) + 5) / 10, 0, 255))
#define IN_FROM_REG(val) ((val) * 10)
static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div)
{
if (rpm == 0)
return 255;
rpm = SENSORS_LIMIT(rpm, 1, 1000000);
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
rpm = clamp_val(rpm, 1, 1000000);
return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
}
#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \
......@@ -102,7 +102,7 @@ static inline long TEMP_FROM_REG(u16 temp)
#define TEMP_LIMIT_FROM_REG(val) (((val) > 0x80 ? \
(val) - 0x100 : (val)) * 1000)
#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) < 0 ? \
#define TEMP_LIMIT_TO_REG(val) clamp_val((val) < 0 ? \
((val) - 500) / 1000 : ((val) + 500) / 1000, 0, 255)
#define DIV_FROM_REG(val) (1 << (val))
......
......@@ -139,7 +139,7 @@ static const int lm85_scaling[] = { /* .001 Volts */
#define SCALE(val, from, to) (((val) * (to) + ((from) / 2)) / (from))
#define INS_TO_REG(n, val) \
SENSORS_LIMIT(SCALE(val, lm85_scaling[n], 192), 0, 255)
clamp_val(SCALE(val, lm85_scaling[n], 192), 0, 255)
#define INSEXT_FROM_REG(n, val, ext) \
SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n])
......@@ -151,19 +151,19 @@ static inline u16 FAN_TO_REG(unsigned long val)
{
if (!val)
return 0xffff;
return SENSORS_LIMIT(5400000 / val, 1, 0xfffe);
return clamp_val(5400000 / val, 1, 0xfffe);
}
#define FAN_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
5400000 / (val))
/* Temperature is reported in .001 degC increments */
#define TEMP_TO_REG(val) \
SENSORS_LIMIT(SCALE(val, 1000, 1), -127, 127)
clamp_val(SCALE(val, 1000, 1), -127, 127)
#define TEMPEXT_FROM_REG(val, ext) \
SCALE(((val) << 4) + (ext), 16, 1000)
#define TEMP_FROM_REG(val) ((val) * 1000)
#define PWM_TO_REG(val) SENSORS_LIMIT(val, 0, 255)
#define PWM_TO_REG(val) clamp_val(val, 0, 255)
#define PWM_FROM_REG(val) (val)
......@@ -258,7 +258,7 @@ static int ZONE_TO_REG(int zone)
return i << 5;
}
#define HYST_TO_REG(val) SENSORS_LIMIT(((val) + 500) / 1000, 0, 15)
#define HYST_TO_REG(val) clamp_val(((val) + 500) / 1000, 0, 15)
#define HYST_FROM_REG(val) ((val) * 1000)
/*
......
......@@ -931,7 +931,7 @@ static ssize_t set_update_interval(struct device *dev,
return err;
mutex_lock(&data->update_lock);
lm90_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000));
lm90_set_convrate(client, data, clamp_val(val, 0, 100000));
mutex_unlock(&data->update_lock);
return count;
......
......@@ -371,8 +371,8 @@ static unsigned LM93_IN_FROM_REG(int nr, u8 reg)
static u8 LM93_IN_TO_REG(int nr, unsigned val)
{
/* range limit */
const long mV = SENSORS_LIMIT(val,
lm93_vin_val_min[nr], lm93_vin_val_max[nr]);
const long mV = clamp_val(val,
lm93_vin_val_min[nr], lm93_vin_val_max[nr]);
/* try not to lose too much precision here */
const long uV = mV * 1000;
......@@ -385,8 +385,8 @@ static u8 LM93_IN_TO_REG(int nr, unsigned val)
const long intercept = uV_min - slope * lm93_vin_reg_min[nr];
u8 result = ((uV - intercept + (slope/2)) / slope);
result = SENSORS_LIMIT(result,
lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]);
result = clamp_val(result,
lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]);
return result;
}
......@@ -411,10 +411,10 @@ static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid)
{
long uV_offset = vid * 1000 - val * 10000;
if (upper) {
uV_offset = SENSORS_LIMIT(uV_offset, 12500, 200000);
uV_offset = clamp_val(uV_offset, 12500, 200000);
return (u8)((uV_offset / 12500 - 1) << 4);
} else {
uV_offset = SENSORS_LIMIT(uV_offset, -400000, -25000);
uV_offset = clamp_val(uV_offset, -400000, -25000);
return (u8)((uV_offset / -25000 - 1) << 0);
}
}
......@@ -437,7 +437,7 @@ static int LM93_TEMP_FROM_REG(u8 reg)
*/
static u8 LM93_TEMP_TO_REG(long temp)
{
int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX);
int ntemp = clamp_val(temp, LM93_TEMP_MIN, LM93_TEMP_MAX);
ntemp += (ntemp < 0 ? -500 : 500);
return (u8)(ntemp / 1000);
}
......@@ -472,7 +472,7 @@ static u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode)
{
int factor = mode ? 5 : 10;
off = SENSORS_LIMIT(off, LM93_TEMP_OFFSET_MIN,
off = clamp_val(off, LM93_TEMP_OFFSET_MIN,
mode ? LM93_TEMP_OFFSET_MAX1 : LM93_TEMP_OFFSET_MAX0);
return (u8)((off + factor/2) / factor);
}
......@@ -620,8 +620,8 @@ static u16 LM93_FAN_TO_REG(long rpm)
if (rpm == 0) {
count = 0x3fff;
} else {
rpm = SENSORS_LIMIT(rpm, 1, 1000000);
count = SENSORS_LIMIT((1350000 + rpm) / rpm, 1, 0x3ffe);
rpm = clamp_val(rpm, 1, 1000000);
count = clamp_val((1350000 + rpm) / rpm, 1, 0x3ffe);
}
regs = count << 2;
......@@ -692,7 +692,7 @@ static int LM93_RAMP_FROM_REG(u8 reg)
*/
static u8 LM93_RAMP_TO_REG(int ramp)
{
ramp = SENSORS_LIMIT(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX);
ramp = clamp_val(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX);
return (u8)((ramp + 2) / 5);
}
......@@ -702,7 +702,7 @@ static u8 LM93_RAMP_TO_REG(int ramp)
*/
static u8 LM93_PROCHOT_TO_REG(long prochot)
{
prochot = SENSORS_LIMIT(prochot, 0, 255);
prochot = clamp_val(prochot, 0, 255);
return (u8)prochot;
}
......@@ -2052,7 +2052,7 @@ static ssize_t store_pwm_auto_channels(struct device *dev,
return err;
mutex_lock(&data->update_lock);
data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255);
data->block9[nr][LM93_PWM_CTL1] = clamp_val(val, 0, 255);
lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL1),
data->block9[nr][LM93_PWM_CTL1]);
mutex_unlock(&data->update_lock);
......@@ -2397,7 +2397,7 @@ static ssize_t store_prochot_override_duty_cycle(struct device *dev,
mutex_lock(&data->update_lock);
data->prochot_override = (data->prochot_override & 0xf0) |
SENSORS_LIMIT(val, 0, 15);
clamp_val(val, 0, 15);
lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE,
data->prochot_override);
mutex_unlock(&data->update_lock);
......
......@@ -259,7 +259,7 @@ static ssize_t set_limit(struct device *dev, struct device_attribute *attr,
val /= 1000;
val = SENSORS_LIMIT(val, 0, (index == 6 ? 127 : 255));
val = clamp_val(val, 0, (index == 6 ? 127 : 255));
mutex_lock(&data->update_lock);
......@@ -284,7 +284,7 @@ static ssize_t set_crit_hyst(struct device *dev, struct device_attribute *attr,
val /= 1000;
val = SENSORS_LIMIT(val, 0, 31);
val = clamp_val(val, 0, 31);
mutex_lock(&data->update_lock);
......
......@@ -118,7 +118,7 @@ static inline int LIMIT_TO_MV(int limit, int range)
static inline int MV_TO_LIMIT(int mv, int range)
{
return SENSORS_LIMIT(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
}
static inline int ADC_TO_CURR(int adc, int gain)
......
......@@ -215,7 +215,7 @@ static ssize_t set_temp_max(struct device *dev,
return ret;
mutex_lock(&data->update_lock);
data->temp_max[index] = SENSORS_LIMIT(temp/1000, -128, 127);
data->temp_max[index] = clamp_val(temp/1000, -128, 127);
if (i2c_smbus_write_byte_data(client,
MAX1668_REG_LIMH_WR(index),
data->temp_max[index]))
......@@ -240,7 +240,7 @@ static ssize_t set_temp_min(struct device *dev,
return ret;
mutex_lock(&data->update_lock);
data->temp_min[index] = SENSORS_LIMIT(temp/1000, -128, 127);
data->temp_min[index] = clamp_val(temp/1000, -128, 127);
if (i2c_smbus_write_byte_data(client,
MAX1668_REG_LIML_WR(index),
data->temp_max[index]))
......
......@@ -74,7 +74,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 };
#define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \
0 : (rpm_ranges[rpm_range] * 30) / (val))
#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255)
#define TEMP_LIMIT_TO_REG(val) clamp_val((val) / 1000, 0, 255)
/*
* Client data (each client gets its own)
......@@ -312,7 +312,7 @@ static ssize_t set_pwm(struct device *dev,
if (res)
return res;
val = SENSORS_LIMIT(val, 0, 255);
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
data->pwm[attr->index] = (u8)(val * 120 / 255);
......
......@@ -239,7 +239,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
return err;
mutex_lock(&data->update_lock);
data->temp_high[attr2->nr] = SENSORS_LIMIT(temp_to_reg(val), 0, 255);
data->temp_high[attr2->nr] = clamp_val(temp_to_reg(val), 0, 255);
i2c_smbus_write_byte_data(client, attr2->index,
data->temp_high[attr2->nr]);
mutex_unlock(&data->update_lock);
......
......@@ -245,7 +245,7 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
if (err)
return err;
rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
/*
* Divide the required speed by 60 to get from rpm to rps, then
......@@ -313,7 +313,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
if (err)
return err;
pwm = SENSORS_LIMIT(pwm, 0, 255);
pwm = clamp_val(pwm, 0, 255);
mutex_lock(&data->update_lock);
......
此差异已折叠。
......@@ -43,7 +43,7 @@ struct ntc_compensation {
* The following compensation tables are from the specification of Murata NTC
* Thermistors Datasheet
*/
const struct ntc_compensation ncpXXwb473[] = {
static const struct ntc_compensation ncpXXwb473[] = {
{ .temp_C = -40, .ohm = 1747920 },
{ .temp_C = -35, .ohm = 1245428 },
{ .temp_C = -30, .ohm = 898485 },
......@@ -79,7 +79,7 @@ const struct ntc_compensation ncpXXwb473[] = {
{ .temp_C = 120, .ohm = 1615 },
{ .temp_C = 125, .ohm = 1406 },
};
const struct ntc_compensation ncpXXwl333[] = {
static const struct ntc_compensation ncpXXwl333[] = {
{ .temp_C = -40, .ohm = 1610154 },
{ .temp_C = -35, .ohm = 1130850 },
{ .temp_C = -30, .ohm = 802609 },
......
......@@ -72,7 +72,7 @@ config SENSORS_MAX34440
default n
help
If you say yes here you get hardware monitoring support for Maxim
MAX34440, MAX34441, and MAX34446.
MAX34440, MAX34441, MAX34446, MAX34460, and MAX34461.
This driver can also be built as a module. If so, the module will
be called max34440.
......
......@@ -2,6 +2,7 @@
* Hardware monitoring driver for Maxim MAX34440/MAX34441
*
* Copyright (c) 2011 Ericsson AB.
* Copyright (c) 2012 Guenter Roeck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -25,7 +26,7 @@
#include <linux/i2c.h>
#include "pmbus.h"
enum chips { max34440, max34441, max34446 };
enum chips { max34440, max34441, max34446, max34460, max34461 };
#define MAX34440_MFR_VOUT_PEAK 0xd4
#define MAX34440_MFR_IOUT_PEAK 0xd5
......@@ -87,7 +88,8 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
MAX34446_MFR_POUT_PEAK);
break;
case PMBUS_VIRT_READ_TEMP_AVG:
if (data->id != max34446)
if (data->id != max34446 && data->id != max34460 &&
data->id != max34461)
return -ENXIO;
ret = pmbus_read_word_data(client, page,
MAX34446_MFR_TEMPERATURE_AVG);
......@@ -322,6 +324,73 @@ static struct pmbus_driver_info max34440_info[] = {
.read_word_data = max34440_read_word_data,
.write_word_data = max34440_write_word_data,
},
[max34460] = {
.pages = 18,
.format[PSC_VOLTAGE_OUT] = direct,
.format[PSC_TEMPERATURE] = direct,
.m[PSC_VOLTAGE_OUT] = 1,
.b[PSC_VOLTAGE_OUT] = 0,
.R[PSC_VOLTAGE_OUT] = 3,
.m[PSC_TEMPERATURE] = 1,
.b[PSC_TEMPERATURE] = 0,
.R[PSC_TEMPERATURE] = 2,
.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.read_byte_data = max34440_read_byte_data,
.read_word_data = max34440_read_word_data,
.write_word_data = max34440_write_word_data,
},
[max34461] = {
.pages = 23,
.format[PSC_VOLTAGE_OUT] = direct,
.format[PSC_TEMPERATURE] = direct,
.m[PSC_VOLTAGE_OUT] = 1,
.b[PSC_VOLTAGE_OUT] = 0,
.R[PSC_VOLTAGE_OUT] = 3,
.m[PSC_TEMPERATURE] = 1,
.b[PSC_TEMPERATURE] = 0,
.R[PSC_TEMPERATURE] = 2,
.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
/* page 16 is reserved */
.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
.read_byte_data = max34440_read_byte_data,
.read_word_data = max34440_read_word_data,
.write_word_data = max34440_write_word_data,
},
};
static int max34440_probe(struct i2c_client *client,
......@@ -343,6 +412,8 @@ static const struct i2c_device_id max34440_id[] = {
{"max34440", max34440},
{"max34441", max34441},
{"max34446", max34446},
{"max34460", max34460},
{"max34461", max34461},
{}
};
MODULE_DEVICE_TABLE(i2c, max34440_id);
......
......@@ -2,6 +2,7 @@
* pmbus.h - Common defines and structures for PMBus devices
*
* Copyright (c) 2010, 2011 Ericsson AB.
* Copyright (c) 2012 Guenter Roeck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -177,6 +178,13 @@
#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28)
#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29)
#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30)
#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31)
#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32)
#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33)
#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34)
#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35)
/*
* CAPABILITY
*/
......@@ -317,6 +325,8 @@ enum pmbus_sensor_classes {
#define PMBUS_HAVE_STATUS_TEMP (1 << 15)
#define PMBUS_HAVE_STATUS_FAN12 (1 << 16)
#define PMBUS_HAVE_STATUS_FAN34 (1 << 17)
#define PMBUS_HAVE_VMON (1 << 18)
#define PMBUS_HAVE_STATUS_VMON (1 << 19)
enum pmbus_data_format { linear = 0, direct, vid };
......@@ -359,6 +369,7 @@ struct pmbus_driver_info {
/* Function declarations */
void pmbus_clear_cache(struct i2c_client *client);
int pmbus_set_page(struct i2c_client *client, u8 page);
int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -326,7 +326,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute
/* Preserve fan min */
tmp = 192 - (old_div * (192 - data->fan_preload[nr])
+ new_div / 2) / new_div;
data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
data->fan_preload[nr] = clamp_val(tmp, 0, 191);
smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
data->fan_preload[nr]);
mutex_unlock(&data->update_lock);
......
此差异已折叠。
此差异已折叠。
......@@ -115,7 +115,7 @@ static ssize_t tmp102_set_temp(struct device *dev,
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
val = SENSORS_LIMIT(val, -256000, 255000);
val = clamp_val(val, -256000, 255000);
mutex_lock(&tmp102->lock);
tmp102->temp[sda->index] = val;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部