diff options
-rw-r--r-- | Documentation/hwmon/adm1275 | 60 | ||||
-rw-r--r-- | Documentation/hwmon/coretemp | 21 | ||||
-rw-r--r-- | Documentation/hwmon/max16065 | 98 | ||||
-rw-r--r-- | Documentation/hwmon/max6642 | 21 | ||||
-rw-r--r-- | Documentation/hwmon/pkgtemp | 36 | ||||
-rw-r--r-- | Documentation/hwmon/sht15 | 74 | ||||
-rw-r--r-- | Documentation/hwmon/ucd9000 | 110 | ||||
-rw-r--r-- | Documentation/hwmon/ucd9200 | 112 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 66 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 6 | ||||
-rw-r--r-- | drivers/hwmon/adm1275.c | 121 | ||||
-rw-r--r-- | drivers/hwmon/coretemp.c | 722 | ||||
-rw-r--r-- | drivers/hwmon/max16065.c | 717 | ||||
-rw-r--r-- | drivers/hwmon/max34440.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/max6642.c | 356 | ||||
-rw-r--r-- | drivers/hwmon/max8688.c | 4 | ||||
-rw-r--r-- | drivers/hwmon/pkgtemp.c | 444 | ||||
-rw-r--r-- | drivers/hwmon/pmbus.h | 10 | ||||
-rw-r--r-- | drivers/hwmon/pmbus_core.c | 970 | ||||
-rw-r--r-- | drivers/hwmon/sht15.c | 747 | ||||
-rw-r--r-- | drivers/hwmon/ucd9000.c | 278 | ||||
-rw-r--r-- | drivers/hwmon/ucd9200.c | 210 | ||||
-rw-r--r-- | include/linux/sht15.h | 18 |
23 files changed, 3765 insertions, 1442 deletions
diff --git a/Documentation/hwmon/adm1275 b/Documentation/hwmon/adm1275 new file mode 100644 index 000000000000..6a3a6476cf20 --- /dev/null +++ b/Documentation/hwmon/adm1275 | |||
@@ -0,0 +1,60 @@ | |||
1 | Kernel driver adm1275 | ||
2 | ===================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Analog Devices ADM1275 | ||
6 | Prefix: 'adm1275' | ||
7 | Addresses scanned: - | ||
8 | Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1275.pdf | ||
9 | |||
10 | Author: Guenter Roeck <guenter.roeck@ericsson.com> | ||
11 | |||
12 | |||
13 | Description | ||
14 | ----------- | ||
15 | |||
16 | This driver supports hardware montoring for Analog Devices ADM1275 Hot-Swap | ||
17 | Controller and Digital Power Monitor. | ||
18 | |||
19 | The ADM1275 is a hot-swap controller that allows a circuit board to be removed | ||
20 | from or inserted into a live backplane. It also features current and voltage | ||
21 | readback via an integrated 12-bit analog-to-digital converter (ADC), accessed | ||
22 | using a PMBus. interface. | ||
23 | |||
24 | The driver is a client driver to the core PMBus driver. Please see | ||
25 | Documentation/hwmon/pmbus for details on PMBus client drivers. | ||
26 | |||
27 | |||
28 | Usage Notes | ||
29 | ----------- | ||
30 | |||
31 | This driver does not auto-detect devices. You will have to instantiate the | ||
32 | devices explicitly. Please see Documentation/i2c/instantiating-devices for | ||
33 | details. | ||
34 | |||
35 | |||
36 | Platform data support | ||
37 | --------------------- | ||
38 | |||
39 | The driver supports standard PMBus driver platform data. Please see | ||
40 | Documentation/hwmon/pmbus for details. | ||
41 | |||
42 | |||
43 | Sysfs entries | ||
44 | ------------- | ||
45 | |||
46 | The following attributes are supported. Limits are read-write; all other | ||
47 | attributes are read-only. | ||
48 | |||
49 | in1_label "vin1" or "vout1" depending on chip variant and | ||
50 | configuration. | ||
51 | in1_input Measured voltage. From READ_VOUT register. | ||
52 | in1_min Minumum Voltage. From VOUT_UV_WARN_LIMIT register. | ||
53 | in1_max Maximum voltage. From VOUT_OV_WARN_LIMIT register. | ||
54 | in1_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status. | ||
55 | in1_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status. | ||
56 | |||
57 | curr1_label "iout1" | ||
58 | curr1_input Measured current. From READ_IOUT register. | ||
59 | curr1_max Maximum current. From IOUT_OC_WARN_LIMIT register. | ||
60 | curr1_max_alarm Current high alarm. From IOUT_OC_WARN_LIMIT register. | ||
diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 25568f844804..f85e913a3401 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp | |||
@@ -15,8 +15,13 @@ Author: Rudolf Marek | |||
15 | 15 | ||
16 | Description | 16 | Description |
17 | ----------- | 17 | ----------- |
18 | This driver permits reading the DTS (Digital Temperature Sensor) embedded | ||
19 | inside Intel CPUs. This driver can read both the per-core and per-package | ||
20 | temperature using the appropriate sensors. The per-package sensor is new; | ||
21 | as of now, it is present only in the SandyBridge platform. The driver will | ||
22 | show the temperature of all cores inside a package under a single device | ||
23 | directory inside hwmon. | ||
18 | 24 | ||
19 | This driver permits reading temperature sensor embedded inside Intel Core CPU. | ||
20 | Temperature is measured in degrees Celsius and measurement resolution is | 25 | Temperature is measured in degrees Celsius and measurement resolution is |
21 | 1 degree C. Valid temperatures are from 0 to TjMax degrees C, because | 26 | 1 degree C. Valid temperatures are from 0 to TjMax degrees C, because |
22 | the actual value of temperature register is in fact a delta from TjMax. | 27 | the actual value of temperature register is in fact a delta from TjMax. |
@@ -27,13 +32,15 @@ mechanism will perform actions to forcibly cool down the processor. Alarm | |||
27 | may be raised, if the temperature grows enough (more than TjMax) to trigger | 32 | may be raised, if the temperature grows enough (more than TjMax) to trigger |
28 | the Out-Of-Spec bit. Following table summarizes the exported sysfs files: | 33 | the Out-Of-Spec bit. Following table summarizes the exported sysfs files: |
29 | 34 | ||
30 | temp1_input - Core temperature (in millidegrees Celsius). | 35 | All Sysfs entries are named with their core_id (represented here by 'X'). |
31 | temp1_max - All cooling devices should be turned on (on Core2). | 36 | tempX_input - Core temperature (in millidegrees Celsius). |
32 | temp1_crit - Maximum junction temperature (in millidegrees Celsius). | 37 | tempX_max - All cooling devices should be turned on (on Core2). |
33 | temp1_crit_alarm - Set when Out-of-spec bit is set, never clears. | 38 | tempX_crit - Maximum junction temperature (in millidegrees Celsius). |
39 | tempX_crit_alarm - Set when Out-of-spec bit is set, never clears. | ||
34 | Correct CPU operation is no longer guaranteed. | 40 | Correct CPU operation is no longer guaranteed. |
35 | temp1_label - Contains string "Core X", where X is processor | 41 | tempX_label - Contains string "Core X", where X is processor |
36 | number. | 42 | number. For Package temp, this will be "Physical id Y", |
43 | where Y is the package number. | ||
37 | 44 | ||
38 | The TjMax temperature is set to 85 degrees C if undocumented model specific | 45 | The TjMax temperature is set to 85 degrees C if undocumented model specific |
39 | register (UMSR) 0xee has bit 30 set. If not the TjMax is 100 degrees C as | 46 | register (UMSR) 0xee has bit 30 set. If not the TjMax is 100 degrees C as |
diff --git a/Documentation/hwmon/max16065 b/Documentation/hwmon/max16065 new file mode 100644 index 000000000000..44b4f61e04f9 --- /dev/null +++ b/Documentation/hwmon/max16065 | |||
@@ -0,0 +1,98 @@ | |||
1 | Kernel driver max16065 | ||
2 | ====================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Maxim MAX16065, MAX16066 | ||
6 | Prefixes: 'max16065', 'max16066' | ||
7 | Addresses scanned: - | ||
8 | Datasheet: | ||
9 | http://datasheets.maxim-ic.com/en/ds/MAX16065-MAX16066.pdf | ||
10 | * Maxim MAX16067 | ||
11 | Prefix: 'max16067' | ||
12 | Addresses scanned: - | ||
13 | Datasheet: | ||
14 | http://datasheets.maxim-ic.com/en/ds/MAX16067.pdf | ||
15 | * Maxim MAX16068 | ||
16 | Prefix: 'max16068' | ||
17 | Addresses scanned: - | ||
18 | Datasheet: | ||
19 | http://datasheets.maxim-ic.com/en/ds/MAX16068.pdf | ||
20 | * Maxim MAX16070/MAX16071 | ||
21 | Prefixes: 'max16070', 'max16071' | ||
22 | Addresses scanned: - | ||
23 | Datasheet: | ||
24 | http://datasheets.maxim-ic.com/en/ds/MAX16070-MAX16071.pdf | ||
25 | |||
26 | |||
27 | Author: Guenter Roeck <guenter.roeck@ericsson.com> | ||
28 | |||
29 | |||
30 | Description | ||
31 | ----------- | ||
32 | |||
33 | [From datasheets] The MAX16065/MAX16066 flash-configurable system managers | ||
34 | monitor and sequence multiple system voltages. The MAX16065/MAX16066 can also | ||
35 | accurately monitor (+/-2.5%) one current channel using a dedicated high-side | ||
36 | current-sense amplifier. The MAX16065 manages up to twelve system voltages | ||
37 | simultaneously, and the MAX16066 manages up to eight supply voltages. | ||
38 | |||
39 | The MAX16067 flash-configurable system manager monitors and sequences multiple | ||
40 | system voltages. The MAX16067 manages up to six system voltages simultaneously. | ||
41 | |||
42 | The MAX16068 flash-configurable system manager monitors and manages up to six | ||
43 | system voltages simultaneously. | ||
44 | |||
45 | The MAX16070/MAX16071 flash-configurable system monitors supervise multiple | ||
46 | system voltages. The MAX16070/MAX16071 can also accurately monitor (+/-2.5%) | ||
47 | one current channel using a dedicated high-side current-sense amplifier. The | ||
48 | MAX16070 monitors up to twelve system voltages simultaneously, and the MAX16071 | ||
49 | monitors up to eight supply voltages. | ||
50 | |||
51 | Each monitored channel has its own low and high critical limits. MAX16065, | ||
52 | MAX16066, MAX16070, and MAX16071 support an additional limit which is | ||
53 | configurable as either low or high secondary limit. MAX16065, MAX16066, | ||
54 | MAX16070, and MAX16071 also support supply current monitoring. | ||
55 | |||
56 | |||
57 | Usage Notes | ||
58 | ----------- | ||
59 | |||
60 | This driver does not probe for devices, since there is no register which | ||
61 | can be safely used to identify the chip. You will have to instantiate | ||
62 | the devices explicitly. Please see Documentation/i2c/instantiating-devices for | ||
63 | details. | ||
64 | |||
65 | |||
66 | Sysfs entries | ||
67 | ------------- | ||
68 | |||
69 | in[0-11]_input Input voltage measurements. | ||
70 | |||
71 | in12_input Voltage on CSP (Current Sense Positive) pin. | ||
72 | Only if the chip supports current sensing and if | ||
73 | current sensing is enabled. | ||
74 | |||
75 | in[0-11]_min Low warning limit. | ||
76 | Supported on MAX16065, MAX16066, MAX16070, and MAX16071 | ||
77 | only. | ||
78 | |||
79 | in[0-11]_max High warning limit. | ||
80 | Supported on MAX16065, MAX16066, MAX16070, and MAX16071 | ||
81 | only. | ||
82 | |||
83 | Either low or high warning limits are supported | ||
84 | (depending on chip configuration), but not both. | ||
85 | |||
86 | in[0-11]_lcrit Low critical limit. | ||
87 | |||
88 | in[0-11]_crit High critical limit. | ||
89 | |||
90 | in[0-11]_alarm Input voltage alarm. | ||
91 | |||
92 | curr1_input Current sense input; only if the chip supports current | ||
93 | sensing and if current sensing is enabled. | ||
94 | Displayed current assumes 0.001 Ohm current sense | ||
95 | resistor. | ||
96 | |||
97 | curr1_alarm Overcurrent alarm; only if the chip supports current | ||
98 | sensing and if current sensing is enabled. | ||
diff --git a/Documentation/hwmon/max6642 b/Documentation/hwmon/max6642 new file mode 100644 index 000000000000..afbd3e4942e2 --- /dev/null +++ b/Documentation/hwmon/max6642 | |||
@@ -0,0 +1,21 @@ | |||
1 | Kernel driver max6642 | ||
2 | ===================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Maxim MAX6642 | ||
6 | Prefix: 'max6642' | ||
7 | Addresses scanned: I2C 0x48-0x4f | ||
8 | Datasheet: Publicly available at the Maxim website | ||
9 | http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf | ||
10 | |||
11 | Authors: | ||
12 | Per Dalen <per.dalen@appeartv.com> | ||
13 | |||
14 | Description | ||
15 | ----------- | ||
16 | |||
17 | The MAX6642 is a digital temperature sensor. It senses its own temperature as | ||
18 | well as the temperature on one external diode. | ||
19 | |||
20 | All temperature values are given in degrees Celsius. Resolution | ||
21 | is 0.25 degree for the local temperature and for the remote temperature. | ||
diff --git a/Documentation/hwmon/pkgtemp b/Documentation/hwmon/pkgtemp deleted file mode 100644 index c8e1fb0fadd3..000000000000 --- a/Documentation/hwmon/pkgtemp +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | Kernel driver pkgtemp | ||
2 | ====================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Intel family | ||
6 | Prefix: 'pkgtemp' | ||
7 | CPUID: | ||
8 | Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual | ||
9 | Volume 3A: System Programming Guide | ||
10 | |||
11 | Author: Fenghua Yu | ||
12 | |||
13 | Description | ||
14 | ----------- | ||
15 | |||
16 | This driver permits reading package level temperature sensor embedded inside | ||
17 | Intel CPU package. The sensors can be in core, uncore, memory controller, or | ||
18 | other components in a package. The feature is first implemented in Intel Sandy | ||
19 | Bridge platform. | ||
20 | |||
21 | Temperature is measured in degrees Celsius and measurement resolution is | ||
22 | 1 degree C. Valid temperatures are from 0 to TjMax degrees C, because the actual | ||
23 | value of temperature register is in fact a delta from TjMax. | ||
24 | |||
25 | Temperature known as TjMax is the maximum junction temperature of package. | ||
26 | We get this from MSR_IA32_TEMPERATURE_TARGET. If the MSR is not accessible, | ||
27 | we define TjMax as 100 degrees Celsius. At this temperature, protection | ||
28 | mechanism will perform actions to forcibly cool down the package. Alarm | ||
29 | may be raised, if the temperature grows enough (more than TjMax) to trigger | ||
30 | the Out-Of-Spec bit. Following table summarizes the exported sysfs files: | ||
31 | |||
32 | temp1_input - Package temperature (in millidegrees Celsius). | ||
33 | temp1_max - All cooling devices should be turned on. | ||
34 | temp1_crit - Maximum junction temperature (in millidegrees Celsius). | ||
35 | temp1_crit_alarm - Set when Out-of-spec bit is set, never clears. | ||
36 | Correct CPU operation is no longer guaranteed. | ||
diff --git a/Documentation/hwmon/sht15 b/Documentation/hwmon/sht15 new file mode 100644 index 000000000000..02850bdfac18 --- /dev/null +++ b/Documentation/hwmon/sht15 | |||
@@ -0,0 +1,74 @@ | |||
1 | Kernel driver sht15 | ||
2 | =================== | ||
3 | |||
4 | Authors: | ||
5 | * Wouter Horre | ||
6 | * Jonathan Cameron | ||
7 | * Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
8 | * Jerome Oufella <jerome.oufella@savoirfairelinux.com> | ||
9 | |||
10 | Supported chips: | ||
11 | * Sensirion SHT10 | ||
12 | Prefix: 'sht10' | ||
13 | |||
14 | * Sensirion SHT11 | ||
15 | Prefix: 'sht11' | ||
16 | |||
17 | * Sensirion SHT15 | ||
18 | Prefix: 'sht15' | ||
19 | |||
20 | * Sensirion SHT71 | ||
21 | Prefix: 'sht71' | ||
22 | |||
23 | * Sensirion SHT75 | ||
24 | Prefix: 'sht75' | ||
25 | |||
26 | Datasheet: Publicly available at the Sensirion website | ||
27 | http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf | ||
28 | |||
29 | Description | ||
30 | ----------- | ||
31 | |||
32 | The SHT10, SHT11, SHT15, SHT71, and SHT75 are humidity and temperature | ||
33 | sensors. | ||
34 | |||
35 | The devices communicate using two GPIO lines. | ||
36 | |||
37 | Supported resolutions for the measurements are 14 bits for temperature and 12 | ||
38 | bits for humidity, or 12 bits for temperature and 8 bits for humidity. | ||
39 | |||
40 | The humidity calibration coefficients are programmed into an OTP memory on the | ||
41 | chip. These coefficients are used to internally calibrate the signals from the | ||
42 | sensors. Disabling the reload of those coefficients allows saving 10ms for each | ||
43 | measurement and decrease power consumption, while loosing on precision. | ||
44 | |||
45 | Some options may be set directly in the sht15_platform_data structure | ||
46 | or via sysfs attributes. | ||
47 | |||
48 | Notes: | ||
49 | * The regulator supply name is set to "vcc". | ||
50 | * If a CRC validation fails, a soft reset command is sent, which resets | ||
51 | status register to its hardware default value, but the driver will try to | ||
52 | restore the previous device configuration. | ||
53 | |||
54 | Platform data | ||
55 | ------------- | ||
56 | |||
57 | * checksum: | ||
58 | set it to true to enable CRC validation of the readings (default to false). | ||
59 | * no_otp_reload: | ||
60 | flag to indicate not to reload from OTP (default to false). | ||
61 | * low_resolution: | ||
62 | flag to indicate the temp/humidity resolution to use (default to false). | ||
63 | |||
64 | Sysfs interface | ||
65 | --------------- | ||
66 | |||
67 | * temp1_input: temperature input | ||
68 | * humidity1_input: humidity input | ||
69 | * heater_enable: write 1 in this attribute to enable the on-chip heater, | ||
70 | 0 to disable it. Be careful not to enable the heater | ||
71 | for too long. | ||
72 | * temp1_fault: if 1, this means that the voltage is low (below 2.47V) and | ||
73 | measurement may be invalid. | ||
74 | * humidity1_fault: same as temp1_fault. | ||
diff --git a/Documentation/hwmon/ucd9000 b/Documentation/hwmon/ucd9000 new file mode 100644 index 000000000000..40ca6db50c48 --- /dev/null +++ b/Documentation/hwmon/ucd9000 | |||
@@ -0,0 +1,110 @@ | |||
1 | Kernel driver ucd9000 | ||
2 | ===================== | ||
3 | |||
4 | Supported chips: | ||
5 | * TI UCD90120, UCD90124, UCD9090, and UCD90910 | ||
6 | Prefixes: 'ucd90120', 'ucd90124', 'ucd9090', 'ucd90910' | ||
7 | Addresses scanned: - | ||
8 | Datasheets: | ||
9 | http://focus.ti.com/lit/ds/symlink/ucd90120.pdf | ||
10 | http://focus.ti.com/lit/ds/symlink/ucd90124.pdf | ||
11 | http://focus.ti.com/lit/ds/symlink/ucd9090.pdf | ||
12 | http://focus.ti.com/lit/ds/symlink/ucd90910.pdf | ||
13 | |||
14 | Author: Guenter Roeck <guenter.roeck@ericsson.com> | ||
15 | |||
16 | |||
17 | Description | ||
18 | ----------- | ||
19 | |||
20 | From datasheets: | ||
21 | |||
22 | The UCD90120 Power Supply Sequencer and System Health Monitor monitors and | ||
23 | sequences up to 12 independent voltage rails. The device integrates a 12-bit | ||
24 | ADC with a 2.5V internal reference for monitoring up to 13 power supply voltage, | ||
25 | current, or temperature inputs. | ||
26 | |||
27 | The UCD90124 is a 12-rail PMBus/I2C addressable power-supply sequencer and | ||
28 | system-health monitor. The device integrates a 12-bit ADC for monitoring up to | ||
29 | 13 power-supply voltage, current, or temperature inputs. Twenty-six GPIO pins | ||
30 | can be used for power supply enables, power-on reset signals, external | ||
31 | interrupts, cascading, or other system functions. Twelve of these pins offer PWM | ||
32 | functionality. Using these pins, the UCD90124 offers support for fan control, | ||
33 | margining, and general-purpose PWM functions. | ||
34 | |||
35 | The UCD9090 is a 10-rail PMBus/I2C addressable power-supply sequencer and | ||
36 | monitor. The device integrates a 12-bit ADC for monitoring up to 10 power-supply | ||
37 | voltage inputs. Twenty-three GPIO pins can be used for power supply enables, | ||
38 | power-on reset signals, external interrupts, cascading, or other system | ||
39 | functions. Ten of these pins offer PWM functionality. Using these pins, the | ||
40 | UCD9090 offers support for margining, and general-purpose PWM functions. | ||
41 | |||
42 | The UCD90910 is a ten-rail I2C / PMBus addressable power-supply sequencer and | ||
43 | system-health monitor. The device integrates a 12-bit ADC for monitoring up to | ||
44 | 13 power-supply voltage, current, or temperature inputs. | ||
45 | |||
46 | This driver is a client driver to the core PMBus driver. Please see | ||
47 | Documentation/hwmon/pmbus for details on PMBus client drivers. | ||
48 | |||
49 | |||
50 | Usage Notes | ||
51 | ----------- | ||
52 | |||
53 | This driver does not auto-detect devices. You will have to instantiate the | ||
54 | devices explicitly. Please see Documentation/i2c/instantiating-devices for | ||
55 | details. | ||
56 | |||
57 | |||
58 | Platform data support | ||
59 | --------------------- | ||
60 | |||
61 | The driver supports standard PMBus driver platform data. Please see | ||
62 | Documentation/hwmon/pmbus for details. | ||
63 | |||
64 | |||
65 | Sysfs entries | ||
66 | ------------- | ||
67 | |||
68 | The following attributes are supported. Limits are read-write; all other | ||
69 | attributes are read-only. | ||
70 | |||
71 | in[1-12]_label "vout[1-12]". | ||
72 | in[1-12]_input Measured voltage. From READ_VOUT register. | ||
73 | in[1-12]_min Minumum Voltage. From VOUT_UV_WARN_LIMIT register. | ||
74 | in[1-12]_max Maximum voltage. From VOUT_OV_WARN_LIMIT register. | ||
75 | in[1-12]_lcrit Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register. | ||
76 | in[1-12]_crit Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register. | ||
77 | in[1-12]_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status. | ||
78 | in[1-12]_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status. | ||
79 | in[1-12]_lcrit_alarm Voltage critical low alarm. From VOLTAGE_UV_FAULT status. | ||
80 | in[1-12]_crit_alarm Voltage critical high alarm. From VOLTAGE_OV_FAULT status. | ||
81 | |||
82 | curr[1-12]_label "iout[1-12]". | ||
83 | curr[1-12]_input Measured current. From READ_IOUT register. | ||
84 | curr[1-12]_max Maximum current. From IOUT_OC_WARN_LIMIT register. | ||
85 | curr[1-12]_lcrit Critical minumum output current. From IOUT_UC_FAULT_LIMIT | ||
86 | register. | ||
87 | curr[1-12]_crit Critical maximum current. From IOUT_OC_FAULT_LIMIT register. | ||
88 | curr[1-12]_max_alarm Current high alarm. From IOUT_OC_WARNING status. | ||
89 | curr[1-12]_crit_alarm Current critical high alarm. From IOUT_OC_FAULT status. | ||
90 | |||
91 | For each attribute index, either voltage or current is | ||
92 | reported, but not both. If voltage or current is | ||
93 | reported depends on the chip configuration. | ||
94 | |||
95 | temp[1-2]_input Measured temperatures. From READ_TEMPERATURE_1 and | ||
96 | READ_TEMPERATURE_2 registers. | ||
97 | temp[1-2]_max Maximum temperature. From OT_WARN_LIMIT register. | ||
98 | temp[1-2]_crit Critical high temperature. From OT_FAULT_LIMIT register. | ||
99 | temp[1-2]_max_alarm Temperature high alarm. | ||
100 | temp[1-2]_crit_alarm Temperature critical high alarm. | ||
101 | |||
102 | fan[1-4]_input Fan RPM. | ||
103 | fan[1-4]_alarm Fan alarm. | ||
104 | fan[1-4]_fault Fan fault. | ||
105 | |||
106 | Fan attributes are only available on chips supporting | ||
107 | fan control (UCD90124, UCD90910). Attribute files are | ||
108 | created only for enabled fans. | ||
109 | Note that even though UCD90910 supports up to 10 fans, | ||
110 | only up to four fans are currently supported. | ||
diff --git a/Documentation/hwmon/ucd9200 b/Documentation/hwmon/ucd9200 new file mode 100644 index 000000000000..3c58607f72fe --- /dev/null +++ b/Documentation/hwmon/ucd9200 | |||
@@ -0,0 +1,112 @@ | |||
1 | Kernel driver ucd9200 | ||
2 | ===================== | ||
3 | |||
4 | Supported chips: | ||
5 | * TI UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and UCD9248 | ||
6 | Prefixes: 'ucd9220', 'ucd9222', 'ucd9224', 'ucd9240', 'ucd9244', 'ucd9246', | ||
7 | 'ucd9248' | ||
8 | Addresses scanned: - | ||
9 | Datasheets: | ||
10 | http://focus.ti.com/lit/ds/symlink/ucd9220.pdf | ||
11 | http://focus.ti.com/lit/ds/symlink/ucd9222.pdf | ||
12 | http://focus.ti.com/lit/ds/symlink/ucd9224.pdf | ||
13 | http://focus.ti.com/lit/ds/symlink/ucd9240.pdf | ||
14 | http://focus.ti.com/lit/ds/symlink/ucd9244.pdf | ||
15 | http://focus.ti.com/lit/ds/symlink/ucd9246.pdf | ||
16 | http://focus.ti.com/lit/ds/symlink/ucd9248.pdf | ||
17 | |||
18 | Author: Guenter Roeck <guenter.roeck@ericsson.com> | ||
19 | |||
20 | |||
21 | Description | ||
22 | ----------- | ||
23 | |||
24 | [From datasheets] UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and | ||
25 | UCD9248 are multi-rail, multi-phase synchronous buck digital PWM controllers | ||
26 | designed for non-isolated DC/DC power applications. The devices integrate | ||
27 | dedicated circuitry for DC/DC loop management with flash memory and a serial | ||
28 | interface to support configuration, monitoring and management. | ||
29 | |||
30 | This driver is a client driver to the core PMBus driver. Please see | ||
31 | Documentation/hwmon/pmbus for details on PMBus client drivers. | ||
32 | |||
33 | |||
34 | Usage Notes | ||
35 | ----------- | ||
36 | |||
37 | This driver does not auto-detect devices. You will have to instantiate the | ||
38 | devices explicitly. Please see Documentation/i2c/instantiating-devices for | ||
39 | details. | ||
40 | |||
41 | |||
42 | Platform data support | ||
43 | --------------------- | ||
44 | |||
45 | The driver supports standard PMBus driver platform data. Please see | ||
46 | Documentation/hwmon/pmbus for details. | ||
47 | |||
48 | |||
49 | Sysfs entries | ||
50 | ------------- | ||
51 | |||
52 | The following attributes are supported. Limits are read-write; all other | ||
53 | attributes are read-only. | ||
54 | |||
55 | in1_label "vin". | ||
56 | in1_input Measured voltage. From READ_VIN register. | ||
57 | in1_min Minumum Voltage. From VIN_UV_WARN_LIMIT register. | ||
58 | in1_max Maximum voltage. From VIN_OV_WARN_LIMIT register. | ||
59 | in1_lcrit Critical minumum Voltage. VIN_UV_FAULT_LIMIT register. | ||
60 | in1_crit Critical maximum voltage. From VIN_OV_FAULT_LIMIT register. | ||
61 | in1_min_alarm Voltage low alarm. From VIN_UV_WARNING status. | ||
62 | in1_max_alarm Voltage high alarm. From VIN_OV_WARNING status. | ||
63 | in1_lcrit_alarm Voltage critical low alarm. From VIN_UV_FAULT status. | ||
64 | in1_crit_alarm Voltage critical high alarm. From VIN_OV_FAULT status. | ||
65 | |||
66 | in[2-5]_label "vout[1-4]". | ||
67 | in[2-5]_input Measured voltage. From READ_VOUT register. | ||
68 | in[2-5]_min Minumum Voltage. From VOUT_UV_WARN_LIMIT register. | ||
69 | in[2-5]_max Maximum voltage. From VOUT_OV_WARN_LIMIT register. | ||
70 | in[2-5]_lcrit Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register. | ||
71 | in[2-5]_crit Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register. | ||
72 | in[2-5]_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status. | ||
73 | in[2-5]_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status. | ||
74 | in[2-5]_lcrit_alarm Voltage critical low alarm. From VOLTAGE_UV_FAULT status. | ||
75 | in[2-5]_crit_alarm Voltage critical high alarm. From VOLTAGE_OV_FAULT status. | ||
76 | |||
77 | curr1_label "iin". | ||
78 | curr1_input Measured current. From READ_IIN register. | ||
79 | |||
80 | curr[2-5]_label "iout[1-4]". | ||
81 | curr[2-5]_input Measured current. From READ_IOUT register. | ||
82 | curr[2-5]_max Maximum current. From IOUT_OC_WARN_LIMIT register. | ||
83 | curr[2-5]_lcrit Critical minumum output current. From IOUT_UC_FAULT_LIMIT | ||
84 | register. | ||
85 | curr[2-5]_crit Critical maximum current. From IOUT_OC_FAULT_LIMIT register. | ||
86 | curr[2-5]_max_alarm Current high alarm. From IOUT_OC_WARNING status. | ||
87 | curr[2-5]_crit_alarm Current critical high alarm. From IOUT_OC_FAULT status. | ||
88 | |||
89 | power1_input Measured input power. From READ_PIN register. | ||
90 | power1_label "pin" | ||
91 | |||
92 | power[2-5]_input Measured output power. From READ_POUT register. | ||
93 | power[2-5]_label "pout[1-4]" | ||
94 | |||
95 | The number of output voltage, current, and power | ||
96 | attribute sets is determined by the number of enabled | ||
97 | rails. See chip datasheets for details. | ||
98 | |||
99 | temp[1-5]_input Measured temperatures. From READ_TEMPERATURE_1 and | ||
100 | READ_TEMPERATURE_2 registers. | ||
101 | temp1 is the chip internal temperature. temp[2-5] are | ||
102 | rail temperatures. temp[2-5] attributes are only | ||
103 | created for enabled rails. See chip datasheets for | ||
104 | details. | ||
105 | temp[1-5]_max Maximum temperature. From OT_WARN_LIMIT register. | ||
106 | temp[1-5]_crit Critical high temperature. From OT_FAULT_LIMIT register. | ||
107 | temp[1-5]_max_alarm Temperature high alarm. | ||
108 | temp[1-5]_crit_alarm Temperature critical high alarm. | ||
109 | |||
110 | fan1_input Fan RPM. ucd9240 only. | ||
111 | fan1_alarm Fan alarm. ucd9240 only. | ||
112 | fan1_fault Fan fault. ucd9240 only. | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 50e40dbd8bb6..43221beb9e97 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -408,13 +408,6 @@ config SENSORS_CORETEMP | |||
408 | sensor inside your CPU. Most of the family 6 CPUs | 408 | sensor inside your CPU. Most of the family 6 CPUs |
409 | are supported. Check Documentation/hwmon/coretemp for details. | 409 | are supported. Check Documentation/hwmon/coretemp for details. |
410 | 410 | ||
411 | config SENSORS_PKGTEMP | ||
412 | tristate "Intel processor package temperature sensor" | ||
413 | depends on X86 && EXPERIMENTAL | ||
414 | help | ||
415 | If you say yes here you get support for the package level temperature | ||
416 | sensor inside your CPU. Check documentation/driver for details. | ||
417 | |||
418 | config SENSORS_IBMAEM | 411 | config SENSORS_IBMAEM |
419 | tristate "IBM Active Energy Manager temperature/power sensors and control" | 412 | tristate "IBM Active Energy Manager temperature/power sensors and control" |
420 | select IPMI_SI | 413 | select IPMI_SI |
@@ -708,6 +701,22 @@ config SENSORS_MAX1111 | |||
708 | This driver can also be built as a module. If so, the module | 701 | This driver can also be built as a module. If so, the module |
709 | will be called max1111. | 702 | will be called max1111. |
710 | 703 | ||
704 | config SENSORS_MAX16065 | ||
705 | tristate "Maxim MAX16065 System Manager and compatibles" | ||
706 | depends on I2C | ||
707 | help | ||
708 | If you say yes here you get support for hardware monitoring | ||
709 | capabilities of the following Maxim System Manager chips. | ||
710 | MAX16065 | ||
711 | MAX16066 | ||
712 | MAX16067 | ||
713 | MAX16068 | ||
714 | MAX16070 | ||
715 | MAX16071 | ||
716 | |||
717 | This driver can also be built as a module. If so, the module | ||
718 | will be called max16065. | ||
719 | |||
711 | config SENSORS_MAX1619 | 720 | config SENSORS_MAX1619 |
712 | tristate "Maxim MAX1619 sensor chip" | 721 | tristate "Maxim MAX1619 sensor chip" |
713 | depends on I2C | 722 | depends on I2C |
@@ -727,6 +736,17 @@ config SENSORS_MAX6639 | |||
727 | This driver can also be built as a module. If so, the module | 736 | This driver can also be built as a module. If so, the module |
728 | will be called max6639. | 737 | will be called max6639. |
729 | 738 | ||
739 | config SENSORS_MAX6642 | ||
740 | tristate "Maxim MAX6642 sensor chip" | ||
741 | depends on I2C && EXPERIMENTAL | ||
742 | help | ||
743 | If you say yes here you get support for MAX6642 sensor chip. | ||
744 | MAX6642 is a SMBus-Compatible Remote/Local Temperature Sensor | ||
745 | with Overtemperature Alarm from Maxim. | ||
746 | |||
747 | This driver can also be built as a module. If so, the module | ||
748 | will be called max6642. | ||
749 | |||
730 | config SENSORS_MAX6650 | 750 | config SENSORS_MAX6650 |
731 | tristate "Maxim MAX6650 sensor chip" | 751 | tristate "Maxim MAX6650 sensor chip" |
732 | depends on I2C && EXPERIMENTAL | 752 | depends on I2C && EXPERIMENTAL |
@@ -800,6 +820,16 @@ config SENSORS_PMBUS | |||
800 | This driver can also be built as a module. If so, the module will | 820 | This driver can also be built as a module. If so, the module will |
801 | be called pmbus. | 821 | be called pmbus. |
802 | 822 | ||
823 | config SENSORS_ADM1275 | ||
824 | tristate "Analog Devices ADM1275" | ||
825 | default n | ||
826 | help | ||
827 | If you say yes here you get hardware monitoring support for Analog | ||
828 | Devices ADM1275 Hot-Swap Controller and Digital Power Monitor. | ||
829 | |||
830 | This driver can also be built as a module. If so, the module will | ||
831 | be called adm1275. | ||
832 | |||
803 | config SENSORS_MAX16064 | 833 | config SENSORS_MAX16064 |
804 | tristate "Maxim MAX16064" | 834 | tristate "Maxim MAX16064" |
805 | default n | 835 | default n |
@@ -830,6 +860,28 @@ config SENSORS_MAX8688 | |||
830 | This driver can also be built as a module. If so, the module will | 860 | This driver can also be built as a module. If so, the module will |
831 | be called max8688. | 861 | be called max8688. |
832 | 862 | ||
863 | config SENSORS_UCD9000 | ||
864 | tristate "TI UCD90120, UCD90124, UCD9090, UCD90910" | ||
865 | default n | ||
866 | help | ||
867 | If you say yes here you get hardware monitoring support for TI | ||
868 | UCD90120, UCD90124, UCD9090, UCD90910 Sequencer and System Health | ||
869 | Controllers. | ||
870 | |||
871 | This driver can also be built as a module. If so, the module will | ||
872 | be called ucd9000. | ||
873 | |||
874 | config SENSORS_UCD9200 | ||
875 | tristate "TI UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, UCD9248" | ||
876 | default n | ||
877 | help | ||
878 | If you say yes here you get hardware monitoring support for TI | ||
879 | UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and UCD9248 | ||
880 | Digital PWM System Controllers. | ||
881 | |||
882 | This driver can also be built as a module. If so, the module will | ||
883 | be called ucd9200. | ||
884 | |||
833 | endif # PMBUS | 885 | endif # PMBUS |
834 | 886 | ||
835 | config SENSORS_SHT15 | 887 | config SENSORS_SHT15 |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 967d0ea9447f..28e8d52f6379 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -40,7 +40,6 @@ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | |||
40 | obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o | 40 | obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o |
41 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 41 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
42 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | 42 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o |
43 | obj-$(CONFIG_SENSORS_PKGTEMP) += pkgtemp.o | ||
44 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | 43 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o |
45 | obj-$(CONFIG_SENSORS_DS620) += ds620.o | 44 | obj-$(CONFIG_SENSORS_DS620) += ds620.o |
46 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 45 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
@@ -83,8 +82,10 @@ obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o | |||
83 | obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o | 82 | obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o |
84 | obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o | 83 | obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o |
85 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o | 84 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o |
85 | obj-$(CONFIG_SENSORS_MAX16065) += max16065.o | ||
86 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 86 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
87 | obj-$(CONFIG_SENSORS_MAX6639) += max6639.o | 87 | obj-$(CONFIG_SENSORS_MAX6639) += max6639.o |
88 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o | ||
88 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | 89 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o |
89 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o | 90 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o |
90 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 91 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
@@ -118,9 +119,12 @@ obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o | |||
118 | # PMBus drivers | 119 | # PMBus drivers |
119 | obj-$(CONFIG_PMBUS) += pmbus_core.o | 120 | obj-$(CONFIG_PMBUS) += pmbus_core.o |
120 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o | 121 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o |
122 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o | ||
121 | obj-$(CONFIG_SENSORS_MAX16064) += max16064.o | 123 | obj-$(CONFIG_SENSORS_MAX16064) += max16064.o |
122 | obj-$(CONFIG_SENSORS_MAX34440) += max34440.o | 124 | obj-$(CONFIG_SENSORS_MAX34440) += max34440.o |
123 | obj-$(CONFIG_SENSORS_MAX8688) += max8688.o | 125 | obj-$(CONFIG_SENSORS_MAX8688) += max8688.o |
126 | obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o | ||
127 | obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o | ||
124 | 128 | ||
125 | ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG | 129 | ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG |
126 | 130 | ||
diff --git a/drivers/hwmon/adm1275.c b/drivers/hwmon/adm1275.c new file mode 100644 index 000000000000..c2ee2048ab91 --- /dev/null +++ b/drivers/hwmon/adm1275.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Hardware monitoring driver for Analog Devices ADM1275 Hot-Swap Controller | ||
3 | * and Digital Power Monitor | ||
4 | * | ||
5 | * Copyright (c) 2011 Ericsson AB. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include "pmbus.h" | ||
25 | |||
26 | #define ADM1275_PMON_CONFIG 0xd4 | ||
27 | |||
28 | #define ADM1275_VIN_VOUT_SELECT (1 << 6) | ||
29 | #define ADM1275_VRANGE (1 << 5) | ||
30 | |||
31 | static int adm1275_probe(struct i2c_client *client, | ||
32 | const struct i2c_device_id *id) | ||
33 | { | ||
34 | int config; | ||
35 | struct pmbus_driver_info *info; | ||
36 | |||
37 | if (!i2c_check_functionality(client->adapter, | ||
38 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) | ||
39 | return -ENODEV; | ||
40 | |||
41 | info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); | ||
42 | if (!info) | ||
43 | return -ENOMEM; | ||
44 | |||
45 | config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); | ||
46 | if (config < 0) | ||
47 | return config; | ||
48 | |||
49 | info->pages = 1; | ||
50 | info->direct[PSC_VOLTAGE_IN] = true; | ||
51 | info->direct[PSC_VOLTAGE_OUT] = true; | ||
52 | info->direct[PSC_CURRENT_OUT] = true; | ||
53 | info->m[PSC_CURRENT_OUT] = 800; | ||
54 | info->b[PSC_CURRENT_OUT] = 20475; | ||
55 | info->R[PSC_CURRENT_OUT] = -1; | ||
56 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | ||
57 | |||
58 | if (config & ADM1275_VRANGE) { | ||
59 | info->m[PSC_VOLTAGE_IN] = 19045; | ||
60 | info->b[PSC_VOLTAGE_IN] = 0; | ||
61 | info->R[PSC_VOLTAGE_IN] = -2; | ||
62 | info->m[PSC_VOLTAGE_OUT] = 19045; | ||
63 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
64 | info->R[PSC_VOLTAGE_OUT] = -2; | ||
65 | } else { | ||
66 | info->m[PSC_VOLTAGE_IN] = 6666; | ||
67 | info->b[PSC_VOLTAGE_IN] = 0; | ||
68 | info->R[PSC_VOLTAGE_IN] = -1; | ||
69 | info->m[PSC_VOLTAGE_OUT] = 6666; | ||
70 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
71 | info->R[PSC_VOLTAGE_OUT] = -1; | ||
72 | } | ||
73 | |||
74 | if (config & ADM1275_VIN_VOUT_SELECT) | ||
75 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | ||
76 | else | ||
77 | info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT; | ||
78 | |||
79 | return pmbus_do_probe(client, id, info); | ||
80 | } | ||
81 | |||
82 | static int adm1275_remove(struct i2c_client *client) | ||
83 | { | ||
84 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
85 | int ret; | ||
86 | |||
87 | ret = pmbus_do_remove(client); | ||
88 | kfree(info); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static const struct i2c_device_id adm1275_id[] = { | ||
93 | {"adm1275", 0}, | ||
94 | { } | ||
95 | }; | ||
96 | MODULE_DEVICE_TABLE(i2c, adm1275_id); | ||
97 | |||
98 | static struct i2c_driver adm1275_driver = { | ||
99 | .driver = { | ||
100 | .name = "adm1275", | ||
101 | }, | ||
102 | .probe = adm1275_probe, | ||
103 | .remove = adm1275_remove, | ||
104 | .id_table = adm1275_id, | ||
105 | }; | ||
106 | |||
107 | static int __init adm1275_init(void) | ||
108 | { | ||
109 | return i2c_add_driver(&adm1275_driver); | ||
110 | } | ||
111 | |||
112 | static void __exit adm1275_exit(void) | ||
113 | { | ||
114 | i2c_del_driver(&adm1275_driver); | ||
115 | } | ||
116 | |||
117 | MODULE_AUTHOR("Guenter Roeck"); | ||
118 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275"); | ||
119 | MODULE_LICENSE("GPL"); | ||
120 | module_init(adm1275_init); | ||
121 | module_exit(adm1275_exit); | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 194ca0aa8b0c..5c7cd60d5f9d 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -35,128 +35,152 @@ | |||
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/cpu.h> | 36 | #include <linux/cpu.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/smp.h> | ||
38 | #include <asm/msr.h> | 39 | #include <asm/msr.h> |
39 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
40 | #include <asm/smp.h> | ||
41 | 41 | ||
42 | #define DRVNAME "coretemp" | 42 | #define DRVNAME "coretemp" |
43 | 43 | ||
44 | typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL, | 44 | #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ |
45 | SHOW_NAME } SHOW; | 45 | #define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ |
46 | #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ | ||
47 | #define MAX_ATTRS 5 /* Maximum no of per-core attrs */ | ||
48 | #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) | ||
49 | |||
50 | #ifdef CONFIG_SMP | ||
51 | #define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id | ||
52 | #define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id | ||
53 | #define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) | ||
54 | #else | ||
55 | #define TO_PHYS_ID(cpu) (cpu) | ||
56 | #define TO_CORE_ID(cpu) (cpu) | ||
57 | #define TO_ATTR_NO(cpu) (cpu) | ||
58 | #endif | ||
46 | 59 | ||
47 | /* | 60 | /* |
48 | * Functions declaration | 61 | * Per-Core Temperature Data |
62 | * @last_updated: The time when the current temperature value was updated | ||
63 | * earlier (in jiffies). | ||
64 | * @cpu_core_id: The CPU Core from which temperature values should be read | ||
65 | * This value is passed as "id" field to rdmsr/wrmsr functions. | ||
66 | * @status_reg: One of IA32_THERM_STATUS or IA32_PACKAGE_THERM_STATUS, | ||
67 | * from where the temperature values should be read. | ||
68 | * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data. | ||
69 | * Otherwise, temp_data holds coretemp data. | ||
70 | * @valid: If this is 1, the current temperature is valid. | ||
49 | */ | 71 | */ |
50 | 72 | struct temp_data { | |
51 | static struct coretemp_data *coretemp_update_device(struct device *dev); | ||
52 | |||
53 | struct coretemp_data { | ||
54 | struct device *hwmon_dev; | ||
55 | struct mutex update_lock; | ||
56 | const char *name; | ||
57 | u32 id; | ||
58 | u16 core_id; | ||
59 | char valid; /* zero until following fields are valid */ | ||
60 | unsigned long last_updated; /* in jiffies */ | ||
61 | int temp; | 73 | int temp; |
62 | int tjmax; | ||
63 | int ttarget; | 74 | int ttarget; |
64 | u8 alarm; | 75 | int tjmax; |
76 | unsigned long last_updated; | ||
77 | unsigned int cpu; | ||
78 | u32 cpu_core_id; | ||
79 | u32 status_reg; | ||
80 | bool is_pkg_data; | ||
81 | bool valid; | ||
82 | struct sensor_device_attribute sd_attrs[MAX_ATTRS]; | ||
83 | char attr_name[MAX_ATTRS][CORETEMP_NAME_LENGTH]; | ||
84 | struct mutex update_lock; | ||
65 | }; | 85 | }; |
66 | 86 | ||
67 | /* | 87 | /* Platform Data per Physical CPU */ |
68 | * Sysfs stuff | 88 | struct platform_data { |
69 | */ | 89 | struct device *hwmon_dev; |
90 | u16 phys_proc_id; | ||
91 | struct temp_data *core_data[MAX_CORE_DATA]; | ||
92 | struct device_attribute name_attr; | ||
93 | }; | ||
70 | 94 | ||
71 | static ssize_t show_name(struct device *dev, struct device_attribute | 95 | struct pdev_entry { |
72 | *devattr, char *buf) | 96 | struct list_head list; |
97 | struct platform_device *pdev; | ||
98 | unsigned int cpu; | ||
99 | u16 phys_proc_id; | ||
100 | u16 cpu_core_id; | ||
101 | }; | ||
102 | |||
103 | static LIST_HEAD(pdev_list); | ||
104 | static DEFINE_MUTEX(pdev_list_mutex); | ||
105 | |||
106 | static ssize_t show_name(struct device *dev, | ||
107 | struct device_attribute *devattr, char *buf) | ||
108 | { | ||
109 | return sprintf(buf, "%s\n", DRVNAME); | ||
110 | } | ||
111 | |||
112 | static ssize_t show_label(struct device *dev, | ||
113 | struct device_attribute *devattr, char *buf) | ||
73 | { | 114 | { |
74 | int ret; | ||
75 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 115 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
76 | struct coretemp_data *data = dev_get_drvdata(dev); | 116 | struct platform_data *pdata = dev_get_drvdata(dev); |
117 | struct temp_data *tdata = pdata->core_data[attr->index]; | ||
77 | 118 | ||
78 | if (attr->index == SHOW_NAME) | 119 | if (tdata->is_pkg_data) |
79 | ret = sprintf(buf, "%s\n", data->name); | 120 | return sprintf(buf, "Physical id %u\n", pdata->phys_proc_id); |
80 | else /* show label */ | 121 | |
81 | ret = sprintf(buf, "Core %d\n", data->core_id); | 122 | return sprintf(buf, "Core %u\n", tdata->cpu_core_id); |
82 | return ret; | ||
83 | } | 123 | } |
84 | 124 | ||
85 | static ssize_t show_alarm(struct device *dev, struct device_attribute | 125 | static ssize_t show_crit_alarm(struct device *dev, |
86 | *devattr, char *buf) | 126 | struct device_attribute *devattr, char *buf) |
87 | { | 127 | { |
88 | struct coretemp_data *data = coretemp_update_device(dev); | 128 | u32 eax, edx; |
89 | /* read the Out-of-spec log, never clear */ | 129 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
90 | return sprintf(buf, "%d\n", data->alarm); | 130 | struct platform_data *pdata = dev_get_drvdata(dev); |
131 | struct temp_data *tdata = pdata->core_data[attr->index]; | ||
132 | |||
133 | rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); | ||
134 | |||
135 | return sprintf(buf, "%d\n", (eax >> 5) & 1); | ||
91 | } | 136 | } |
92 | 137 | ||
93 | static ssize_t show_temp(struct device *dev, | 138 | static ssize_t show_tjmax(struct device *dev, |
94 | struct device_attribute *devattr, char *buf) | 139 | struct device_attribute *devattr, char *buf) |
95 | { | 140 | { |
96 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 141 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
97 | struct coretemp_data *data = coretemp_update_device(dev); | 142 | struct platform_data *pdata = dev_get_drvdata(dev); |
98 | int err; | ||
99 | 143 | ||
100 | if (attr->index == SHOW_TEMP) | 144 | return sprintf(buf, "%d\n", pdata->core_data[attr->index]->tjmax); |
101 | err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN; | ||
102 | else if (attr->index == SHOW_TJMAX) | ||
103 | err = sprintf(buf, "%d\n", data->tjmax); | ||
104 | else | ||
105 | err = sprintf(buf, "%d\n", data->ttarget); | ||
106 | return err; | ||
107 | } | 145 | } |
108 | 146 | ||
109 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, | 147 | static ssize_t show_ttarget(struct device *dev, |
110 | SHOW_TEMP); | 148 | struct device_attribute *devattr, char *buf) |
111 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, | 149 | { |
112 | SHOW_TJMAX); | 150 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
113 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, | 151 | struct platform_data *pdata = dev_get_drvdata(dev); |
114 | SHOW_TTARGET); | ||
115 | static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL); | ||
116 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); | ||
117 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); | ||
118 | |||
119 | static struct attribute *coretemp_attributes[] = { | ||
120 | &sensor_dev_attr_name.dev_attr.attr, | ||
121 | &sensor_dev_attr_temp1_label.dev_attr.attr, | ||
122 | &dev_attr_temp1_crit_alarm.attr, | ||
123 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
124 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
125 | NULL | ||
126 | }; | ||
127 | 152 | ||
128 | static const struct attribute_group coretemp_group = { | 153 | return sprintf(buf, "%d\n", pdata->core_data[attr->index]->ttarget); |
129 | .attrs = coretemp_attributes, | 154 | } |
130 | }; | ||
131 | 155 | ||
132 | static struct coretemp_data *coretemp_update_device(struct device *dev) | 156 | static ssize_t show_temp(struct device *dev, |
157 | struct device_attribute *devattr, char *buf) | ||
133 | { | 158 | { |
134 | struct coretemp_data *data = dev_get_drvdata(dev); | 159 | u32 eax, edx; |
135 | 160 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | |
136 | mutex_lock(&data->update_lock); | 161 | struct platform_data *pdata = dev_get_drvdata(dev); |
162 | struct temp_data *tdata = pdata->core_data[attr->index]; | ||
137 | 163 | ||
138 | if (!data->valid || time_after(jiffies, data->last_updated + HZ)) { | 164 | mutex_lock(&tdata->update_lock); |
139 | u32 eax, edx; | ||
140 | 165 | ||
141 | data->valid = 0; | 166 | /* Check whether the time interval has elapsed */ |
142 | rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); | 167 | if (!tdata->valid || time_after(jiffies, tdata->last_updated + HZ)) { |
143 | data->alarm = (eax >> 5) & 1; | 168 | rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); |
144 | /* update only if data has been valid */ | 169 | tdata->valid = 0; |
170 | /* Check whether the data is valid */ | ||
145 | if (eax & 0x80000000) { | 171 | if (eax & 0x80000000) { |
146 | data->temp = data->tjmax - (((eax >> 16) | 172 | tdata->temp = tdata->tjmax - |
147 | & 0x7f) * 1000); | 173 | ((eax >> 16) & 0x7f) * 1000; |
148 | data->valid = 1; | 174 | tdata->valid = 1; |
149 | } else { | ||
150 | dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax); | ||
151 | } | 175 | } |
152 | data->last_updated = jiffies; | 176 | tdata->last_updated = jiffies; |
153 | } | 177 | } |
154 | 178 | ||
155 | mutex_unlock(&data->update_lock); | 179 | mutex_unlock(&tdata->update_lock); |
156 | return data; | 180 | return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; |
157 | } | 181 | } |
158 | 182 | ||
159 | static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | 183 | static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) |
160 | { | 184 | { |
161 | /* The 100C is default for both mobile and non mobile CPUs */ | 185 | /* The 100C is default for both mobile and non mobile CPUs */ |
162 | 186 | ||
@@ -169,9 +193,8 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
169 | 193 | ||
170 | /* Early chips have no MSR for TjMax */ | 194 | /* Early chips have no MSR for TjMax */ |
171 | 195 | ||
172 | if ((c->x86_model == 0xf) && (c->x86_mask < 4)) { | 196 | if (c->x86_model == 0xf && c->x86_mask < 4) |
173 | usemsr_ee = 0; | 197 | usemsr_ee = 0; |
174 | } | ||
175 | 198 | ||
176 | /* Atom CPUs */ | 199 | /* Atom CPUs */ |
177 | 200 | ||
@@ -190,14 +213,14 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
190 | pci_dev_put(host_bridge); | 213 | pci_dev_put(host_bridge); |
191 | } | 214 | } |
192 | 215 | ||
193 | if ((c->x86_model > 0xe) && (usemsr_ee)) { | 216 | if (c->x86_model > 0xe && usemsr_ee) { |
194 | u8 platform_id; | 217 | u8 platform_id; |
195 | 218 | ||
196 | /* Now we can detect the mobile CPU using Intel provided table | 219 | /* |
197 | http://softwarecommunity.intel.com/Wiki/Mobility/720.htm | 220 | * Now we can detect the mobile CPU using Intel provided table |
198 | For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU | 221 | * http://softwarecommunity.intel.com/Wiki/Mobility/720.htm |
199 | */ | 222 | * For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU |
200 | 223 | */ | |
201 | err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx); | 224 | err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx); |
202 | if (err) { | 225 | if (err) { |
203 | dev_warn(dev, | 226 | dev_warn(dev, |
@@ -205,20 +228,26 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
205 | " CPU\n"); | 228 | " CPU\n"); |
206 | usemsr_ee = 0; | 229 | usemsr_ee = 0; |
207 | } else if (c->x86_model < 0x17 && !(eax & 0x10000000)) { | 230 | } else if (c->x86_model < 0x17 && !(eax & 0x10000000)) { |
208 | /* Trust bit 28 up to Penryn, I could not find any | 231 | /* |
209 | documentation on that; if you happen to know | 232 | * Trust bit 28 up to Penryn, I could not find any |
210 | someone at Intel please ask */ | 233 | * documentation on that; if you happen to know |
234 | * someone at Intel please ask | ||
235 | */ | ||
211 | usemsr_ee = 0; | 236 | usemsr_ee = 0; |
212 | } else { | 237 | } else { |
213 | /* Platform ID bits 52:50 (EDX starts at bit 32) */ | 238 | /* Platform ID bits 52:50 (EDX starts at bit 32) */ |
214 | platform_id = (edx >> 18) & 0x7; | 239 | platform_id = (edx >> 18) & 0x7; |
215 | 240 | ||
216 | /* Mobile Penryn CPU seems to be platform ID 7 or 5 | 241 | /* |
217 | (guesswork) */ | 242 | * Mobile Penryn CPU seems to be platform ID 7 or 5 |
218 | if ((c->x86_model == 0x17) && | 243 | * (guesswork) |
219 | ((platform_id == 5) || (platform_id == 7))) { | 244 | */ |
220 | /* If MSR EE bit is set, set it to 90 degrees C, | 245 | if (c->x86_model == 0x17 && |
221 | otherwise 105 degrees C */ | 246 | (platform_id == 5 || platform_id == 7)) { |
247 | /* | ||
248 | * If MSR EE bit is set, set it to 90 degrees C, | ||
249 | * otherwise 105 degrees C | ||
250 | */ | ||
222 | tjmax_ee = 90000; | 251 | tjmax_ee = 90000; |
223 | tjmax = 105000; | 252 | tjmax = 105000; |
224 | } | 253 | } |
@@ -226,7 +255,6 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
226 | } | 255 | } |
227 | 256 | ||
228 | if (usemsr_ee) { | 257 | if (usemsr_ee) { |
229 | |||
230 | err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); | 258 | err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); |
231 | if (err) { | 259 | if (err) { |
232 | dev_warn(dev, | 260 | dev_warn(dev, |
@@ -235,25 +263,28 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
235 | } else if (eax & 0x40000000) { | 263 | } else if (eax & 0x40000000) { |
236 | tjmax = tjmax_ee; | 264 | tjmax = tjmax_ee; |
237 | } | 265 | } |
238 | /* if we dont use msr EE it means we are desktop CPU (with exeception | ||
239 | of Atom) */ | ||
240 | } else if (tjmax == 100000) { | 266 | } else if (tjmax == 100000) { |
267 | /* | ||
268 | * If we don't use msr EE it means we are desktop CPU | ||
269 | * (with exeception of Atom) | ||
270 | */ | ||
241 | dev_warn(dev, "Using relative temperature scale!\n"); | 271 | dev_warn(dev, "Using relative temperature scale!\n"); |
242 | } | 272 | } |
243 | 273 | ||
244 | return tjmax; | 274 | return tjmax; |
245 | } | 275 | } |
246 | 276 | ||
247 | static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, | 277 | static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) |
248 | struct device *dev) | ||
249 | { | 278 | { |
250 | /* The 100C is default for both mobile and non mobile CPUs */ | 279 | /* The 100C is default for both mobile and non mobile CPUs */ |
251 | int err; | 280 | int err; |
252 | u32 eax, edx; | 281 | u32 eax, edx; |
253 | u32 val; | 282 | u32 val; |
254 | 283 | ||
255 | /* A new feature of current Intel(R) processors, the | 284 | /* |
256 | IA32_TEMPERATURE_TARGET contains the TjMax value */ | 285 | * A new feature of current Intel(R) processors, the |
286 | * IA32_TEMPERATURE_TARGET contains the TjMax value | ||
287 | */ | ||
257 | err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); | 288 | err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); |
258 | if (err) { | 289 | if (err) { |
259 | dev_warn(dev, "Unable to read TjMax from CPU.\n"); | 290 | dev_warn(dev, "Unable to read TjMax from CPU.\n"); |
@@ -263,7 +294,7 @@ static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, | |||
263 | * If the TjMax is not plausible, an assumption | 294 | * If the TjMax is not plausible, an assumption |
264 | * will be used | 295 | * will be used |
265 | */ | 296 | */ |
266 | if ((val > 80) && (val < 120)) { | 297 | if (val > 80 && val < 120) { |
267 | dev_info(dev, "TjMax is %d C.\n", val); | 298 | dev_info(dev, "TjMax is %d C.\n", val); |
268 | return val * 1000; | 299 | return val * 1000; |
269 | } | 300 | } |
@@ -300,115 +331,293 @@ static void __devinit get_ucode_rev_on_cpu(void *edx) | |||
300 | rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx); | 331 | rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx); |
301 | } | 332 | } |
302 | 333 | ||
303 | static int __devinit coretemp_probe(struct platform_device *pdev) | 334 | static int get_pkg_tjmax(unsigned int cpu, struct device *dev) |
304 | { | 335 | { |
305 | struct coretemp_data *data; | ||
306 | struct cpuinfo_x86 *c = &cpu_data(pdev->id); | ||
307 | int err; | 336 | int err; |
308 | u32 eax, edx; | 337 | u32 eax, edx, val; |
309 | 338 | ||
310 | if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) { | 339 | err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); |
311 | err = -ENOMEM; | 340 | if (!err) { |
312 | dev_err(&pdev->dev, "Out of memory\n"); | 341 | val = (eax >> 16) & 0xff; |
313 | goto exit; | 342 | if (val > 80 && val < 120) |
343 | return val * 1000; | ||
314 | } | 344 | } |
345 | dev_warn(dev, "Unable to read Pkg-TjMax from CPU:%u\n", cpu); | ||
346 | return 100000; /* Default TjMax: 100 degree celsius */ | ||
347 | } | ||
315 | 348 | ||
316 | data->id = pdev->id; | 349 | static int create_name_attr(struct platform_data *pdata, struct device *dev) |
317 | #ifdef CONFIG_SMP | 350 | { |
318 | data->core_id = c->cpu_core_id; | 351 | pdata->name_attr.attr.name = "name"; |
319 | #endif | 352 | pdata->name_attr.attr.mode = S_IRUGO; |
320 | data->name = "coretemp"; | 353 | pdata->name_attr.show = show_name; |
321 | mutex_init(&data->update_lock); | 354 | return device_create_file(dev, &pdata->name_attr); |
355 | } | ||
322 | 356 | ||
323 | /* test if we can access the THERM_STATUS MSR */ | 357 | static int create_core_attrs(struct temp_data *tdata, struct device *dev, |
324 | err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); | 358 | int attr_no) |
325 | if (err) { | 359 | { |
326 | dev_err(&pdev->dev, | 360 | int err, i; |
327 | "Unable to access THERM_STATUS MSR, giving up\n"); | 361 | static ssize_t (*rd_ptr[MAX_ATTRS]) (struct device *dev, |
328 | goto exit_free; | 362 | struct device_attribute *devattr, char *buf) = { |
363 | show_label, show_crit_alarm, show_ttarget, | ||
364 | show_temp, show_tjmax }; | ||
365 | static const char *names[MAX_ATTRS] = { | ||
366 | "temp%d_label", "temp%d_crit_alarm", | ||
367 | "temp%d_max", "temp%d_input", | ||
368 | "temp%d_crit" }; | ||
369 | |||
370 | for (i = 0; i < MAX_ATTRS; i++) { | ||
371 | snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, names[i], | ||
372 | attr_no); | ||
373 | tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; | ||
374 | tdata->sd_attrs[i].dev_attr.attr.mode = S_IRUGO; | ||
375 | tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; | ||
376 | tdata->sd_attrs[i].dev_attr.store = NULL; | ||
377 | tdata->sd_attrs[i].index = attr_no; | ||
378 | err = device_create_file(dev, &tdata->sd_attrs[i].dev_attr); | ||
379 | if (err) | ||
380 | goto exit_free; | ||
381 | } | ||
382 | return 0; | ||
383 | |||
384 | exit_free: | ||
385 | while (--i >= 0) | ||
386 | device_remove_file(dev, &tdata->sd_attrs[i].dev_attr); | ||
387 | return err; | ||
388 | } | ||
389 | |||
390 | static void update_ttarget(__u8 cpu_model, struct temp_data *tdata, | ||
391 | struct device *dev) | ||
392 | { | ||
393 | int err; | ||
394 | u32 eax, edx; | ||
395 | |||
396 | /* | ||
397 | * Initialize ttarget value. Eventually this will be | ||
398 | * initialized with the value from MSR_IA32_THERM_INTERRUPT | ||
399 | * register. If IA32_TEMPERATURE_TARGET is supported, this | ||
400 | * value will be over written below. | ||
401 | * To Do: Patch to initialize ttarget from MSR_IA32_THERM_INTERRUPT | ||
402 | */ | ||
403 | tdata->ttarget = tdata->tjmax - 20000; | ||
404 | |||
405 | /* | ||
406 | * Read the still undocumented IA32_TEMPERATURE_TARGET. It exists | ||
407 | * on older CPUs but not in this register, | ||
408 | * Atoms don't have it either. | ||
409 | */ | ||
410 | if (cpu_model > 0xe && cpu_model != 0x1c) { | ||
411 | err = rdmsr_safe_on_cpu(tdata->cpu, | ||
412 | MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); | ||
413 | if (err) { | ||
414 | dev_warn(dev, | ||
415 | "Unable to read IA32_TEMPERATURE_TARGET MSR\n"); | ||
416 | } else { | ||
417 | tdata->ttarget = tdata->tjmax - | ||
418 | ((eax >> 8) & 0xff) * 1000; | ||
419 | } | ||
329 | } | 420 | } |
421 | } | ||
330 | 422 | ||
331 | /* Check if we have problem with errata AE18 of Core processors: | 423 | static int chk_ucode_version(struct platform_device *pdev) |
332 | Readings might stop update when processor visited too deep sleep, | 424 | { |
333 | fixed for stepping D0 (6EC). | 425 | struct cpuinfo_x86 *c = &cpu_data(pdev->id); |
334 | */ | 426 | int err; |
427 | u32 edx; | ||
335 | 428 | ||
336 | if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) { | 429 | /* |
430 | * Check if we have problem with errata AE18 of Core processors: | ||
431 | * Readings might stop update when processor visited too deep sleep, | ||
432 | * fixed for stepping D0 (6EC). | ||
433 | */ | ||
434 | if (c->x86_model == 0xe && c->x86_mask < 0xc) { | ||
337 | /* check for microcode update */ | 435 | /* check for microcode update */ |
338 | err = smp_call_function_single(data->id, get_ucode_rev_on_cpu, | 436 | err = smp_call_function_single(pdev->id, get_ucode_rev_on_cpu, |
339 | &edx, 1); | 437 | &edx, 1); |
340 | if (err) { | 438 | if (err) { |
341 | dev_err(&pdev->dev, | 439 | dev_err(&pdev->dev, |
342 | "Cannot determine microcode revision of " | 440 | "Cannot determine microcode revision of " |
343 | "CPU#%u (%d)!\n", data->id, err); | 441 | "CPU#%u (%d)!\n", pdev->id, err); |
344 | err = -ENODEV; | 442 | return -ENODEV; |
345 | goto exit_free; | ||
346 | } else if (edx < 0x39) { | 443 | } else if (edx < 0x39) { |
347 | err = -ENODEV; | ||
348 | dev_err(&pdev->dev, | 444 | dev_err(&pdev->dev, |
349 | "Errata AE18 not fixed, update BIOS or " | 445 | "Errata AE18 not fixed, update BIOS or " |
350 | "microcode of the CPU!\n"); | 446 | "microcode of the CPU!\n"); |
351 | goto exit_free; | 447 | return -ENODEV; |
352 | } | 448 | } |
353 | } | 449 | } |
450 | return 0; | ||
451 | } | ||
354 | 452 | ||
355 | data->tjmax = get_tjmax(c, data->id, &pdev->dev); | 453 | static struct platform_device *coretemp_get_pdev(unsigned int cpu) |
356 | platform_set_drvdata(pdev, data); | 454 | { |
455 | u16 phys_proc_id = TO_PHYS_ID(cpu); | ||
456 | struct pdev_entry *p; | ||
457 | |||
458 | mutex_lock(&pdev_list_mutex); | ||
459 | |||
460 | list_for_each_entry(p, &pdev_list, list) | ||
461 | if (p->phys_proc_id == phys_proc_id) { | ||
462 | mutex_unlock(&pdev_list_mutex); | ||
463 | return p->pdev; | ||
464 | } | ||
465 | |||
466 | mutex_unlock(&pdev_list_mutex); | ||
467 | return NULL; | ||
468 | } | ||
469 | |||
470 | static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) | ||
471 | { | ||
472 | struct temp_data *tdata; | ||
473 | |||
474 | tdata = kzalloc(sizeof(struct temp_data), GFP_KERNEL); | ||
475 | if (!tdata) | ||
476 | return NULL; | ||
477 | |||
478 | tdata->status_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_STATUS : | ||
479 | MSR_IA32_THERM_STATUS; | ||
480 | tdata->is_pkg_data = pkg_flag; | ||
481 | tdata->cpu = cpu; | ||
482 | tdata->cpu_core_id = TO_CORE_ID(cpu); | ||
483 | mutex_init(&tdata->update_lock); | ||
484 | return tdata; | ||
485 | } | ||
486 | |||
487 | static int create_core_data(struct platform_data *pdata, | ||
488 | struct platform_device *pdev, | ||
489 | unsigned int cpu, int pkg_flag) | ||
490 | { | ||
491 | struct temp_data *tdata; | ||
492 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
493 | u32 eax, edx; | ||
494 | int err, attr_no; | ||
357 | 495 | ||
358 | /* | 496 | /* |
359 | * read the still undocumented IA32_TEMPERATURE_TARGET. It exists | 497 | * Find attr number for sysfs: |
360 | * on older CPUs but not in this register, | 498 | * We map the attr number to core id of the CPU |
361 | * Atoms don't have it either. | 499 | * The attr number is always core id + 2 |
500 | * The Pkgtemp will always show up as temp1_*, if available | ||
362 | */ | 501 | */ |
502 | attr_no = pkg_flag ? 1 : TO_ATTR_NO(cpu); | ||
363 | 503 | ||
364 | if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { | 504 | if (attr_no > MAX_CORE_DATA - 1) |
365 | err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, | 505 | return -ERANGE; |
366 | &eax, &edx); | 506 | |
367 | if (err) { | 507 | /* Skip if it is a HT core, Not an error */ |
368 | dev_warn(&pdev->dev, "Unable to read" | 508 | if (pdata->core_data[attr_no] != NULL) |
369 | " IA32_TEMPERATURE_TARGET MSR\n"); | 509 | return 0; |
370 | } else { | ||
371 | data->ttarget = data->tjmax - | ||
372 | (((eax >> 8) & 0xff) * 1000); | ||
373 | err = device_create_file(&pdev->dev, | ||
374 | &sensor_dev_attr_temp1_max.dev_attr); | ||
375 | if (err) | ||
376 | goto exit_free; | ||
377 | } | ||
378 | } | ||
379 | 510 | ||
380 | if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) | 511 | tdata = init_temp_data(cpu, pkg_flag); |
381 | goto exit_dev; | 512 | if (!tdata) |
513 | return -ENOMEM; | ||
382 | 514 | ||
383 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 515 | /* Test if we can access the status register */ |
384 | if (IS_ERR(data->hwmon_dev)) { | 516 | err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx); |
385 | err = PTR_ERR(data->hwmon_dev); | 517 | if (err) |
386 | dev_err(&pdev->dev, "Class registration failed (%d)\n", | 518 | goto exit_free; |
387 | err); | 519 | |
388 | goto exit_class; | 520 | /* We can access status register. Get Critical Temperature */ |
389 | } | 521 | if (pkg_flag) |
522 | tdata->tjmax = get_pkg_tjmax(pdev->id, &pdev->dev); | ||
523 | else | ||
524 | tdata->tjmax = get_tjmax(c, cpu, &pdev->dev); | ||
525 | |||
526 | update_ttarget(c->x86_model, tdata, &pdev->dev); | ||
527 | pdata->core_data[attr_no] = tdata; | ||
528 | |||
529 | /* Create sysfs interfaces */ | ||
530 | err = create_core_attrs(tdata, &pdev->dev, attr_no); | ||
531 | if (err) | ||
532 | goto exit_free; | ||
390 | 533 | ||
391 | return 0; | 534 | return 0; |
535 | exit_free: | ||
536 | kfree(tdata); | ||
537 | return err; | ||
538 | } | ||
539 | |||
540 | static void coretemp_add_core(unsigned int cpu, int pkg_flag) | ||
541 | { | ||
542 | struct platform_data *pdata; | ||
543 | struct platform_device *pdev = coretemp_get_pdev(cpu); | ||
544 | int err; | ||
545 | |||
546 | if (!pdev) | ||
547 | return; | ||
548 | |||
549 | pdata = platform_get_drvdata(pdev); | ||
550 | |||
551 | err = create_core_data(pdata, pdev, cpu, pkg_flag); | ||
552 | if (err) | ||
553 | dev_err(&pdev->dev, "Adding Core %u failed\n", cpu); | ||
554 | } | ||
555 | |||
556 | static void coretemp_remove_core(struct platform_data *pdata, | ||
557 | struct device *dev, int indx) | ||
558 | { | ||
559 | int i; | ||
560 | struct temp_data *tdata = pdata->core_data[indx]; | ||
392 | 561 | ||
393 | exit_class: | 562 | /* Remove the sysfs attributes */ |
394 | sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); | 563 | for (i = 0; i < MAX_ATTRS; i++) |
395 | exit_dev: | 564 | device_remove_file(dev, &tdata->sd_attrs[i].dev_attr); |
396 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | 565 | |
566 | kfree(pdata->core_data[indx]); | ||
567 | pdata->core_data[indx] = NULL; | ||
568 | } | ||
569 | |||
570 | static int __devinit coretemp_probe(struct platform_device *pdev) | ||
571 | { | ||
572 | struct platform_data *pdata; | ||
573 | int err; | ||
574 | |||
575 | /* Check the microcode version of the CPU */ | ||
576 | err = chk_ucode_version(pdev); | ||
577 | if (err) | ||
578 | return err; | ||
579 | |||
580 | /* Initialize the per-package data structures */ | ||
581 | pdata = kzalloc(sizeof(struct platform_data), GFP_KERNEL); | ||
582 | if (!pdata) | ||
583 | return -ENOMEM; | ||
584 | |||
585 | err = create_name_attr(pdata, &pdev->dev); | ||
586 | if (err) | ||
587 | goto exit_free; | ||
588 | |||
589 | pdata->phys_proc_id = TO_PHYS_ID(pdev->id); | ||
590 | platform_set_drvdata(pdev, pdata); | ||
591 | |||
592 | pdata->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
593 | if (IS_ERR(pdata->hwmon_dev)) { | ||
594 | err = PTR_ERR(pdata->hwmon_dev); | ||
595 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | ||
596 | goto exit_name; | ||
597 | } | ||
598 | return 0; | ||
599 | |||
600 | exit_name: | ||
601 | device_remove_file(&pdev->dev, &pdata->name_attr); | ||
602 | platform_set_drvdata(pdev, NULL); | ||
397 | exit_free: | 603 | exit_free: |
398 | kfree(data); | 604 | kfree(pdata); |
399 | exit: | ||
400 | return err; | 605 | return err; |
401 | } | 606 | } |
402 | 607 | ||
403 | static int __devexit coretemp_remove(struct platform_device *pdev) | 608 | static int __devexit coretemp_remove(struct platform_device *pdev) |
404 | { | 609 | { |
405 | struct coretemp_data *data = platform_get_drvdata(pdev); | 610 | struct platform_data *pdata = platform_get_drvdata(pdev); |
611 | int i; | ||
612 | |||
613 | for (i = MAX_CORE_DATA - 1; i >= 0; --i) | ||
614 | if (pdata->core_data[i]) | ||
615 | coretemp_remove_core(pdata, &pdev->dev, i); | ||
406 | 616 | ||
407 | hwmon_device_unregister(data->hwmon_dev); | 617 | device_remove_file(&pdev->dev, &pdata->name_attr); |
408 | sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); | 618 | hwmon_device_unregister(pdata->hwmon_dev); |
409 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
410 | platform_set_drvdata(pdev, NULL); | 619 | platform_set_drvdata(pdev, NULL); |
411 | kfree(data); | 620 | kfree(pdata); |
412 | return 0; | 621 | return 0; |
413 | } | 622 | } |
414 | 623 | ||
@@ -421,50 +630,14 @@ static struct platform_driver coretemp_driver = { | |||
421 | .remove = __devexit_p(coretemp_remove), | 630 | .remove = __devexit_p(coretemp_remove), |
422 | }; | 631 | }; |
423 | 632 | ||
424 | struct pdev_entry { | ||
425 | struct list_head list; | ||
426 | struct platform_device *pdev; | ||
427 | unsigned int cpu; | ||
428 | #ifdef CONFIG_SMP | ||
429 | u16 phys_proc_id; | ||
430 | u16 cpu_core_id; | ||
431 | #endif | ||
432 | }; | ||
433 | |||
434 | static LIST_HEAD(pdev_list); | ||
435 | static DEFINE_MUTEX(pdev_list_mutex); | ||
436 | |||
437 | static int __cpuinit coretemp_device_add(unsigned int cpu) | 633 | static int __cpuinit coretemp_device_add(unsigned int cpu) |
438 | { | 634 | { |
439 | int err; | 635 | int err; |
440 | struct platform_device *pdev; | 636 | struct platform_device *pdev; |
441 | struct pdev_entry *pdev_entry; | 637 | struct pdev_entry *pdev_entry; |
442 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
443 | |||
444 | /* | ||
445 | * CPUID.06H.EAX[0] indicates whether the CPU has thermal | ||
446 | * sensors. We check this bit only, all the early CPUs | ||
447 | * without thermal sensors will be filtered out. | ||
448 | */ | ||
449 | if (!cpu_has(c, X86_FEATURE_DTS)) { | ||
450 | pr_info("CPU (model=0x%x) has no thermal sensor\n", | ||
451 | c->x86_model); | ||
452 | return 0; | ||
453 | } | ||
454 | 638 | ||
455 | mutex_lock(&pdev_list_mutex); | 639 | mutex_lock(&pdev_list_mutex); |
456 | 640 | ||
457 | #ifdef CONFIG_SMP | ||
458 | /* Skip second HT entry of each core */ | ||
459 | list_for_each_entry(pdev_entry, &pdev_list, list) { | ||
460 | if (c->phys_proc_id == pdev_entry->phys_proc_id && | ||
461 | c->cpu_core_id == pdev_entry->cpu_core_id) { | ||
462 | err = 0; /* Not an error */ | ||
463 | goto exit; | ||
464 | } | ||
465 | } | ||
466 | #endif | ||
467 | |||
468 | pdev = platform_device_alloc(DRVNAME, cpu); | 641 | pdev = platform_device_alloc(DRVNAME, cpu); |
469 | if (!pdev) { | 642 | if (!pdev) { |
470 | err = -ENOMEM; | 643 | err = -ENOMEM; |
@@ -486,10 +659,9 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) | |||
486 | 659 | ||
487 | pdev_entry->pdev = pdev; | 660 | pdev_entry->pdev = pdev; |
488 | pdev_entry->cpu = cpu; | 661 | pdev_entry->cpu = cpu; |
489 | #ifdef CONFIG_SMP | 662 | pdev_entry->phys_proc_id = TO_PHYS_ID(cpu); |
490 | pdev_entry->phys_proc_id = c->phys_proc_id; | 663 | pdev_entry->cpu_core_id = TO_CORE_ID(cpu); |
491 | pdev_entry->cpu_core_id = c->cpu_core_id; | 664 | |
492 | #endif | ||
493 | list_add_tail(&pdev_entry->list, &pdev_list); | 665 | list_add_tail(&pdev_entry->list, &pdev_list); |
494 | mutex_unlock(&pdev_list_mutex); | 666 | mutex_unlock(&pdev_list_mutex); |
495 | 667 | ||
@@ -504,28 +676,108 @@ exit: | |||
504 | return err; | 676 | return err; |
505 | } | 677 | } |
506 | 678 | ||
507 | static void __cpuinit coretemp_device_remove(unsigned int cpu) | 679 | static void coretemp_device_remove(unsigned int cpu) |
508 | { | 680 | { |
509 | struct pdev_entry *p; | 681 | struct pdev_entry *p, *n; |
510 | unsigned int i; | 682 | u16 phys_proc_id = TO_PHYS_ID(cpu); |
511 | 683 | ||
512 | mutex_lock(&pdev_list_mutex); | 684 | mutex_lock(&pdev_list_mutex); |
513 | list_for_each_entry(p, &pdev_list, list) { | 685 | list_for_each_entry_safe(p, n, &pdev_list, list) { |
514 | if (p->cpu != cpu) | 686 | if (p->phys_proc_id != phys_proc_id) |
515 | continue; | 687 | continue; |
516 | |||
517 | platform_device_unregister(p->pdev); | 688 | platform_device_unregister(p->pdev); |
518 | list_del(&p->list); | 689 | list_del(&p->list); |
519 | mutex_unlock(&pdev_list_mutex); | ||
520 | kfree(p); | 690 | kfree(p); |
521 | for_each_cpu(i, cpu_sibling_mask(cpu)) | ||
522 | if (i != cpu && !coretemp_device_add(i)) | ||
523 | break; | ||
524 | return; | ||
525 | } | 691 | } |
526 | mutex_unlock(&pdev_list_mutex); | 692 | mutex_unlock(&pdev_list_mutex); |
527 | } | 693 | } |
528 | 694 | ||
695 | static bool is_any_core_online(struct platform_data *pdata) | ||
696 | { | ||
697 | int i; | ||
698 | |||
699 | /* Find online cores, except pkgtemp data */ | ||
700 | for (i = MAX_CORE_DATA - 1; i >= 0; --i) { | ||
701 | if (pdata->core_data[i] && | ||
702 | !pdata->core_data[i]->is_pkg_data) { | ||
703 | return true; | ||
704 | } | ||
705 | } | ||
706 | return false; | ||
707 | } | ||
708 | |||
709 | static void __cpuinit get_core_online(unsigned int cpu) | ||
710 | { | ||
711 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
712 | struct platform_device *pdev = coretemp_get_pdev(cpu); | ||
713 | int err; | ||
714 | |||
715 | /* | ||
716 | * CPUID.06H.EAX[0] indicates whether the CPU has thermal | ||
717 | * sensors. We check this bit only, all the early CPUs | ||
718 | * without thermal sensors will be filtered out. | ||
719 | */ | ||
720 | if (!cpu_has(c, X86_FEATURE_DTS)) | ||
721 | return; | ||
722 | |||
723 | if (!pdev) { | ||
724 | /* | ||
725 | * Alright, we have DTS support. | ||
726 | * We are bringing the _first_ core in this pkg | ||
727 | * online. So, initialize per-pkg data structures and | ||
728 | * then bring this core online. | ||
729 | */ | ||
730 | err = coretemp_device_add(cpu); | ||
731 | if (err) | ||
732 | return; | ||
733 | /* | ||
734 | * Check whether pkgtemp support is available. | ||
735 | * If so, add interfaces for pkgtemp. | ||
736 | */ | ||
737 | if (cpu_has(c, X86_FEATURE_PTS)) | ||
738 | coretemp_add_core(cpu, 1); | ||
739 | } | ||
740 | /* | ||
741 | * Physical CPU device already exists. | ||
742 | * So, just add interfaces for this core. | ||
743 | */ | ||
744 | coretemp_add_core(cpu, 0); | ||
745 | } | ||
746 | |||
747 | static void __cpuinit put_core_offline(unsigned int cpu) | ||
748 | { | ||
749 | int i, indx; | ||
750 | struct platform_data *pdata; | ||
751 | struct platform_device *pdev = coretemp_get_pdev(cpu); | ||
752 | |||
753 | /* If the physical CPU device does not exist, just return */ | ||
754 | if (!pdev) | ||
755 | return; | ||
756 | |||
757 | pdata = platform_get_drvdata(pdev); | ||
758 | |||
759 | indx = TO_ATTR_NO(cpu); | ||
760 | |||
761 | if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu) | ||
762 | coretemp_remove_core(pdata, &pdev->dev, indx); | ||
763 | |||
764 | /* Online the HT version of this core, if any */ | ||
765 | for_each_cpu(i, cpu_sibling_mask(cpu)) { | ||
766 | if (i != cpu) { | ||
767 | get_core_online(i); | ||
768 | break; | ||
769 | } | ||
770 | } | ||
771 | /* | ||
772 | * If all cores in this pkg are offline, remove the device. | ||
773 | * coretemp_device_remove calls unregister_platform_device, | ||
774 | * which in turn calls coretemp_remove. This removes the | ||
775 | * pkgtemp entry and does other clean ups. | ||
776 | */ | ||
777 | if (!is_any_core_online(pdata)) | ||
778 | coretemp_device_remove(cpu); | ||
779 | } | ||
780 | |||
529 | static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb, | 781 | static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb, |
530 | unsigned long action, void *hcpu) | 782 | unsigned long action, void *hcpu) |
531 | { | 783 | { |
@@ -534,10 +786,10 @@ static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb, | |||
534 | switch (action) { | 786 | switch (action) { |
535 | case CPU_ONLINE: | 787 | case CPU_ONLINE: |
536 | case CPU_DOWN_FAILED: | 788 | case CPU_DOWN_FAILED: |
537 | coretemp_device_add(cpu); | 789 | get_core_online(cpu); |
538 | break; | 790 | break; |
539 | case CPU_DOWN_PREPARE: | 791 | case CPU_DOWN_PREPARE: |
540 | coretemp_device_remove(cpu); | 792 | put_core_offline(cpu); |
541 | break; | 793 | break; |
542 | } | 794 | } |
543 | return NOTIFY_OK; | 795 | return NOTIFY_OK; |
@@ -560,7 +812,7 @@ static int __init coretemp_init(void) | |||
560 | goto exit; | 812 | goto exit; |
561 | 813 | ||
562 | for_each_online_cpu(i) | 814 | for_each_online_cpu(i) |
563 | coretemp_device_add(i); | 815 | get_core_online(i); |
564 | 816 | ||
565 | #ifndef CONFIG_HOTPLUG_CPU | 817 | #ifndef CONFIG_HOTPLUG_CPU |
566 | if (list_empty(&pdev_list)) { | 818 | if (list_empty(&pdev_list)) { |
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c new file mode 100644 index 000000000000..d94a24fdf4ba --- /dev/null +++ b/drivers/hwmon/max16065.c | |||
@@ -0,0 +1,717 @@ | |||
1 | /* | ||
2 | * Driver for | ||
3 | * Maxim MAX16065/MAX16066 12-Channel/8-Channel, Flash-Configurable | ||
4 | * System Managers with Nonvolatile Fault Registers | ||
5 | * Maxim MAX16067/MAX16068 6-Channel, Flash-Configurable System Managers | ||
6 | * with Nonvolatile Fault Registers | ||
7 | * Maxim MAX16070/MAX16071 12-Channel/8-Channel, Flash-Configurable System | ||
8 | * Monitors with Nonvolatile Fault Registers | ||
9 | * | ||
10 | * Copyright (C) 2011 Ericsson AB. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; version 2 of the License. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/hwmon.h> | ||
24 | #include <linux/hwmon-sysfs.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | |||
28 | enum chips { max16065, max16066, max16067, max16068, max16070, max16071 }; | ||
29 | |||
30 | /* | ||
31 | * Registers | ||
32 | */ | ||
33 | #define MAX16065_ADC(x) ((x) * 2) | ||
34 | |||
35 | #define MAX16065_CURR_SENSE 0x18 | ||
36 | #define MAX16065_CSP_ADC 0x19 | ||
37 | #define MAX16065_FAULT(x) (0x1b + (x)) | ||
38 | #define MAX16065_SCALE(x) (0x43 + (x)) | ||
39 | #define MAX16065_CURR_CONTROL 0x47 | ||
40 | #define MAX16065_LIMIT(l, x) (0x48 + (l) + (x) * 3) /* | ||
41 | * l: limit | ||
42 | * 0: min/max | ||
43 | * 1: crit | ||
44 | * 2: lcrit | ||
45 | * x: ADC index | ||
46 | */ | ||
47 | |||
48 | #define MAX16065_SW_ENABLE 0x73 | ||
49 | |||
50 | #define MAX16065_WARNING_OV (1 << 3) /* Set if secondary threshold is OV | ||
51 | warning */ | ||
52 | |||
53 | #define MAX16065_CURR_ENABLE (1 << 0) | ||
54 | |||
55 | #define MAX16065_NUM_LIMIT 3 | ||
56 | #define MAX16065_NUM_ADC 12 /* maximum number of ADC channels */ | ||
57 | |||
58 | static const int max16065_num_adc[] = { | ||
59 | [max16065] = 12, | ||
60 | [max16066] = 8, | ||
61 | [max16067] = 6, | ||
62 | [max16068] = 6, | ||
63 | [max16070] = 12, | ||
64 | [max16071] = 8, | ||
65 | }; | ||
66 | |||
67 | static const bool max16065_have_secondary[] = { | ||
68 | [max16065] = true, | ||
69 | [max16066] = true, | ||
70 | [max16067] = false, | ||
71 | [max16068] = false, | ||
72 | [max16070] = true, | ||
73 | [max16071] = true, | ||
74 | }; | ||
75 | |||
76 | static const bool max16065_have_current[] = { | ||
77 | [max16065] = true, | ||
78 | [max16066] = true, | ||
79 | [max16067] = false, | ||
80 | [max16068] = false, | ||
81 | [max16070] = true, | ||
82 | [max16071] = true, | ||
83 | }; | ||
84 | |||
85 | struct max16065_data { | ||
86 | enum chips type; | ||
87 | struct device *hwmon_dev; | ||
88 | struct mutex update_lock; | ||
89 | bool valid; | ||
90 | unsigned long last_updated; /* in jiffies */ | ||
91 | int num_adc; | ||
92 | bool have_current; | ||
93 | int curr_gain; | ||
94 | /* limits are in mV */ | ||
95 | int limit[MAX16065_NUM_LIMIT][MAX16065_NUM_ADC]; | ||
96 | int range[MAX16065_NUM_ADC + 1];/* voltage range */ | ||
97 | int adc[MAX16065_NUM_ADC + 1]; /* adc values (raw) including csp_adc */ | ||
98 | int curr_sense; | ||
99 | int fault[2]; | ||
100 | }; | ||
101 | |||
102 | static const int max16065_adc_range[] = { 5560, 2780, 1390, 0 }; | ||
103 | static const int max16065_csp_adc_range[] = { 7000, 14000 }; | ||
104 | |||
105 | /* ADC registers have 10 bit resolution. */ | ||
106 | static inline int ADC_TO_MV(int adc, int range) | ||
107 | { | ||
108 | return (adc * range) / 1024; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * Limit registers have 8 bit resolution and match upper 8 bits of ADC | ||
113 | * registers. | ||
114 | */ | ||
115 | static inline int LIMIT_TO_MV(int limit, int range) | ||
116 | { | ||
117 | return limit * range / 256; | ||
118 | } | ||
119 | |||
120 | static inline int MV_TO_LIMIT(int mv, int range) | ||
121 | { | ||
122 | return SENSORS_LIMIT(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255); | ||
123 | } | ||
124 | |||
125 | static inline int ADC_TO_CURR(int adc, int gain) | ||
126 | { | ||
127 | return adc * 1400000 / gain * 255; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * max16065_read_adc() | ||
132 | * | ||
133 | * Read 16 bit value from <reg>, <reg+1>. | ||
134 | * Upper 8 bits are in <reg>, lower 2 bits are in bits 7:6 of <reg+1>. | ||
135 | */ | ||
136 | static int max16065_read_adc(struct i2c_client *client, int reg) | ||
137 | { | ||
138 | int rv; | ||
139 | |||
140 | rv = i2c_smbus_read_word_data(client, reg); | ||
141 | if (unlikely(rv < 0)) | ||
142 | return rv; | ||
143 | return ((rv & 0xff) << 2) | ((rv >> 14) & 0x03); | ||
144 | } | ||
145 | |||
146 | static struct max16065_data *max16065_update_device(struct device *dev) | ||
147 | { | ||
148 | struct i2c_client *client = to_i2c_client(dev); | ||
149 | struct max16065_data *data = i2c_get_clientdata(client); | ||
150 | |||
151 | mutex_lock(&data->update_lock); | ||
152 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
153 | int i; | ||
154 | |||
155 | for (i = 0; i < data->num_adc; i++) | ||
156 | data->adc[i] | ||
157 | = max16065_read_adc(client, MAX16065_ADC(i)); | ||
158 | |||
159 | if (data->have_current) { | ||
160 | data->adc[MAX16065_NUM_ADC] | ||
161 | = max16065_read_adc(client, MAX16065_CSP_ADC); | ||
162 | data->curr_sense | ||
163 | = i2c_smbus_read_byte_data(client, | ||
164 | MAX16065_CURR_SENSE); | ||
165 | } | ||
166 | |||
167 | for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++) | ||
168 | data->fault[i] | ||
169 | = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i)); | ||
170 | |||
171 | data->last_updated = jiffies; | ||
172 | data->valid = 1; | ||
173 | } | ||
174 | mutex_unlock(&data->update_lock); | ||
175 | return data; | ||
176 | } | ||
177 | |||
178 | static ssize_t max16065_show_alarm(struct device *dev, | ||
179 | struct device_attribute *da, char *buf) | ||
180 | { | ||
181 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | ||
182 | struct max16065_data *data = max16065_update_device(dev); | ||
183 | int val = data->fault[attr2->nr]; | ||
184 | |||
185 | if (val < 0) | ||
186 | return val; | ||
187 | |||
188 | val &= (1 << attr2->index); | ||
189 | if (val) | ||
190 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
191 | MAX16065_FAULT(attr2->nr), val); | ||
192 | |||
193 | return snprintf(buf, PAGE_SIZE, "%d\n", !!val); | ||
194 | } | ||
195 | |||
196 | static ssize_t max16065_show_input(struct device *dev, | ||
197 | struct device_attribute *da, char *buf) | ||
198 | { | ||
199 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
200 | struct max16065_data *data = max16065_update_device(dev); | ||
201 | int adc = data->adc[attr->index]; | ||
202 | |||
203 | if (unlikely(adc < 0)) | ||
204 | return adc; | ||
205 | |||
206 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
207 | ADC_TO_MV(adc, data->range[attr->index])); | ||
208 | } | ||
209 | |||
210 | static ssize_t max16065_show_current(struct device *dev, | ||
211 | struct device_attribute *da, char *buf) | ||
212 | { | ||
213 | struct max16065_data *data = max16065_update_device(dev); | ||
214 | |||
215 | if (unlikely(data->curr_sense < 0)) | ||
216 | return data->curr_sense; | ||
217 | |||
218 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
219 | ADC_TO_CURR(data->curr_sense, data->curr_gain)); | ||
220 | } | ||
221 | |||
222 | static ssize_t max16065_set_limit(struct device *dev, | ||
223 | struct device_attribute *da, | ||
224 | const char *buf, size_t count) | ||
225 | { | ||
226 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | ||
227 | struct i2c_client *client = to_i2c_client(dev); | ||
228 | struct max16065_data *data = i2c_get_clientdata(client); | ||
229 | unsigned long val; | ||
230 | int err; | ||
231 | int limit; | ||
232 | |||
233 | err = strict_strtoul(buf, 10, &val); | ||
234 | if (unlikely(err < 0)) | ||
235 | return err; | ||
236 | |||
237 | limit = MV_TO_LIMIT(val, data->range[attr2->index]); | ||
238 | |||
239 | mutex_lock(&data->update_lock); | ||
240 | data->limit[attr2->nr][attr2->index] | ||
241 | = LIMIT_TO_MV(limit, data->range[attr2->index]); | ||
242 | i2c_smbus_write_byte_data(client, | ||
243 | MAX16065_LIMIT(attr2->nr, attr2->index), | ||
244 | limit); | ||
245 | mutex_unlock(&data->update_lock); | ||
246 | |||
247 | return count; | ||
248 | } | ||
249 | |||
250 | static ssize_t max16065_show_limit(struct device *dev, | ||
251 | struct device_attribute *da, char *buf) | ||
252 | { | ||
253 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | ||
254 | struct i2c_client *client = to_i2c_client(dev); | ||
255 | struct max16065_data *data = i2c_get_clientdata(client); | ||
256 | |||
257 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
258 | data->limit[attr2->nr][attr2->index]); | ||
259 | } | ||
260 | |||
261 | /* Construct a sensor_device_attribute structure for each register */ | ||
262 | |||
263 | /* Input voltages */ | ||
264 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, max16065_show_input, NULL, 0); | ||
265 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, max16065_show_input, NULL, 1); | ||
266 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, max16065_show_input, NULL, 2); | ||
267 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, max16065_show_input, NULL, 3); | ||
268 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, max16065_show_input, NULL, 4); | ||
269 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, max16065_show_input, NULL, 5); | ||
270 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, max16065_show_input, NULL, 6); | ||
271 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, max16065_show_input, NULL, 7); | ||
272 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, max16065_show_input, NULL, 8); | ||
273 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, max16065_show_input, NULL, 9); | ||
274 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, max16065_show_input, NULL, 10); | ||
275 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, max16065_show_input, NULL, 11); | ||
276 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, max16065_show_input, NULL, 12); | ||
277 | |||
278 | /* Input voltages lcrit */ | ||
279 | static SENSOR_DEVICE_ATTR_2(in0_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
280 | max16065_set_limit, 2, 0); | ||
281 | static SENSOR_DEVICE_ATTR_2(in1_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
282 | max16065_set_limit, 2, 1); | ||
283 | static SENSOR_DEVICE_ATTR_2(in2_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
284 | max16065_set_limit, 2, 2); | ||
285 | static SENSOR_DEVICE_ATTR_2(in3_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
286 | max16065_set_limit, 2, 3); | ||
287 | static SENSOR_DEVICE_ATTR_2(in4_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
288 | max16065_set_limit, 2, 4); | ||
289 | static SENSOR_DEVICE_ATTR_2(in5_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
290 | max16065_set_limit, 2, 5); | ||
291 | static SENSOR_DEVICE_ATTR_2(in6_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
292 | max16065_set_limit, 2, 6); | ||
293 | static SENSOR_DEVICE_ATTR_2(in7_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
294 | max16065_set_limit, 2, 7); | ||
295 | static SENSOR_DEVICE_ATTR_2(in8_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
296 | max16065_set_limit, 2, 8); | ||
297 | static SENSOR_DEVICE_ATTR_2(in9_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
298 | max16065_set_limit, 2, 9); | ||
299 | static SENSOR_DEVICE_ATTR_2(in10_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
300 | max16065_set_limit, 2, 10); | ||
301 | static SENSOR_DEVICE_ATTR_2(in11_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
302 | max16065_set_limit, 2, 11); | ||
303 | |||
304 | /* Input voltages crit */ | ||
305 | static SENSOR_DEVICE_ATTR_2(in0_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
306 | max16065_set_limit, 1, 0); | ||
307 | static SENSOR_DEVICE_ATTR_2(in1_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
308 | max16065_set_limit, 1, 1); | ||
309 | static SENSOR_DEVICE_ATTR_2(in2_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
310 | max16065_set_limit, 1, 2); | ||
311 | static SENSOR_DEVICE_ATTR_2(in3_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
312 | max16065_set_limit, 1, 3); | ||
313 | static SENSOR_DEVICE_ATTR_2(in4_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
314 | max16065_set_limit, 1, 4); | ||
315 | static SENSOR_DEVICE_ATTR_2(in5_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
316 | max16065_set_limit, 1, 5); | ||
317 | static SENSOR_DEVICE_ATTR_2(in6_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
318 | max16065_set_limit, 1, 6); | ||
319 | static SENSOR_DEVICE_ATTR_2(in7_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
320 | max16065_set_limit, 1, 7); | ||
321 | static SENSOR_DEVICE_ATTR_2(in8_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
322 | max16065_set_limit, 1, 8); | ||
323 | static SENSOR_DEVICE_ATTR_2(in9_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
324 | max16065_set_limit, 1, 9); | ||
325 | static SENSOR_DEVICE_ATTR_2(in10_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
326 | max16065_set_limit, 1, 10); | ||
327 | static SENSOR_DEVICE_ATTR_2(in11_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
328 | max16065_set_limit, 1, 11); | ||
329 | |||
330 | /* Input voltages min */ | ||
331 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
332 | max16065_set_limit, 0, 0); | ||
333 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
334 | max16065_set_limit, 0, 1); | ||
335 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
336 | max16065_set_limit, 0, 2); | ||
337 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
338 | max16065_set_limit, 0, 3); | ||
339 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
340 | max16065_set_limit, 0, 4); | ||
341 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
342 | max16065_set_limit, 0, 5); | ||
343 | static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
344 | max16065_set_limit, 0, 6); | ||
345 | static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
346 | max16065_set_limit, 0, 7); | ||
347 | static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
348 | max16065_set_limit, 0, 8); | ||
349 | static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
350 | max16065_set_limit, 0, 9); | ||
351 | static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
352 | max16065_set_limit, 0, 10); | ||
353 | static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
354 | max16065_set_limit, 0, 11); | ||
355 | |||
356 | /* Input voltages max */ | ||
357 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
358 | max16065_set_limit, 0, 0); | ||
359 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
360 | max16065_set_limit, 0, 1); | ||
361 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
362 | max16065_set_limit, 0, 2); | ||
363 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
364 | max16065_set_limit, 0, 3); | ||
365 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
366 | max16065_set_limit, 0, 4); | ||
367 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
368 | max16065_set_limit, 0, 5); | ||
369 | static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
370 | max16065_set_limit, 0, 6); | ||
371 | static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
372 | max16065_set_limit, 0, 7); | ||
373 | static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
374 | max16065_set_limit, 0, 8); | ||
375 | static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
376 | max16065_set_limit, 0, 9); | ||
377 | static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
378 | max16065_set_limit, 0, 10); | ||
379 | static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, max16065_show_limit, | ||
380 | max16065_set_limit, 0, 11); | ||
381 | |||
382 | /* alarms */ | ||
383 | static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
384 | 0, 0); | ||
385 | static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
386 | 0, 1); | ||
387 | static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
388 | 0, 2); | ||
389 | static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
390 | 0, 3); | ||
391 | static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
392 | 0, 4); | ||
393 | static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
394 | 0, 5); | ||
395 | static SENSOR_DEVICE_ATTR_2(in6_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
396 | 0, 6); | ||
397 | static SENSOR_DEVICE_ATTR_2(in7_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
398 | 0, 7); | ||
399 | static SENSOR_DEVICE_ATTR_2(in8_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
400 | 1, 0); | ||
401 | static SENSOR_DEVICE_ATTR_2(in9_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
402 | 1, 1); | ||
403 | static SENSOR_DEVICE_ATTR_2(in10_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
404 | 1, 2); | ||
405 | static SENSOR_DEVICE_ATTR_2(in11_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
406 | 1, 3); | ||
407 | |||
408 | /* Current and alarm */ | ||
409 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, max16065_show_current, NULL, 0); | ||
410 | static SENSOR_DEVICE_ATTR_2(curr1_alarm, S_IRUGO, max16065_show_alarm, NULL, | ||
411 | 1, 4); | ||
412 | |||
413 | /* | ||
414 | * Finally, construct an array of pointers to members of the above objects, | ||
415 | * as required for sysfs_create_group() | ||
416 | */ | ||
417 | static struct attribute *max16065_basic_attributes[] = { | ||
418 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
419 | &sensor_dev_attr_in0_lcrit.dev_attr.attr, | ||
420 | &sensor_dev_attr_in0_crit.dev_attr.attr, | ||
421 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
422 | |||
423 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
424 | &sensor_dev_attr_in1_lcrit.dev_attr.attr, | ||
425 | &sensor_dev_attr_in1_crit.dev_attr.attr, | ||
426 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
427 | |||
428 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
429 | &sensor_dev_attr_in2_lcrit.dev_attr.attr, | ||
430 | &sensor_dev_attr_in2_crit.dev_attr.attr, | ||
431 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
432 | |||
433 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
434 | &sensor_dev_attr_in3_lcrit.dev_attr.attr, | ||
435 | &sensor_dev_attr_in3_crit.dev_attr.attr, | ||
436 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
437 | |||
438 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
439 | &sensor_dev_attr_in4_lcrit.dev_attr.attr, | ||
440 | &sensor_dev_attr_in4_crit.dev_attr.attr, | ||
441 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
442 | |||
443 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
444 | &sensor_dev_attr_in5_lcrit.dev_attr.attr, | ||
445 | &sensor_dev_attr_in5_crit.dev_attr.attr, | ||
446 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
447 | |||
448 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
449 | &sensor_dev_attr_in6_lcrit.dev_attr.attr, | ||
450 | &sensor_dev_attr_in6_crit.dev_attr.attr, | ||
451 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
452 | |||
453 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
454 | &sensor_dev_attr_in7_lcrit.dev_attr.attr, | ||
455 | &sensor_dev_attr_in7_crit.dev_attr.attr, | ||
456 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
457 | |||
458 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
459 | &sensor_dev_attr_in8_lcrit.dev_attr.attr, | ||
460 | &sensor_dev_attr_in8_crit.dev_attr.attr, | ||
461 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | ||
462 | |||
463 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
464 | &sensor_dev_attr_in9_lcrit.dev_attr.attr, | ||
465 | &sensor_dev_attr_in9_crit.dev_attr.attr, | ||
466 | &sensor_dev_attr_in9_alarm.dev_attr.attr, | ||
467 | |||
468 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
469 | &sensor_dev_attr_in10_lcrit.dev_attr.attr, | ||
470 | &sensor_dev_attr_in10_crit.dev_attr.attr, | ||
471 | &sensor_dev_attr_in10_alarm.dev_attr.attr, | ||
472 | |||
473 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
474 | &sensor_dev_attr_in11_lcrit.dev_attr.attr, | ||
475 | &sensor_dev_attr_in11_crit.dev_attr.attr, | ||
476 | &sensor_dev_attr_in11_alarm.dev_attr.attr, | ||
477 | |||
478 | NULL | ||
479 | }; | ||
480 | |||
481 | static struct attribute *max16065_current_attributes[] = { | ||
482 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
483 | &sensor_dev_attr_curr1_input.dev_attr.attr, | ||
484 | &sensor_dev_attr_curr1_alarm.dev_attr.attr, | ||
485 | NULL | ||
486 | }; | ||
487 | |||
488 | static struct attribute *max16065_min_attributes[] = { | ||
489 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
490 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
491 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
492 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
493 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
494 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
495 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
496 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
497 | &sensor_dev_attr_in8_min.dev_attr.attr, | ||
498 | &sensor_dev_attr_in9_min.dev_attr.attr, | ||
499 | &sensor_dev_attr_in10_min.dev_attr.attr, | ||
500 | &sensor_dev_attr_in11_min.dev_attr.attr, | ||
501 | NULL | ||
502 | }; | ||
503 | |||
504 | static struct attribute *max16065_max_attributes[] = { | ||
505 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
506 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
507 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
508 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
509 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
510 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
511 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
512 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
513 | &sensor_dev_attr_in8_max.dev_attr.attr, | ||
514 | &sensor_dev_attr_in9_max.dev_attr.attr, | ||
515 | &sensor_dev_attr_in10_max.dev_attr.attr, | ||
516 | &sensor_dev_attr_in11_max.dev_attr.attr, | ||
517 | NULL | ||
518 | }; | ||
519 | |||
520 | static const struct attribute_group max16065_basic_group = { | ||
521 | .attrs = max16065_basic_attributes, | ||
522 | }; | ||
523 | |||
524 | static const struct attribute_group max16065_current_group = { | ||
525 | .attrs = max16065_current_attributes, | ||
526 | }; | ||
527 | |||
528 | static const struct attribute_group max16065_min_group = { | ||
529 | .attrs = max16065_min_attributes, | ||
530 | }; | ||
531 | |||
532 | static const struct attribute_group max16065_max_group = { | ||
533 | .attrs = max16065_max_attributes, | ||
534 | }; | ||
535 | |||
536 | static void max16065_cleanup(struct i2c_client *client) | ||
537 | { | ||
538 | sysfs_remove_group(&client->dev.kobj, &max16065_max_group); | ||
539 | sysfs_remove_group(&client->dev.kobj, &max16065_min_group); | ||
540 | sysfs_remove_group(&client->dev.kobj, &max16065_current_group); | ||
541 | sysfs_remove_group(&client->dev.kobj, &max16065_basic_group); | ||
542 | } | ||
543 | |||
544 | static int max16065_probe(struct i2c_client *client, | ||
545 | const struct i2c_device_id *id) | ||
546 | { | ||
547 | struct i2c_adapter *adapter = client->adapter; | ||
548 | struct max16065_data *data; | ||
549 | int i, j, val, ret; | ||
550 | bool have_secondary; /* true if chip has secondary limits */ | ||
551 | bool secondary_is_max = false; /* secondary limits reflect max */ | ||
552 | |||
553 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ||
554 | | I2C_FUNC_SMBUS_READ_WORD_DATA)) | ||
555 | return -ENODEV; | ||
556 | |||
557 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
558 | if (unlikely(!data)) | ||
559 | return -ENOMEM; | ||
560 | |||
561 | i2c_set_clientdata(client, data); | ||
562 | mutex_init(&data->update_lock); | ||
563 | |||
564 | data->num_adc = max16065_num_adc[id->driver_data]; | ||
565 | data->have_current = max16065_have_current[id->driver_data]; | ||
566 | have_secondary = max16065_have_secondary[id->driver_data]; | ||
567 | |||
568 | if (have_secondary) { | ||
569 | val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE); | ||
570 | if (unlikely(val < 0)) { | ||
571 | ret = val; | ||
572 | goto out_free; | ||
573 | } | ||
574 | secondary_is_max = val & MAX16065_WARNING_OV; | ||
575 | } | ||
576 | |||
577 | /* Read scale registers, convert to range */ | ||
578 | for (i = 0; i < DIV_ROUND_UP(data->num_adc, 4); i++) { | ||
579 | val = i2c_smbus_read_byte_data(client, MAX16065_SCALE(i)); | ||
580 | if (unlikely(val < 0)) { | ||
581 | ret = val; | ||
582 | goto out_free; | ||
583 | } | ||
584 | for (j = 0; j < 4 && i * 4 + j < data->num_adc; j++) { | ||
585 | data->range[i * 4 + j] = | ||
586 | max16065_adc_range[(val >> (j * 2)) & 0x3]; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | /* Read limits */ | ||
591 | for (i = 0; i < MAX16065_NUM_LIMIT; i++) { | ||
592 | if (i == 0 && !have_secondary) | ||
593 | continue; | ||
594 | |||
595 | for (j = 0; j < data->num_adc; j++) { | ||
596 | val = i2c_smbus_read_byte_data(client, | ||
597 | MAX16065_LIMIT(i, j)); | ||
598 | if (unlikely(val < 0)) { | ||
599 | ret = val; | ||
600 | goto out_free; | ||
601 | } | ||
602 | data->limit[i][j] = LIMIT_TO_MV(val, data->range[j]); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* Register sysfs hooks */ | ||
607 | for (i = 0; i < data->num_adc * 4; i++) { | ||
608 | /* Do not create sysfs entry if channel is disabled */ | ||
609 | if (!data->range[i / 4]) | ||
610 | continue; | ||
611 | |||
612 | ret = sysfs_create_file(&client->dev.kobj, | ||
613 | max16065_basic_attributes[i]); | ||
614 | if (unlikely(ret)) | ||
615 | goto out; | ||
616 | } | ||
617 | |||
618 | if (have_secondary) { | ||
619 | struct attribute **attr = secondary_is_max ? | ||
620 | max16065_max_attributes : max16065_min_attributes; | ||
621 | |||
622 | for (i = 0; i < data->num_adc; i++) { | ||
623 | if (!data->range[i]) | ||
624 | continue; | ||
625 | |||
626 | ret = sysfs_create_file(&client->dev.kobj, attr[i]); | ||
627 | if (unlikely(ret)) | ||
628 | goto out; | ||
629 | } | ||
630 | } | ||
631 | |||
632 | if (data->have_current) { | ||
633 | val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL); | ||
634 | if (unlikely(val < 0)) { | ||
635 | ret = val; | ||
636 | goto out; | ||
637 | } | ||
638 | if (val & MAX16065_CURR_ENABLE) { | ||
639 | /* | ||
640 | * Current gain is 6, 12, 24, 48 based on values in | ||
641 | * bit 2,3. | ||
642 | */ | ||
643 | data->curr_gain = 6 << ((val >> 2) & 0x03); | ||
644 | data->range[MAX16065_NUM_ADC] | ||
645 | = max16065_csp_adc_range[(val >> 1) & 0x01]; | ||
646 | ret = sysfs_create_group(&client->dev.kobj, | ||
647 | &max16065_current_group); | ||
648 | if (unlikely(ret)) | ||
649 | goto out; | ||
650 | } else { | ||
651 | data->have_current = false; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
656 | if (unlikely(IS_ERR(data->hwmon_dev))) { | ||
657 | ret = PTR_ERR(data->hwmon_dev); | ||
658 | goto out; | ||
659 | } | ||
660 | return 0; | ||
661 | |||
662 | out: | ||
663 | max16065_cleanup(client); | ||
664 | out_free: | ||
665 | kfree(data); | ||
666 | return ret; | ||
667 | } | ||
668 | |||
669 | static int max16065_remove(struct i2c_client *client) | ||
670 | { | ||
671 | struct max16065_data *data = i2c_get_clientdata(client); | ||
672 | |||
673 | hwmon_device_unregister(data->hwmon_dev); | ||
674 | max16065_cleanup(client); | ||
675 | kfree(data); | ||
676 | |||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | static const struct i2c_device_id max16065_id[] = { | ||
681 | { "max16065", max16065 }, | ||
682 | { "max16066", max16066 }, | ||
683 | { "max16067", max16067 }, | ||
684 | { "max16068", max16068 }, | ||
685 | { "max16070", max16070 }, | ||
686 | { "max16071", max16071 }, | ||
687 | { } | ||
688 | }; | ||
689 | |||
690 | MODULE_DEVICE_TABLE(i2c, max16065_id); | ||
691 | |||
692 | /* This is the driver that will be inserted */ | ||
693 | static struct i2c_driver max16065_driver = { | ||
694 | .driver = { | ||
695 | .name = "max16065", | ||
696 | }, | ||
697 | .probe = max16065_probe, | ||
698 | .remove = max16065_remove, | ||
699 | .id_table = max16065_id, | ||
700 | }; | ||
701 | |||
702 | static int __init max16065_init(void) | ||
703 | { | ||
704 | return i2c_add_driver(&max16065_driver); | ||
705 | } | ||
706 | |||
707 | static void __exit max16065_exit(void) | ||
708 | { | ||
709 | i2c_del_driver(&max16065_driver); | ||
710 | } | ||
711 | |||
712 | MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); | ||
713 | MODULE_DESCRIPTION("MAX16065 driver"); | ||
714 | MODULE_LICENSE("GPL"); | ||
715 | |||
716 | module_init(max16065_init); | ||
717 | module_exit(max16065_exit); | ||
diff --git a/drivers/hwmon/max34440.c b/drivers/hwmon/max34440.c index 992b701b4c5e..db11e1a175b2 100644 --- a/drivers/hwmon/max34440.c +++ b/drivers/hwmon/max34440.c | |||
@@ -32,7 +32,7 @@ enum chips { max34440, max34441 }; | |||
32 | #define MAX34440_STATUS_OT_FAULT (1 << 5) | 32 | #define MAX34440_STATUS_OT_FAULT (1 << 5) |
33 | #define MAX34440_STATUS_OT_WARN (1 << 6) | 33 | #define MAX34440_STATUS_OT_WARN (1 << 6) |
34 | 34 | ||
35 | static int max34440_get_status(struct i2c_client *client, int page, int reg) | 35 | static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) |
36 | { | 36 | { |
37 | int ret; | 37 | int ret; |
38 | int mfg_status; | 38 | int mfg_status; |
@@ -108,7 +108,7 @@ static struct pmbus_driver_info max34440_info[] = { | |||
108 | .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | 108 | .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, |
109 | .func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | 109 | .func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, |
110 | .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | 110 | .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, |
111 | .get_status = max34440_get_status, | 111 | .read_byte_data = max34440_read_byte_data, |
112 | }, | 112 | }, |
113 | [max34441] = { | 113 | [max34441] = { |
114 | .pages = 12, | 114 | .pages = 12, |
@@ -149,7 +149,7 @@ static struct pmbus_driver_info max34440_info[] = { | |||
149 | .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | 149 | .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, |
150 | .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | 150 | .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, |
151 | .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | 151 | .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, |
152 | .get_status = max34440_get_status, | 152 | .read_byte_data = max34440_read_byte_data, |
153 | }, | 153 | }, |
154 | }; | 154 | }; |
155 | 155 | ||
diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c new file mode 100644 index 000000000000..0f9fc40379cd --- /dev/null +++ b/drivers/hwmon/max6642.c | |||
@@ -0,0 +1,356 @@ | |||
1 | /* | ||
2 | * Driver for +/-1 degree C, SMBus-Compatible Remote/Local Temperature Sensor | ||
3 | * with Overtemperature Alarm | ||
4 | * | ||
5 | * Copyright (C) 2011 AppearTV AS | ||
6 | * | ||
7 | * Derived from: | ||
8 | * | ||
9 | * Based on the max1619 driver. | ||
10 | * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru> | ||
11 | * Jean Delvare <khali@linux-fr.org> | ||
12 | * | ||
13 | * The MAX6642 is a sensor chip made by Maxim. | ||
14 | * It reports up to two temperatures (its own plus up to | ||
15 | * one external one). Complete datasheet can be | ||
16 | * obtained from Maxim's website at: | ||
17 | * http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify | ||
20 | * it under the terms of the GNU General Public License as published by | ||
21 | * the Free Software Foundation; either version 2 of the License, or | ||
22 | * (at your option) any later version. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, | ||
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
27 | * GNU General Public License for more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License | ||
30 | * along with this program; if not, write to the Free Software | ||
31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
32 | */ | ||
33 | |||
34 | |||
35 | #include <linux/module.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/jiffies.h> | ||
39 | #include <linux/i2c.h> | ||
40 | #include <linux/hwmon.h> | ||
41 | #include <linux/hwmon-sysfs.h> | ||
42 | #include <linux/err.h> | ||
43 | #include <linux/mutex.h> | ||
44 | #include <linux/sysfs.h> | ||
45 | |||
46 | static const unsigned short normal_i2c[] = { | ||
47 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; | ||
48 | |||
49 | /* | ||
50 | * The MAX6642 registers | ||
51 | */ | ||
52 | |||
53 | #define MAX6642_REG_R_MAN_ID 0xFE | ||
54 | #define MAX6642_REG_R_CONFIG 0x03 | ||
55 | #define MAX6642_REG_W_CONFIG 0x09 | ||
56 | #define MAX6642_REG_R_STATUS 0x02 | ||
57 | #define MAX6642_REG_R_LOCAL_TEMP 0x00 | ||
58 | #define MAX6642_REG_R_LOCAL_TEMPL 0x11 | ||
59 | #define MAX6642_REG_R_LOCAL_HIGH 0x05 | ||
60 | #define MAX6642_REG_W_LOCAL_HIGH 0x0B | ||
61 | #define MAX6642_REG_R_REMOTE_TEMP 0x01 | ||
62 | #define MAX6642_REG_R_REMOTE_TEMPL 0x10 | ||
63 | #define MAX6642_REG_R_REMOTE_HIGH 0x07 | ||
64 | #define MAX6642_REG_W_REMOTE_HIGH 0x0D | ||
65 | |||
66 | /* | ||
67 | * Conversions | ||
68 | */ | ||
69 | |||
70 | static int temp_from_reg10(int val) | ||
71 | { | ||
72 | return val * 250; | ||
73 | } | ||
74 | |||
75 | static int temp_from_reg(int val) | ||
76 | { | ||
77 | return val * 1000; | ||
78 | } | ||
79 | |||
80 | static int temp_to_reg(int val) | ||
81 | { | ||
82 | return val / 1000; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Client data (each client gets its own) | ||
87 | */ | ||
88 | |||
89 | struct max6642_data { | ||
90 | struct device *hwmon_dev; | ||
91 | struct mutex update_lock; | ||
92 | bool valid; /* zero until following fields are valid */ | ||
93 | unsigned long last_updated; /* in jiffies */ | ||
94 | |||
95 | /* registers values */ | ||
96 | u16 temp_input[2]; /* local/remote */ | ||
97 | u16 temp_high[2]; /* local/remote */ | ||
98 | u8 alarms; | ||
99 | }; | ||
100 | |||
101 | /* | ||
102 | * Real code | ||
103 | */ | ||
104 | |||
105 | static void max6642_init_client(struct i2c_client *client) | ||
106 | { | ||
107 | u8 config; | ||
108 | struct max6642_data *data = i2c_get_clientdata(client); | ||
109 | |||
110 | /* | ||
111 | * Start the conversions. | ||
112 | */ | ||
113 | config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG); | ||
114 | if (config & 0x40) | ||
115 | i2c_smbus_write_byte_data(client, MAX6642_REG_W_CONFIG, | ||
116 | config & 0xBF); /* run */ | ||
117 | |||
118 | data->temp_high[0] = i2c_smbus_read_byte_data(client, | ||
119 | MAX6642_REG_R_LOCAL_HIGH); | ||
120 | data->temp_high[1] = i2c_smbus_read_byte_data(client, | ||
121 | MAX6642_REG_R_REMOTE_HIGH); | ||
122 | } | ||
123 | |||
124 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
125 | static int max6642_detect(struct i2c_client *client, | ||
126 | struct i2c_board_info *info) | ||
127 | { | ||
128 | struct i2c_adapter *adapter = client->adapter; | ||
129 | u8 reg_config, reg_status, man_id; | ||
130 | |||
131 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
132 | return -ENODEV; | ||
133 | |||
134 | /* identification */ | ||
135 | man_id = i2c_smbus_read_byte_data(client, MAX6642_REG_R_MAN_ID); | ||
136 | if (man_id != 0x4D) | ||
137 | return -ENODEV; | ||
138 | |||
139 | /* | ||
140 | * We read the config and status register, the 4 lower bits in the | ||
141 | * config register should be zero and bit 5, 3, 1 and 0 should be | ||
142 | * zero in the status register. | ||
143 | */ | ||
144 | reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG); | ||
145 | reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS); | ||
146 | if (((reg_config & 0x0f) != 0x00) || | ||
147 | ((reg_status & 0x2b) != 0x00)) | ||
148 | return -ENODEV; | ||
149 | |||
150 | strlcpy(info->type, "max6642", I2C_NAME_SIZE); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static struct max6642_data *max6642_update_device(struct device *dev) | ||
156 | { | ||
157 | struct i2c_client *client = to_i2c_client(dev); | ||
158 | struct max6642_data *data = i2c_get_clientdata(client); | ||
159 | u16 val, tmp; | ||
160 | |||
161 | mutex_lock(&data->update_lock); | ||
162 | |||
163 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
164 | dev_dbg(&client->dev, "Updating max6642 data.\n"); | ||
165 | val = i2c_smbus_read_byte_data(client, | ||
166 | MAX6642_REG_R_LOCAL_TEMPL); | ||
167 | tmp = (val >> 6) & 3; | ||
168 | val = i2c_smbus_read_byte_data(client, | ||
169 | MAX6642_REG_R_LOCAL_TEMP); | ||
170 | val = (val << 2) | tmp; | ||
171 | data->temp_input[0] = val; | ||
172 | val = i2c_smbus_read_byte_data(client, | ||
173 | MAX6642_REG_R_REMOTE_TEMPL); | ||
174 | tmp = (val >> 6) & 3; | ||
175 | val = i2c_smbus_read_byte_data(client, | ||
176 | MAX6642_REG_R_REMOTE_TEMP); | ||
177 | val = (val << 2) | tmp; | ||
178 | data->temp_input[1] = val; | ||
179 | data->alarms = i2c_smbus_read_byte_data(client, | ||
180 | MAX6642_REG_R_STATUS); | ||
181 | |||
182 | data->last_updated = jiffies; | ||
183 | data->valid = 1; | ||
184 | } | ||
185 | |||
186 | mutex_unlock(&data->update_lock); | ||
187 | |||
188 | return data; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Sysfs stuff | ||
193 | */ | ||
194 | |||
195 | static ssize_t show_temp_max10(struct device *dev, | ||
196 | struct device_attribute *dev_attr, char *buf) | ||
197 | { | ||
198 | struct max6642_data *data = max6642_update_device(dev); | ||
199 | struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); | ||
200 | |||
201 | return sprintf(buf, "%d\n", | ||
202 | temp_from_reg10(data->temp_input[attr->index])); | ||
203 | } | ||
204 | |||
205 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
206 | char *buf) | ||
207 | { | ||
208 | struct max6642_data *data = max6642_update_device(dev); | ||
209 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); | ||
210 | |||
211 | return sprintf(buf, "%d\n", temp_from_reg(data->temp_high[attr2->nr])); | ||
212 | } | ||
213 | |||
214 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | ||
215 | const char *buf, size_t count) | ||
216 | { | ||
217 | unsigned long val; | ||
218 | int err; | ||
219 | struct i2c_client *client = to_i2c_client(dev); | ||
220 | struct max6642_data *data = i2c_get_clientdata(client); | ||
221 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); | ||
222 | |||
223 | err = strict_strtoul(buf, 10, &val); | ||
224 | if (err < 0) | ||
225 | return err; | ||
226 | |||
227 | mutex_lock(&data->update_lock); | ||
228 | data->temp_high[attr2->nr] = SENSORS_LIMIT(temp_to_reg(val), 0, 255); | ||
229 | i2c_smbus_write_byte_data(client, attr2->index, | ||
230 | data->temp_high[attr2->nr]); | ||
231 | mutex_unlock(&data->update_lock); | ||
232 | return count; | ||
233 | } | ||
234 | |||
235 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
236 | char *buf) | ||
237 | { | ||
238 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
239 | struct max6642_data *data = max6642_update_device(dev); | ||
240 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | ||
241 | } | ||
242 | |||
243 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_max10, NULL, 0); | ||
244 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_max10, NULL, 1); | ||
245 | static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
246 | set_temp_max, 0, MAX6642_REG_W_LOCAL_HIGH); | ||
247 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
248 | set_temp_max, 1, MAX6642_REG_W_REMOTE_HIGH); | ||
249 | static SENSOR_DEVICE_ATTR(temp_fault, S_IRUGO, show_alarm, NULL, 2); | ||
250 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
251 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
252 | |||
253 | static struct attribute *max6642_attributes[] = { | ||
254 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
255 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
256 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
257 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
258 | |||
259 | &sensor_dev_attr_temp_fault.dev_attr.attr, | ||
260 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
261 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
262 | NULL | ||
263 | }; | ||
264 | |||
265 | static const struct attribute_group max6642_group = { | ||
266 | .attrs = max6642_attributes, | ||
267 | }; | ||
268 | |||
269 | static int max6642_probe(struct i2c_client *new_client, | ||
270 | const struct i2c_device_id *id) | ||
271 | { | ||
272 | struct max6642_data *data; | ||
273 | int err; | ||
274 | |||
275 | data = kzalloc(sizeof(struct max6642_data), GFP_KERNEL); | ||
276 | if (!data) { | ||
277 | err = -ENOMEM; | ||
278 | goto exit; | ||
279 | } | ||
280 | |||
281 | i2c_set_clientdata(new_client, data); | ||
282 | mutex_init(&data->update_lock); | ||
283 | |||
284 | /* Initialize the MAX6642 chip */ | ||
285 | max6642_init_client(new_client); | ||
286 | |||
287 | /* Register sysfs hooks */ | ||
288 | err = sysfs_create_group(&new_client->dev.kobj, &max6642_group); | ||
289 | if (err) | ||
290 | goto exit_free; | ||
291 | |||
292 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
293 | if (IS_ERR(data->hwmon_dev)) { | ||
294 | err = PTR_ERR(data->hwmon_dev); | ||
295 | goto exit_remove_files; | ||
296 | } | ||
297 | |||
298 | return 0; | ||
299 | |||
300 | exit_remove_files: | ||
301 | sysfs_remove_group(&new_client->dev.kobj, &max6642_group); | ||
302 | exit_free: | ||
303 | kfree(data); | ||
304 | exit: | ||
305 | return err; | ||
306 | } | ||
307 | |||
308 | static int max6642_remove(struct i2c_client *client) | ||
309 | { | ||
310 | struct max6642_data *data = i2c_get_clientdata(client); | ||
311 | |||
312 | hwmon_device_unregister(data->hwmon_dev); | ||
313 | sysfs_remove_group(&client->dev.kobj, &max6642_group); | ||
314 | |||
315 | kfree(data); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Driver data (common to all clients) | ||
321 | */ | ||
322 | |||
323 | static const struct i2c_device_id max6642_id[] = { | ||
324 | { "max6642", 0 }, | ||
325 | { } | ||
326 | }; | ||
327 | MODULE_DEVICE_TABLE(i2c, max6642_id); | ||
328 | |||
329 | static struct i2c_driver max6642_driver = { | ||
330 | .class = I2C_CLASS_HWMON, | ||
331 | .driver = { | ||
332 | .name = "max6642", | ||
333 | }, | ||
334 | .probe = max6642_probe, | ||
335 | .remove = max6642_remove, | ||
336 | .id_table = max6642_id, | ||
337 | .detect = max6642_detect, | ||
338 | .address_list = normal_i2c, | ||
339 | }; | ||
340 | |||
341 | static int __init max6642_init(void) | ||
342 | { | ||
343 | return i2c_add_driver(&max6642_driver); | ||
344 | } | ||
345 | |||
346 | static void __exit max6642_exit(void) | ||
347 | { | ||
348 | i2c_del_driver(&max6642_driver); | ||
349 | } | ||
350 | |||
351 | MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>"); | ||
352 | MODULE_DESCRIPTION("MAX6642 sensor driver"); | ||
353 | MODULE_LICENSE("GPL"); | ||
354 | |||
355 | module_init(max6642_init); | ||
356 | module_exit(max6642_exit); | ||
diff --git a/drivers/hwmon/max8688.c b/drivers/hwmon/max8688.c index 8ebfef2ecf26..7fb93f4e9f21 100644 --- a/drivers/hwmon/max8688.c +++ b/drivers/hwmon/max8688.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #define MAX8688_STATUS_OT_FAULT (1 << 13) | 37 | #define MAX8688_STATUS_OT_FAULT (1 << 13) |
38 | #define MAX8688_STATUS_OT_WARNING (1 << 14) | 38 | #define MAX8688_STATUS_OT_WARNING (1 << 14) |
39 | 39 | ||
40 | static int max8688_get_status(struct i2c_client *client, int page, int reg) | 40 | static int max8688_read_byte_data(struct i2c_client *client, int page, int reg) |
41 | { | 41 | { |
42 | int ret = 0; | 42 | int ret = 0; |
43 | int mfg_status; | 43 | int mfg_status; |
@@ -110,7 +110,7 @@ static struct pmbus_driver_info max8688_info = { | |||
110 | .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP | 110 | .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP |
111 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT | 111 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
112 | | PMBUS_HAVE_STATUS_TEMP, | 112 | | PMBUS_HAVE_STATUS_TEMP, |
113 | .get_status = max8688_get_status, | 113 | .read_byte_data = max8688_read_byte_data, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static int max8688_probe(struct i2c_client *client, | 116 | static int max8688_probe(struct i2c_client *client, |
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c deleted file mode 100644 index 21c817d98123..000000000000 --- a/drivers/hwmon/pkgtemp.c +++ /dev/null | |||
@@ -1,444 +0,0 @@ | |||
1 | /* | ||
2 | * pkgtemp.c - Linux kernel module for processor package hardware monitoring | ||
3 | * | ||
4 | * Copyright (C) 2010 Fenghua Yu <fenghua.yu@intel.com> | ||
5 | * | ||
6 | * Inspired from many hwmon drivers especially coretemp. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA. | ||
21 | */ | ||
22 | |||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/hwmon.h> | ||
30 | #include <linux/sysfs.h> | ||
31 | #include <linux/hwmon-sysfs.h> | ||
32 | #include <linux/err.h> | ||
33 | #include <linux/mutex.h> | ||
34 | #include <linux/list.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/cpu.h> | ||
37 | #include <asm/msr.h> | ||
38 | #include <asm/processor.h> | ||
39 | #include <asm/smp.h> | ||
40 | |||
41 | #define DRVNAME "pkgtemp" | ||
42 | |||
43 | enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL, SHOW_NAME }; | ||
44 | |||
45 | /* | ||
46 | * Functions declaration | ||
47 | */ | ||
48 | |||
49 | static struct pkgtemp_data *pkgtemp_update_device(struct device *dev); | ||
50 | |||
51 | struct pkgtemp_data { | ||
52 | struct device *hwmon_dev; | ||
53 | struct mutex update_lock; | ||
54 | const char *name; | ||
55 | u32 id; | ||
56 | u16 phys_proc_id; | ||
57 | char valid; /* zero until following fields are valid */ | ||
58 | unsigned long last_updated; /* in jiffies */ | ||
59 | int temp; | ||
60 | int tjmax; | ||
61 | int ttarget; | ||
62 | u8 alarm; | ||
63 | }; | ||
64 | |||
65 | /* | ||
66 | * Sysfs stuff | ||
67 | */ | ||
68 | |||
69 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
70 | *devattr, char *buf) | ||
71 | { | ||
72 | int ret; | ||
73 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
74 | struct pkgtemp_data *data = dev_get_drvdata(dev); | ||
75 | |||
76 | if (attr->index == SHOW_NAME) | ||
77 | ret = sprintf(buf, "%s\n", data->name); | ||
78 | else /* show label */ | ||
79 | ret = sprintf(buf, "physical id %d\n", | ||
80 | data->phys_proc_id); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | static ssize_t show_alarm(struct device *dev, struct device_attribute | ||
85 | *devattr, char *buf) | ||
86 | { | ||
87 | struct pkgtemp_data *data = pkgtemp_update_device(dev); | ||
88 | /* read the Out-of-spec log, never clear */ | ||
89 | return sprintf(buf, "%d\n", data->alarm); | ||
90 | } | ||
91 | |||
92 | static ssize_t show_temp(struct device *dev, | ||
93 | struct device_attribute *devattr, char *buf) | ||
94 | { | ||
95 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
96 | struct pkgtemp_data *data = pkgtemp_update_device(dev); | ||
97 | int err = 0; | ||
98 | |||
99 | if (attr->index == SHOW_TEMP) | ||
100 | err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN; | ||
101 | else if (attr->index == SHOW_TJMAX) | ||
102 | err = sprintf(buf, "%d\n", data->tjmax); | ||
103 | else | ||
104 | err = sprintf(buf, "%d\n", data->ttarget); | ||
105 | return err; | ||
106 | } | ||
107 | |||
108 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, SHOW_TEMP); | ||
109 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, SHOW_TJMAX); | ||
110 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, SHOW_TTARGET); | ||
111 | static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL); | ||
112 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); | ||
113 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); | ||
114 | |||
115 | static struct attribute *pkgtemp_attributes[] = { | ||
116 | &sensor_dev_attr_name.dev_attr.attr, | ||
117 | &sensor_dev_attr_temp1_label.dev_attr.attr, | ||
118 | &dev_attr_temp1_crit_alarm.attr, | ||
119 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
120 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
121 | NULL | ||
122 | }; | ||
123 | |||
124 | static const struct attribute_group pkgtemp_group = { | ||
125 | .attrs = pkgtemp_attributes, | ||
126 | }; | ||
127 | |||
128 | static struct pkgtemp_data *pkgtemp_update_device(struct device *dev) | ||
129 | { | ||
130 | struct pkgtemp_data *data = dev_get_drvdata(dev); | ||
131 | unsigned int cpu; | ||
132 | int err; | ||
133 | |||
134 | mutex_lock(&data->update_lock); | ||
135 | |||
136 | if (!data->valid || time_after(jiffies, data->last_updated + HZ)) { | ||
137 | u32 eax, edx; | ||
138 | |||
139 | data->valid = 0; | ||
140 | cpu = data->id; | ||
141 | err = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_STATUS, | ||
142 | &eax, &edx); | ||
143 | if (!err) { | ||
144 | data->alarm = (eax >> 5) & 1; | ||
145 | data->temp = data->tjmax - (((eax >> 16) | ||
146 | & 0x7f) * 1000); | ||
147 | data->valid = 1; | ||
148 | } else | ||
149 | dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax); | ||
150 | |||
151 | data->last_updated = jiffies; | ||
152 | } | ||
153 | |||
154 | mutex_unlock(&data->update_lock); | ||
155 | return data; | ||
156 | } | ||
157 | |||
158 | static int get_tjmax(int cpu, struct device *dev) | ||
159 | { | ||
160 | int default_tjmax = 100000; | ||
161 | int err; | ||
162 | u32 eax, edx; | ||
163 | u32 val; | ||
164 | |||
165 | /* IA32_TEMPERATURE_TARGET contains the TjMax value */ | ||
166 | err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); | ||
167 | if (!err) { | ||
168 | val = (eax >> 16) & 0xff; | ||
169 | if ((val > 80) && (val < 120)) { | ||
170 | dev_info(dev, "TjMax is %d C.\n", val); | ||
171 | return val * 1000; | ||
172 | } | ||
173 | } | ||
174 | dev_warn(dev, "Unable to read TjMax from CPU.\n"); | ||
175 | return default_tjmax; | ||
176 | } | ||
177 | |||
178 | static int __devinit pkgtemp_probe(struct platform_device *pdev) | ||
179 | { | ||
180 | struct pkgtemp_data *data; | ||
181 | int err; | ||
182 | u32 eax, edx; | ||
183 | #ifdef CONFIG_SMP | ||
184 | struct cpuinfo_x86 *c = &cpu_data(pdev->id); | ||
185 | #endif | ||
186 | |||
187 | data = kzalloc(sizeof(struct pkgtemp_data), GFP_KERNEL); | ||
188 | if (!data) { | ||
189 | err = -ENOMEM; | ||
190 | dev_err(&pdev->dev, "Out of memory\n"); | ||
191 | goto exit; | ||
192 | } | ||
193 | |||
194 | data->id = pdev->id; | ||
195 | #ifdef CONFIG_SMP | ||
196 | data->phys_proc_id = c->phys_proc_id; | ||
197 | #endif | ||
198 | data->name = "pkgtemp"; | ||
199 | mutex_init(&data->update_lock); | ||
200 | |||
201 | /* test if we can access the THERM_STATUS MSR */ | ||
202 | err = rdmsr_safe_on_cpu(data->id, MSR_IA32_PACKAGE_THERM_STATUS, | ||
203 | &eax, &edx); | ||
204 | if (err) { | ||
205 | dev_err(&pdev->dev, | ||
206 | "Unable to access THERM_STATUS MSR, giving up\n"); | ||
207 | goto exit_free; | ||
208 | } | ||
209 | |||
210 | data->tjmax = get_tjmax(data->id, &pdev->dev); | ||
211 | platform_set_drvdata(pdev, data); | ||
212 | |||
213 | err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, | ||
214 | &eax, &edx); | ||
215 | if (err) { | ||
216 | dev_warn(&pdev->dev, "Unable to read" | ||
217 | " IA32_TEMPERATURE_TARGET MSR\n"); | ||
218 | } else { | ||
219 | data->ttarget = data->tjmax - (((eax >> 8) & 0xff) * 1000); | ||
220 | err = device_create_file(&pdev->dev, | ||
221 | &sensor_dev_attr_temp1_max.dev_attr); | ||
222 | if (err) | ||
223 | goto exit_free; | ||
224 | } | ||
225 | |||
226 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); | ||
227 | if (err) | ||
228 | goto exit_dev; | ||
229 | |||
230 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
231 | if (IS_ERR(data->hwmon_dev)) { | ||
232 | err = PTR_ERR(data->hwmon_dev); | ||
233 | dev_err(&pdev->dev, "Class registration failed (%d)\n", | ||
234 | err); | ||
235 | goto exit_class; | ||
236 | } | ||
237 | |||
238 | return 0; | ||
239 | |||
240 | exit_class: | ||
241 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | ||
242 | exit_dev: | ||
243 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
244 | exit_free: | ||
245 | kfree(data); | ||
246 | exit: | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | static int __devexit pkgtemp_remove(struct platform_device *pdev) | ||
251 | { | ||
252 | struct pkgtemp_data *data = platform_get_drvdata(pdev); | ||
253 | |||
254 | hwmon_device_unregister(data->hwmon_dev); | ||
255 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | ||
256 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
257 | platform_set_drvdata(pdev, NULL); | ||
258 | kfree(data); | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static struct platform_driver pkgtemp_driver = { | ||
263 | .driver = { | ||
264 | .owner = THIS_MODULE, | ||
265 | .name = DRVNAME, | ||
266 | }, | ||
267 | .probe = pkgtemp_probe, | ||
268 | .remove = __devexit_p(pkgtemp_remove), | ||
269 | }; | ||
270 | |||
271 | struct pdev_entry { | ||
272 | struct list_head list; | ||
273 | struct platform_device *pdev; | ||
274 | unsigned int cpu; | ||
275 | #ifdef CONFIG_SMP | ||
276 | u16 phys_proc_id; | ||
277 | #endif | ||
278 | }; | ||
279 | |||
280 | static LIST_HEAD(pdev_list); | ||
281 | static DEFINE_MUTEX(pdev_list_mutex); | ||
282 | |||
283 | static int __cpuinit pkgtemp_device_add(unsigned int cpu) | ||
284 | { | ||
285 | int err; | ||
286 | struct platform_device *pdev; | ||
287 | struct pdev_entry *pdev_entry; | ||
288 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
289 | |||
290 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
291 | return 0; | ||
292 | |||
293 | mutex_lock(&pdev_list_mutex); | ||
294 | |||
295 | #ifdef CONFIG_SMP | ||
296 | /* Only keep the first entry in each package */ | ||
297 | list_for_each_entry(pdev_entry, &pdev_list, list) { | ||
298 | if (c->phys_proc_id == pdev_entry->phys_proc_id) { | ||
299 | err = 0; /* Not an error */ | ||
300 | goto exit; | ||
301 | } | ||
302 | } | ||
303 | #endif | ||
304 | |||
305 | pdev = platform_device_alloc(DRVNAME, cpu); | ||
306 | if (!pdev) { | ||
307 | err = -ENOMEM; | ||
308 | pr_err("Device allocation failed\n"); | ||
309 | goto exit; | ||
310 | } | ||
311 | |||
312 | pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL); | ||
313 | if (!pdev_entry) { | ||
314 | err = -ENOMEM; | ||
315 | goto exit_device_put; | ||
316 | } | ||
317 | |||
318 | err = platform_device_add(pdev); | ||
319 | if (err) { | ||
320 | pr_err("Device addition failed (%d)\n", err); | ||
321 | goto exit_device_free; | ||
322 | } | ||
323 | |||
324 | #ifdef CONFIG_SMP | ||
325 | pdev_entry->phys_proc_id = c->phys_proc_id; | ||
326 | #endif | ||
327 | pdev_entry->pdev = pdev; | ||
328 | pdev_entry->cpu = cpu; | ||
329 | list_add_tail(&pdev_entry->list, &pdev_list); | ||
330 | mutex_unlock(&pdev_list_mutex); | ||
331 | |||
332 | return 0; | ||
333 | |||
334 | exit_device_free: | ||
335 | kfree(pdev_entry); | ||
336 | exit_device_put: | ||
337 | platform_device_put(pdev); | ||
338 | exit: | ||
339 | mutex_unlock(&pdev_list_mutex); | ||
340 | return err; | ||
341 | } | ||
342 | |||
343 | static void __cpuinit pkgtemp_device_remove(unsigned int cpu) | ||
344 | { | ||
345 | struct pdev_entry *p; | ||
346 | unsigned int i; | ||
347 | int err; | ||
348 | |||
349 | mutex_lock(&pdev_list_mutex); | ||
350 | list_for_each_entry(p, &pdev_list, list) { | ||
351 | if (p->cpu != cpu) | ||
352 | continue; | ||
353 | |||
354 | platform_device_unregister(p->pdev); | ||
355 | list_del(&p->list); | ||
356 | mutex_unlock(&pdev_list_mutex); | ||
357 | kfree(p); | ||
358 | for_each_cpu(i, cpu_core_mask(cpu)) { | ||
359 | if (i != cpu) { | ||
360 | err = pkgtemp_device_add(i); | ||
361 | if (!err) | ||
362 | break; | ||
363 | } | ||
364 | } | ||
365 | return; | ||
366 | } | ||
367 | mutex_unlock(&pdev_list_mutex); | ||
368 | } | ||
369 | |||
370 | static int __cpuinit pkgtemp_cpu_callback(struct notifier_block *nfb, | ||
371 | unsigned long action, void *hcpu) | ||
372 | { | ||
373 | unsigned int cpu = (unsigned long) hcpu; | ||
374 | |||
375 | switch (action) { | ||
376 | case CPU_ONLINE: | ||
377 | case CPU_DOWN_FAILED: | ||
378 | pkgtemp_device_add(cpu); | ||
379 | break; | ||
380 | case CPU_DOWN_PREPARE: | ||
381 | pkgtemp_device_remove(cpu); | ||
382 | break; | ||
383 | } | ||
384 | return NOTIFY_OK; | ||
385 | } | ||
386 | |||
387 | static struct notifier_block pkgtemp_cpu_notifier __refdata = { | ||
388 | .notifier_call = pkgtemp_cpu_callback, | ||
389 | }; | ||
390 | |||
391 | static int __init pkgtemp_init(void) | ||
392 | { | ||
393 | int i, err = -ENODEV; | ||
394 | |||
395 | /* quick check if we run Intel */ | ||
396 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) | ||
397 | goto exit; | ||
398 | |||
399 | err = platform_driver_register(&pkgtemp_driver); | ||
400 | if (err) | ||
401 | goto exit; | ||
402 | |||
403 | for_each_online_cpu(i) | ||
404 | pkgtemp_device_add(i); | ||
405 | |||
406 | #ifndef CONFIG_HOTPLUG_CPU | ||
407 | if (list_empty(&pdev_list)) { | ||
408 | err = -ENODEV; | ||
409 | goto exit_driver_unreg; | ||
410 | } | ||
411 | #endif | ||
412 | |||
413 | register_hotcpu_notifier(&pkgtemp_cpu_notifier); | ||
414 | return 0; | ||
415 | |||
416 | #ifndef CONFIG_HOTPLUG_CPU | ||
417 | exit_driver_unreg: | ||
418 | platform_driver_unregister(&pkgtemp_driver); | ||
419 | #endif | ||
420 | exit: | ||
421 | return err; | ||
422 | } | ||
423 | |||
424 | static void __exit pkgtemp_exit(void) | ||
425 | { | ||
426 | struct pdev_entry *p, *n; | ||
427 | |||
428 | unregister_hotcpu_notifier(&pkgtemp_cpu_notifier); | ||
429 | mutex_lock(&pdev_list_mutex); | ||
430 | list_for_each_entry_safe(p, n, &pdev_list, list) { | ||
431 | platform_device_unregister(p->pdev); | ||
432 | list_del(&p->list); | ||
433 | kfree(p); | ||
434 | } | ||
435 | mutex_unlock(&pdev_list_mutex); | ||
436 | platform_driver_unregister(&pkgtemp_driver); | ||
437 | } | ||
438 | |||
439 | MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>"); | ||
440 | MODULE_DESCRIPTION("Intel processor package temperature monitor"); | ||
441 | MODULE_LICENSE("GPL"); | ||
442 | |||
443 | module_init(pkgtemp_init) | ||
444 | module_exit(pkgtemp_exit) | ||
diff --git a/drivers/hwmon/pmbus.h b/drivers/hwmon/pmbus.h index a81f7f228762..50647ab7235a 100644 --- a/drivers/hwmon/pmbus.h +++ b/drivers/hwmon/pmbus.h | |||
@@ -281,13 +281,11 @@ struct pmbus_driver_info { | |||
281 | 281 | ||
282 | u32 func[PMBUS_PAGES]; /* Functionality, per page */ | 282 | u32 func[PMBUS_PAGES]; /* Functionality, per page */ |
283 | /* | 283 | /* |
284 | * The get_status function maps manufacturing specific status values | 284 | * The following functions map manufacturing specific register values |
285 | * into PMBus standard status values. | 285 | * to PMBus standard register values. Specify only if mapping is |
286 | * This function is optional and only necessary if chip specific status | 286 | * necessary. |
287 | * register values have to be mapped into standard PMBus status register | ||
288 | * values. | ||
289 | */ | 287 | */ |
290 | int (*get_status)(struct i2c_client *client, int page, int reg); | 288 | int (*read_byte_data)(struct i2c_client *client, int page, int reg); |
291 | /* | 289 | /* |
292 | * The identify function determines supported PMBus functionality. | 290 | * The identify function determines supported PMBus functionality. |
293 | * This function is only necessary if a chip driver supports multiple | 291 | * This function is only necessary if a chip driver supports multiple |
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c index 196ffafafd88..98799bab69ce 100644 --- a/drivers/hwmon/pmbus_core.c +++ b/drivers/hwmon/pmbus_core.c | |||
@@ -270,18 +270,22 @@ const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) | |||
270 | } | 270 | } |
271 | EXPORT_SYMBOL_GPL(pmbus_get_driver_info); | 271 | EXPORT_SYMBOL_GPL(pmbus_get_driver_info); |
272 | 272 | ||
273 | static int pmbus_get_status(struct i2c_client *client, int page, int reg) | 273 | /* |
274 | * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if | ||
275 | * a device specific mapping funcion exists and calls it if necessary. | ||
276 | */ | ||
277 | static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) | ||
274 | { | 278 | { |
275 | struct pmbus_data *data = i2c_get_clientdata(client); | 279 | struct pmbus_data *data = i2c_get_clientdata(client); |
276 | const struct pmbus_driver_info *info = data->info; | 280 | const struct pmbus_driver_info *info = data->info; |
277 | int status; | 281 | int status; |
278 | 282 | ||
279 | if (info->get_status) { | 283 | if (info->read_byte_data) { |
280 | status = info->get_status(client, page, reg); | 284 | status = info->read_byte_data(client, page, reg); |
281 | if (status != -ENODATA) | 285 | if (status != -ENODATA) |
282 | return status; | 286 | return status; |
283 | } | 287 | } |
284 | return pmbus_read_byte_data(client, page, reg); | 288 | return pmbus_read_byte_data(client, page, reg); |
285 | } | 289 | } |
286 | 290 | ||
287 | static struct pmbus_data *pmbus_update_device(struct device *dev) | 291 | static struct pmbus_data *pmbus_update_device(struct device *dev) |
@@ -302,38 +306,41 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) | |||
302 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) | 306 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) |
303 | continue; | 307 | continue; |
304 | data->status[PB_STATUS_VOUT_BASE + i] | 308 | data->status[PB_STATUS_VOUT_BASE + i] |
305 | = pmbus_get_status(client, i, PMBUS_STATUS_VOUT); | 309 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_VOUT); |
306 | } | 310 | } |
307 | for (i = 0; i < info->pages; i++) { | 311 | for (i = 0; i < info->pages; i++) { |
308 | if (!(info->func[i] & PMBUS_HAVE_STATUS_IOUT)) | 312 | if (!(info->func[i] & PMBUS_HAVE_STATUS_IOUT)) |
309 | continue; | 313 | continue; |
310 | data->status[PB_STATUS_IOUT_BASE + i] | 314 | data->status[PB_STATUS_IOUT_BASE + i] |
311 | = pmbus_get_status(client, i, PMBUS_STATUS_IOUT); | 315 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_IOUT); |
312 | } | 316 | } |
313 | for (i = 0; i < info->pages; i++) { | 317 | for (i = 0; i < info->pages; i++) { |
314 | if (!(info->func[i] & PMBUS_HAVE_STATUS_TEMP)) | 318 | if (!(info->func[i] & PMBUS_HAVE_STATUS_TEMP)) |
315 | continue; | 319 | continue; |
316 | data->status[PB_STATUS_TEMP_BASE + i] | 320 | data->status[PB_STATUS_TEMP_BASE + i] |
317 | = pmbus_get_status(client, i, | 321 | = _pmbus_read_byte_data(client, i, |
318 | PMBUS_STATUS_TEMPERATURE); | 322 | PMBUS_STATUS_TEMPERATURE); |
319 | } | 323 | } |
320 | for (i = 0; i < info->pages; i++) { | 324 | for (i = 0; i < info->pages; i++) { |
321 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN12)) | 325 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN12)) |
322 | continue; | 326 | continue; |
323 | data->status[PB_STATUS_FAN_BASE + i] | 327 | data->status[PB_STATUS_FAN_BASE + i] |
324 | = pmbus_get_status(client, i, PMBUS_STATUS_FAN_12); | 328 | = _pmbus_read_byte_data(client, i, |
329 | PMBUS_STATUS_FAN_12); | ||
325 | } | 330 | } |
326 | 331 | ||
327 | for (i = 0; i < info->pages; i++) { | 332 | for (i = 0; i < info->pages; i++) { |
328 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34)) | 333 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34)) |
329 | continue; | 334 | continue; |
330 | data->status[PB_STATUS_FAN34_BASE + i] | 335 | data->status[PB_STATUS_FAN34_BASE + i] |
331 | = pmbus_get_status(client, i, PMBUS_STATUS_FAN_34); | 336 | = _pmbus_read_byte_data(client, i, |
337 | PMBUS_STATUS_FAN_34); | ||
332 | } | 338 | } |
333 | 339 | ||
334 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) | 340 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) |
335 | data->status[PB_STATUS_INPUT_BASE] | 341 | data->status[PB_STATUS_INPUT_BASE] |
336 | = pmbus_get_status(client, 0, PMBUS_STATUS_INPUT); | 342 | = _pmbus_read_byte_data(client, 0, |
343 | PMBUS_STATUS_INPUT); | ||
337 | 344 | ||
338 | for (i = 0; i < data->num_sensors; i++) { | 345 | for (i = 0; i < data->num_sensors; i++) { |
339 | struct pmbus_sensor *sensor = &data->sensors[i]; | 346 | struct pmbus_sensor *sensor = &data->sensors[i]; |
@@ -793,53 +800,6 @@ static void pmbus_add_label(struct pmbus_data *data, | |||
793 | data->num_labels++; | 800 | data->num_labels++; |
794 | } | 801 | } |
795 | 802 | ||
796 | static const int pmbus_temp_registers[] = { | ||
797 | PMBUS_READ_TEMPERATURE_1, | ||
798 | PMBUS_READ_TEMPERATURE_2, | ||
799 | PMBUS_READ_TEMPERATURE_3 | ||
800 | }; | ||
801 | |||
802 | static const int pmbus_temp_flags[] = { | ||
803 | PMBUS_HAVE_TEMP, | ||
804 | PMBUS_HAVE_TEMP2, | ||
805 | PMBUS_HAVE_TEMP3 | ||
806 | }; | ||
807 | |||
808 | static const int pmbus_fan_registers[] = { | ||
809 | PMBUS_READ_FAN_SPEED_1, | ||
810 | PMBUS_READ_FAN_SPEED_2, | ||
811 | PMBUS_READ_FAN_SPEED_3, | ||
812 | PMBUS_READ_FAN_SPEED_4 | ||
813 | }; | ||
814 | |||
815 | static const int pmbus_fan_config_registers[] = { | ||
816 | PMBUS_FAN_CONFIG_12, | ||
817 | PMBUS_FAN_CONFIG_12, | ||
818 | PMBUS_FAN_CONFIG_34, | ||
819 | PMBUS_FAN_CONFIG_34 | ||
820 | }; | ||
821 | |||
822 | static const int pmbus_fan_status_registers[] = { | ||
823 | PMBUS_STATUS_FAN_12, | ||
824 | PMBUS_STATUS_FAN_12, | ||
825 | PMBUS_STATUS_FAN_34, | ||
826 | PMBUS_STATUS_FAN_34 | ||
827 | }; | ||
828 | |||
829 | static const u32 pmbus_fan_flags[] = { | ||
830 | PMBUS_HAVE_FAN12, | ||
831 | PMBUS_HAVE_FAN12, | ||
832 | PMBUS_HAVE_FAN34, | ||
833 | PMBUS_HAVE_FAN34 | ||
834 | }; | ||
835 | |||
836 | static const u32 pmbus_fan_status_flags[] = { | ||
837 | PMBUS_HAVE_STATUS_FAN12, | ||
838 | PMBUS_HAVE_STATUS_FAN12, | ||
839 | PMBUS_HAVE_STATUS_FAN34, | ||
840 | PMBUS_HAVE_STATUS_FAN34 | ||
841 | }; | ||
842 | |||
843 | /* | 803 | /* |
844 | * Determine maximum number of sensors, booleans, and labels. | 804 | * Determine maximum number of sensors, booleans, and labels. |
845 | * To keep things simple, only make a rough high estimate. | 805 | * To keep things simple, only make a rough high estimate. |
@@ -900,499 +860,431 @@ static void pmbus_find_max_attr(struct i2c_client *client, | |||
900 | /* | 860 | /* |
901 | * Search for attributes. Allocate sensors, booleans, and labels as needed. | 861 | * Search for attributes. Allocate sensors, booleans, and labels as needed. |
902 | */ | 862 | */ |
903 | static void pmbus_find_attributes(struct i2c_client *client, | ||
904 | struct pmbus_data *data) | ||
905 | { | ||
906 | const struct pmbus_driver_info *info = data->info; | ||
907 | int page, i0, i1, in_index; | ||
908 | 863 | ||
909 | /* | 864 | /* |
910 | * Input voltage sensors | 865 | * The pmbus_limit_attr structure describes a single limit attribute |
911 | */ | 866 | * and its associated alarm attribute. |
912 | in_index = 1; | 867 | */ |
913 | if (info->func[0] & PMBUS_HAVE_VIN) { | 868 | struct pmbus_limit_attr { |
914 | bool have_alarm = false; | 869 | u8 reg; /* Limit register */ |
915 | 870 | const char *attr; /* Attribute name */ | |
916 | i0 = data->num_sensors; | 871 | const char *alarm; /* Alarm attribute name */ |
917 | pmbus_add_label(data, "in", in_index, "vin", 0); | 872 | u32 sbit; /* Alarm attribute status bit */ |
918 | pmbus_add_sensor(data, "in", "input", in_index, 0, | 873 | }; |
919 | PMBUS_READ_VIN, PSC_VOLTAGE_IN, true, true); | 874 | |
920 | if (pmbus_check_word_register(client, 0, | 875 | /* |
921 | PMBUS_VIN_UV_WARN_LIMIT)) { | 876 | * The pmbus_sensor_attr structure describes one sensor attribute. This |
922 | i1 = data->num_sensors; | 877 | * description includes a reference to the associated limit attributes. |
923 | pmbus_add_sensor(data, "in", "min", in_index, | 878 | */ |
924 | 0, PMBUS_VIN_UV_WARN_LIMIT, | 879 | struct pmbus_sensor_attr { |
925 | PSC_VOLTAGE_IN, false, false); | 880 | u8 reg; /* sensor register */ |
926 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { | 881 | enum pmbus_sensor_classes class;/* sensor class */ |
927 | pmbus_add_boolean_reg(data, "in", "min_alarm", | 882 | const char *label; /* sensor label */ |
928 | in_index, | 883 | bool paged; /* true if paged sensor */ |
929 | PB_STATUS_INPUT_BASE, | 884 | bool update; /* true if update needed */ |
930 | PB_VOLTAGE_UV_WARNING); | 885 | bool compare; /* true if compare function needed */ |
931 | have_alarm = true; | 886 | u32 func; /* sensor mask */ |
932 | } | 887 | u32 sfunc; /* sensor status mask */ |
933 | } | 888 | int sbase; /* status base register */ |
934 | if (pmbus_check_word_register(client, 0, | 889 | u32 gbit; /* generic status bit */ |
935 | PMBUS_VIN_UV_FAULT_LIMIT)) { | 890 | const struct pmbus_limit_attr *limit;/* limit registers */ |
936 | i1 = data->num_sensors; | 891 | int nlimit; /* # of limit registers */ |
937 | pmbus_add_sensor(data, "in", "lcrit", in_index, | 892 | }; |
938 | 0, PMBUS_VIN_UV_FAULT_LIMIT, | 893 | |
939 | PSC_VOLTAGE_IN, false, false); | 894 | /* |
940 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { | 895 | * Add a set of limit attributes and, if supported, the associated |
941 | pmbus_add_boolean_reg(data, "in", "lcrit_alarm", | 896 | * alarm attributes. |
942 | in_index, | 897 | */ |
943 | PB_STATUS_INPUT_BASE, | 898 | static bool pmbus_add_limit_attrs(struct i2c_client *client, |
944 | PB_VOLTAGE_UV_FAULT); | 899 | struct pmbus_data *data, |
945 | have_alarm = true; | 900 | const struct pmbus_driver_info *info, |
946 | } | 901 | const char *name, int index, int page, |
947 | } | 902 | int cbase, |
948 | if (pmbus_check_word_register(client, 0, | 903 | const struct pmbus_sensor_attr *attr) |
949 | PMBUS_VIN_OV_WARN_LIMIT)) { | 904 | { |
950 | i1 = data->num_sensors; | 905 | const struct pmbus_limit_attr *l = attr->limit; |
951 | pmbus_add_sensor(data, "in", "max", in_index, | 906 | int nlimit = attr->nlimit; |
952 | 0, PMBUS_VIN_OV_WARN_LIMIT, | 907 | bool have_alarm = false; |
953 | PSC_VOLTAGE_IN, false, false); | 908 | int i, cindex; |
954 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { | 909 | |
955 | pmbus_add_boolean_reg(data, "in", "max_alarm", | 910 | for (i = 0; i < nlimit; i++) { |
956 | in_index, | 911 | if (pmbus_check_word_register(client, page, l->reg)) { |
957 | PB_STATUS_INPUT_BASE, | 912 | cindex = data->num_sensors; |
958 | PB_VOLTAGE_OV_WARNING); | 913 | pmbus_add_sensor(data, name, l->attr, index, page, |
959 | have_alarm = true; | 914 | l->reg, attr->class, attr->update, |
960 | } | 915 | false); |
961 | } | 916 | if (info->func[page] & attr->sfunc) { |
962 | if (pmbus_check_word_register(client, 0, | 917 | if (attr->compare) { |
963 | PMBUS_VIN_OV_FAULT_LIMIT)) { | 918 | pmbus_add_boolean_cmp(data, name, |
964 | i1 = data->num_sensors; | 919 | l->alarm, index, |
965 | pmbus_add_sensor(data, "in", "crit", in_index, | 920 | cbase, cindex, |
966 | 0, PMBUS_VIN_OV_FAULT_LIMIT, | 921 | attr->sbase + page, l->sbit); |
967 | PSC_VOLTAGE_IN, false, false); | 922 | } else { |
968 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { | 923 | pmbus_add_boolean_reg(data, name, |
969 | pmbus_add_boolean_reg(data, "in", "crit_alarm", | 924 | l->alarm, index, |
970 | in_index, | 925 | attr->sbase + page, l->sbit); |
971 | PB_STATUS_INPUT_BASE, | 926 | } |
972 | PB_VOLTAGE_OV_FAULT); | ||
973 | have_alarm = true; | 927 | have_alarm = true; |
974 | } | 928 | } |
975 | } | 929 | } |
976 | /* | 930 | l++; |
977 | * Add generic alarm attribute only if there are no individual | ||
978 | * attributes. | ||
979 | */ | ||
980 | if (!have_alarm) | ||
981 | pmbus_add_boolean_reg(data, "in", "alarm", | ||
982 | in_index, | ||
983 | PB_STATUS_BASE, | ||
984 | PB_STATUS_VIN_UV); | ||
985 | in_index++; | ||
986 | } | ||
987 | if (info->func[0] & PMBUS_HAVE_VCAP) { | ||
988 | pmbus_add_label(data, "in", in_index, "vcap", 0); | ||
989 | pmbus_add_sensor(data, "in", "input", in_index, 0, | ||
990 | PMBUS_READ_VCAP, PSC_VOLTAGE_IN, true, true); | ||
991 | in_index++; | ||
992 | } | 931 | } |
932 | return have_alarm; | ||
933 | } | ||
993 | 934 | ||
994 | /* | 935 | static void pmbus_add_sensor_attrs_one(struct i2c_client *client, |
995 | * Output voltage sensors | 936 | struct pmbus_data *data, |
996 | */ | 937 | const struct pmbus_driver_info *info, |
997 | for (page = 0; page < info->pages; page++) { | 938 | const char *name, |
998 | bool have_alarm = false; | 939 | int index, int page, |
999 | 940 | const struct pmbus_sensor_attr *attr) | |
1000 | if (!(info->func[page] & PMBUS_HAVE_VOUT)) | 941 | { |
1001 | continue; | 942 | bool have_alarm; |
1002 | 943 | int cbase = data->num_sensors; | |
1003 | i0 = data->num_sensors; | 944 | |
1004 | pmbus_add_label(data, "in", in_index, "vout", page + 1); | 945 | if (attr->label) |
1005 | pmbus_add_sensor(data, "in", "input", in_index, page, | 946 | pmbus_add_label(data, name, index, attr->label, |
1006 | PMBUS_READ_VOUT, PSC_VOLTAGE_OUT, true, true); | 947 | attr->paged ? page + 1 : 0); |
1007 | if (pmbus_check_word_register(client, page, | 948 | pmbus_add_sensor(data, name, "input", index, page, attr->reg, |
1008 | PMBUS_VOUT_UV_WARN_LIMIT)) { | 949 | attr->class, true, true); |
1009 | i1 = data->num_sensors; | 950 | if (attr->sfunc) { |
1010 | pmbus_add_sensor(data, "in", "min", in_index, page, | 951 | have_alarm = pmbus_add_limit_attrs(client, data, info, name, |
1011 | PMBUS_VOUT_UV_WARN_LIMIT, | 952 | index, page, cbase, attr); |
1012 | PSC_VOLTAGE_OUT, false, false); | ||
1013 | if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { | ||
1014 | pmbus_add_boolean_reg(data, "in", "min_alarm", | ||
1015 | in_index, | ||
1016 | PB_STATUS_VOUT_BASE + | ||
1017 | page, | ||
1018 | PB_VOLTAGE_UV_WARNING); | ||
1019 | have_alarm = true; | ||
1020 | } | ||
1021 | } | ||
1022 | if (pmbus_check_word_register(client, page, | ||
1023 | PMBUS_VOUT_UV_FAULT_LIMIT)) { | ||
1024 | i1 = data->num_sensors; | ||
1025 | pmbus_add_sensor(data, "in", "lcrit", in_index, page, | ||
1026 | PMBUS_VOUT_UV_FAULT_LIMIT, | ||
1027 | PSC_VOLTAGE_OUT, false, false); | ||
1028 | if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { | ||
1029 | pmbus_add_boolean_reg(data, "in", "lcrit_alarm", | ||
1030 | in_index, | ||
1031 | PB_STATUS_VOUT_BASE + | ||
1032 | page, | ||
1033 | PB_VOLTAGE_UV_FAULT); | ||
1034 | have_alarm = true; | ||
1035 | } | ||
1036 | } | ||
1037 | if (pmbus_check_word_register(client, page, | ||
1038 | PMBUS_VOUT_OV_WARN_LIMIT)) { | ||
1039 | i1 = data->num_sensors; | ||
1040 | pmbus_add_sensor(data, "in", "max", in_index, page, | ||
1041 | PMBUS_VOUT_OV_WARN_LIMIT, | ||
1042 | PSC_VOLTAGE_OUT, false, false); | ||
1043 | if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { | ||
1044 | pmbus_add_boolean_reg(data, "in", "max_alarm", | ||
1045 | in_index, | ||
1046 | PB_STATUS_VOUT_BASE + | ||
1047 | page, | ||
1048 | PB_VOLTAGE_OV_WARNING); | ||
1049 | have_alarm = true; | ||
1050 | } | ||
1051 | } | ||
1052 | if (pmbus_check_word_register(client, page, | ||
1053 | PMBUS_VOUT_OV_FAULT_LIMIT)) { | ||
1054 | i1 = data->num_sensors; | ||
1055 | pmbus_add_sensor(data, "in", "crit", in_index, page, | ||
1056 | PMBUS_VOUT_OV_FAULT_LIMIT, | ||
1057 | PSC_VOLTAGE_OUT, false, false); | ||
1058 | if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) { | ||
1059 | pmbus_add_boolean_reg(data, "in", "crit_alarm", | ||
1060 | in_index, | ||
1061 | PB_STATUS_VOUT_BASE + | ||
1062 | page, | ||
1063 | PB_VOLTAGE_OV_FAULT); | ||
1064 | have_alarm = true; | ||
1065 | } | ||
1066 | } | ||
1067 | /* | 953 | /* |
1068 | * Add generic alarm attribute only if there are no individual | 954 | * Add generic alarm attribute only if there are no individual |
1069 | * attributes. | 955 | * alarm attributes, and if there is a global alarm bit. |
1070 | */ | 956 | */ |
1071 | if (!have_alarm) | 957 | if (!have_alarm && attr->gbit) |
1072 | pmbus_add_boolean_reg(data, "in", "alarm", | 958 | pmbus_add_boolean_reg(data, name, "alarm", index, |
1073 | in_index, | ||
1074 | PB_STATUS_BASE + page, | 959 | PB_STATUS_BASE + page, |
1075 | PB_STATUS_VOUT_OV); | 960 | attr->gbit); |
1076 | in_index++; | ||
1077 | } | 961 | } |
962 | } | ||
1078 | 963 | ||
1079 | /* | 964 | static void pmbus_add_sensor_attrs(struct i2c_client *client, |
1080 | * Current sensors | 965 | struct pmbus_data *data, |
1081 | */ | 966 | const char *name, |
967 | const struct pmbus_sensor_attr *attrs, | ||
968 | int nattrs) | ||
969 | { | ||
970 | const struct pmbus_driver_info *info = data->info; | ||
971 | int index, i; | ||
1082 | 972 | ||
1083 | /* | 973 | index = 1; |
1084 | * Input current sensors | 974 | for (i = 0; i < nattrs; i++) { |
1085 | */ | 975 | int page, pages; |
1086 | in_index = 1; | 976 | |
1087 | if (info->func[0] & PMBUS_HAVE_IIN) { | 977 | pages = attrs->paged ? info->pages : 1; |
1088 | i0 = data->num_sensors; | 978 | for (page = 0; page < pages; page++) { |
1089 | pmbus_add_label(data, "curr", in_index, "iin", 0); | 979 | if (!(info->func[page] & attrs->func)) |
1090 | pmbus_add_sensor(data, "curr", "input", in_index, 0, | 980 | continue; |
1091 | PMBUS_READ_IIN, PSC_CURRENT_IN, true, true); | 981 | pmbus_add_sensor_attrs_one(client, data, info, name, |
1092 | if (pmbus_check_word_register(client, 0, | 982 | index, page, attrs); |
1093 | PMBUS_IIN_OC_WARN_LIMIT)) { | 983 | index++; |
1094 | i1 = data->num_sensors; | ||
1095 | pmbus_add_sensor(data, "curr", "max", in_index, | ||
1096 | 0, PMBUS_IIN_OC_WARN_LIMIT, | ||
1097 | PSC_CURRENT_IN, false, false); | ||
1098 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { | ||
1099 | pmbus_add_boolean_reg(data, "curr", "max_alarm", | ||
1100 | in_index, | ||
1101 | PB_STATUS_INPUT_BASE, | ||
1102 | PB_IIN_OC_WARNING); | ||
1103 | } | ||
1104 | } | ||
1105 | if (pmbus_check_word_register(client, 0, | ||
1106 | PMBUS_IIN_OC_FAULT_LIMIT)) { | ||
1107 | i1 = data->num_sensors; | ||
1108 | pmbus_add_sensor(data, "curr", "crit", in_index, | ||
1109 | 0, PMBUS_IIN_OC_FAULT_LIMIT, | ||
1110 | PSC_CURRENT_IN, false, false); | ||
1111 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) | ||
1112 | pmbus_add_boolean_reg(data, "curr", | ||
1113 | "crit_alarm", | ||
1114 | in_index, | ||
1115 | PB_STATUS_INPUT_BASE, | ||
1116 | PB_IIN_OC_FAULT); | ||
1117 | } | 984 | } |
1118 | in_index++; | 985 | attrs++; |
1119 | } | 986 | } |
987 | } | ||
1120 | 988 | ||
1121 | /* | 989 | static const struct pmbus_limit_attr vin_limit_attrs[] = { |
1122 | * Output current sensors | 990 | { |
1123 | */ | 991 | .reg = PMBUS_VIN_UV_WARN_LIMIT, |
1124 | for (page = 0; page < info->pages; page++) { | 992 | .attr = "min", |
1125 | bool have_alarm = false; | 993 | .alarm = "min_alarm", |
1126 | 994 | .sbit = PB_VOLTAGE_UV_WARNING, | |
1127 | if (!(info->func[page] & PMBUS_HAVE_IOUT)) | 995 | }, { |
1128 | continue; | 996 | .reg = PMBUS_VIN_UV_FAULT_LIMIT, |
1129 | 997 | .attr = "lcrit", | |
1130 | i0 = data->num_sensors; | 998 | .alarm = "lcrit_alarm", |
1131 | pmbus_add_label(data, "curr", in_index, "iout", page + 1); | 999 | .sbit = PB_VOLTAGE_UV_FAULT, |
1132 | pmbus_add_sensor(data, "curr", "input", in_index, page, | 1000 | }, { |
1133 | PMBUS_READ_IOUT, PSC_CURRENT_OUT, true, true); | 1001 | .reg = PMBUS_VIN_OV_WARN_LIMIT, |
1134 | if (pmbus_check_word_register(client, page, | 1002 | .attr = "max", |
1135 | PMBUS_IOUT_OC_WARN_LIMIT)) { | 1003 | .alarm = "max_alarm", |
1136 | i1 = data->num_sensors; | 1004 | .sbit = PB_VOLTAGE_OV_WARNING, |
1137 | pmbus_add_sensor(data, "curr", "max", in_index, page, | 1005 | }, { |
1138 | PMBUS_IOUT_OC_WARN_LIMIT, | 1006 | .reg = PMBUS_VIN_OV_FAULT_LIMIT, |
1139 | PSC_CURRENT_OUT, false, false); | 1007 | .attr = "crit", |
1140 | if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { | 1008 | .alarm = "crit_alarm", |
1141 | pmbus_add_boolean_reg(data, "curr", "max_alarm", | 1009 | .sbit = PB_VOLTAGE_OV_FAULT, |
1142 | in_index, | 1010 | }, |
1143 | PB_STATUS_IOUT_BASE + | 1011 | }; |
1144 | page, PB_IOUT_OC_WARNING); | 1012 | |
1145 | have_alarm = true; | 1013 | static const struct pmbus_limit_attr vout_limit_attrs[] = { |
1146 | } | 1014 | { |
1147 | } | 1015 | .reg = PMBUS_VOUT_UV_WARN_LIMIT, |
1148 | if (pmbus_check_word_register(client, page, | 1016 | .attr = "min", |
1149 | PMBUS_IOUT_UC_FAULT_LIMIT)) { | 1017 | .alarm = "min_alarm", |
1150 | i1 = data->num_sensors; | 1018 | .sbit = PB_VOLTAGE_UV_WARNING, |
1151 | pmbus_add_sensor(data, "curr", "lcrit", in_index, page, | 1019 | }, { |
1152 | PMBUS_IOUT_UC_FAULT_LIMIT, | 1020 | .reg = PMBUS_VOUT_UV_FAULT_LIMIT, |
1153 | PSC_CURRENT_OUT, false, false); | 1021 | .attr = "lcrit", |
1154 | if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { | 1022 | .alarm = "lcrit_alarm", |
1155 | pmbus_add_boolean_reg(data, "curr", | 1023 | .sbit = PB_VOLTAGE_UV_FAULT, |
1156 | "lcrit_alarm", | 1024 | }, { |
1157 | in_index, | 1025 | .reg = PMBUS_VOUT_OV_WARN_LIMIT, |
1158 | PB_STATUS_IOUT_BASE + | 1026 | .attr = "max", |
1159 | page, PB_IOUT_UC_FAULT); | 1027 | .alarm = "max_alarm", |
1160 | have_alarm = true; | 1028 | .sbit = PB_VOLTAGE_OV_WARNING, |
1161 | } | 1029 | }, { |
1162 | } | 1030 | .reg = PMBUS_VOUT_OV_FAULT_LIMIT, |
1163 | if (pmbus_check_word_register(client, page, | 1031 | .attr = "crit", |
1164 | PMBUS_IOUT_OC_FAULT_LIMIT)) { | 1032 | .alarm = "crit_alarm", |
1165 | i1 = data->num_sensors; | 1033 | .sbit = PB_VOLTAGE_OV_FAULT, |
1166 | pmbus_add_sensor(data, "curr", "crit", in_index, page, | ||
1167 | PMBUS_IOUT_OC_FAULT_LIMIT, | ||
1168 | PSC_CURRENT_OUT, false, false); | ||
1169 | if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { | ||
1170 | pmbus_add_boolean_reg(data, "curr", | ||
1171 | "crit_alarm", | ||
1172 | in_index, | ||
1173 | PB_STATUS_IOUT_BASE + | ||
1174 | page, PB_IOUT_OC_FAULT); | ||
1175 | have_alarm = true; | ||
1176 | } | ||
1177 | } | ||
1178 | /* | ||
1179 | * Add generic alarm attribute only if there are no individual | ||
1180 | * attributes. | ||
1181 | */ | ||
1182 | if (!have_alarm) | ||
1183 | pmbus_add_boolean_reg(data, "curr", "alarm", | ||
1184 | in_index, | ||
1185 | PB_STATUS_BASE + page, | ||
1186 | PB_STATUS_IOUT_OC); | ||
1187 | in_index++; | ||
1188 | } | 1034 | } |
1035 | }; | ||
1189 | 1036 | ||
1190 | /* | 1037 | static const struct pmbus_sensor_attr voltage_attributes[] = { |
1191 | * Power sensors | 1038 | { |
1192 | */ | 1039 | .reg = PMBUS_READ_VIN, |
1193 | /* | 1040 | .class = PSC_VOLTAGE_IN, |
1194 | * Input Power sensors | 1041 | .label = "vin", |
1195 | */ | 1042 | .func = PMBUS_HAVE_VIN, |
1196 | in_index = 1; | 1043 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1197 | if (info->func[0] & PMBUS_HAVE_PIN) { | 1044 | .sbase = PB_STATUS_INPUT_BASE, |
1198 | i0 = data->num_sensors; | 1045 | .gbit = PB_STATUS_VIN_UV, |
1199 | pmbus_add_label(data, "power", in_index, "pin", 0); | 1046 | .limit = vin_limit_attrs, |
1200 | pmbus_add_sensor(data, "power", "input", in_index, | 1047 | .nlimit = ARRAY_SIZE(vin_limit_attrs), |
1201 | 0, PMBUS_READ_PIN, PSC_POWER, true, true); | 1048 | }, { |
1202 | if (pmbus_check_word_register(client, 0, | 1049 | .reg = PMBUS_READ_VCAP, |
1203 | PMBUS_PIN_OP_WARN_LIMIT)) { | 1050 | .class = PSC_VOLTAGE_IN, |
1204 | i1 = data->num_sensors; | 1051 | .label = "vcap", |
1205 | pmbus_add_sensor(data, "power", "max", in_index, | 1052 | .func = PMBUS_HAVE_VCAP, |
1206 | 0, PMBUS_PIN_OP_WARN_LIMIT, PSC_POWER, | 1053 | }, { |
1207 | false, false); | 1054 | .reg = PMBUS_READ_VOUT, |
1208 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) | 1055 | .class = PSC_VOLTAGE_OUT, |
1209 | pmbus_add_boolean_reg(data, "power", | 1056 | .label = "vout", |
1210 | "alarm", | 1057 | .paged = true, |
1211 | in_index, | 1058 | .func = PMBUS_HAVE_VOUT, |
1212 | PB_STATUS_INPUT_BASE, | 1059 | .sfunc = PMBUS_HAVE_STATUS_VOUT, |
1213 | PB_PIN_OP_WARNING); | 1060 | .sbase = PB_STATUS_VOUT_BASE, |
1214 | } | 1061 | .gbit = PB_STATUS_VOUT_OV, |
1215 | in_index++; | 1062 | .limit = vout_limit_attrs, |
1063 | .nlimit = ARRAY_SIZE(vout_limit_attrs), | ||
1216 | } | 1064 | } |
1065 | }; | ||
1217 | 1066 | ||
1218 | /* | 1067 | /* Current attributes */ |
1219 | * Output Power sensors | 1068 | |
1220 | */ | 1069 | static const struct pmbus_limit_attr iin_limit_attrs[] = { |
1221 | for (page = 0; page < info->pages; page++) { | 1070 | { |
1222 | bool need_alarm = false; | 1071 | .reg = PMBUS_IIN_OC_WARN_LIMIT, |
1072 | .attr = "max", | ||
1073 | .alarm = "max_alarm", | ||
1074 | .sbit = PB_IIN_OC_WARNING, | ||
1075 | }, { | ||
1076 | .reg = PMBUS_IIN_OC_FAULT_LIMIT, | ||
1077 | .attr = "crit", | ||
1078 | .alarm = "crit_alarm", | ||
1079 | .sbit = PB_IIN_OC_FAULT, | ||
1080 | } | ||
1081 | }; | ||
1223 | 1082 | ||
1224 | if (!(info->func[page] & PMBUS_HAVE_POUT)) | 1083 | static const struct pmbus_limit_attr iout_limit_attrs[] = { |
1225 | continue; | 1084 | { |
1085 | .reg = PMBUS_IOUT_OC_WARN_LIMIT, | ||
1086 | .attr = "max", | ||
1087 | .alarm = "max_alarm", | ||
1088 | .sbit = PB_IOUT_OC_WARNING, | ||
1089 | }, { | ||
1090 | .reg = PMBUS_IOUT_UC_FAULT_LIMIT, | ||
1091 | .attr = "lcrit", | ||
1092 | .alarm = "lcrit_alarm", | ||
1093 | .sbit = PB_IOUT_UC_FAULT, | ||
1094 | }, { | ||
1095 | .reg = PMBUS_IOUT_OC_FAULT_LIMIT, | ||
1096 | .attr = "crit", | ||
1097 | .alarm = "crit_alarm", | ||
1098 | .sbit = PB_IOUT_OC_FAULT, | ||
1099 | } | ||
1100 | }; | ||
1226 | 1101 | ||
1227 | i0 = data->num_sensors; | 1102 | static const struct pmbus_sensor_attr current_attributes[] = { |
1228 | pmbus_add_label(data, "power", in_index, "pout", page + 1); | 1103 | { |
1229 | pmbus_add_sensor(data, "power", "input", in_index, page, | 1104 | .reg = PMBUS_READ_IIN, |
1230 | PMBUS_READ_POUT, PSC_POWER, true, true); | 1105 | .class = PSC_CURRENT_IN, |
1231 | /* | 1106 | .label = "iin", |
1232 | * Per hwmon sysfs API, power_cap is to be used to limit output | 1107 | .func = PMBUS_HAVE_IIN, |
1233 | * power. | 1108 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1234 | * We have two registers related to maximum output power, | 1109 | .sbase = PB_STATUS_INPUT_BASE, |
1235 | * PMBUS_POUT_MAX and PMBUS_POUT_OP_WARN_LIMIT. | 1110 | .limit = iin_limit_attrs, |
1236 | * PMBUS_POUT_MAX matches the powerX_cap attribute definition. | 1111 | .nlimit = ARRAY_SIZE(iin_limit_attrs), |
1237 | * There is no attribute in the API to match | 1112 | }, { |
1238 | * PMBUS_POUT_OP_WARN_LIMIT. We use powerX_max for now. | 1113 | .reg = PMBUS_READ_IOUT, |
1239 | */ | 1114 | .class = PSC_CURRENT_OUT, |
1240 | if (pmbus_check_word_register(client, page, PMBUS_POUT_MAX)) { | 1115 | .label = "iout", |
1241 | i1 = data->num_sensors; | 1116 | .paged = true, |
1242 | pmbus_add_sensor(data, "power", "cap", in_index, page, | 1117 | .func = PMBUS_HAVE_IOUT, |
1243 | PMBUS_POUT_MAX, PSC_POWER, | 1118 | .sfunc = PMBUS_HAVE_STATUS_IOUT, |
1244 | false, false); | 1119 | .sbase = PB_STATUS_IOUT_BASE, |
1245 | need_alarm = true; | 1120 | .gbit = PB_STATUS_IOUT_OC, |
1246 | } | 1121 | .limit = iout_limit_attrs, |
1247 | if (pmbus_check_word_register(client, page, | 1122 | .nlimit = ARRAY_SIZE(iout_limit_attrs), |
1248 | PMBUS_POUT_OP_WARN_LIMIT)) { | ||
1249 | i1 = data->num_sensors; | ||
1250 | pmbus_add_sensor(data, "power", "max", in_index, page, | ||
1251 | PMBUS_POUT_OP_WARN_LIMIT, PSC_POWER, | ||
1252 | false, false); | ||
1253 | need_alarm = true; | ||
1254 | } | ||
1255 | if (need_alarm && (info->func[page] & PMBUS_HAVE_STATUS_IOUT)) | ||
1256 | pmbus_add_boolean_reg(data, "power", "alarm", | ||
1257 | in_index, | ||
1258 | PB_STATUS_IOUT_BASE + page, | ||
1259 | PB_POUT_OP_WARNING | ||
1260 | | PB_POWER_LIMITING); | ||
1261 | |||
1262 | if (pmbus_check_word_register(client, page, | ||
1263 | PMBUS_POUT_OP_FAULT_LIMIT)) { | ||
1264 | i1 = data->num_sensors; | ||
1265 | pmbus_add_sensor(data, "power", "crit", in_index, page, | ||
1266 | PMBUS_POUT_OP_FAULT_LIMIT, PSC_POWER, | ||
1267 | false, false); | ||
1268 | if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) | ||
1269 | pmbus_add_boolean_reg(data, "power", | ||
1270 | "crit_alarm", | ||
1271 | in_index, | ||
1272 | PB_STATUS_IOUT_BASE | ||
1273 | + page, | ||
1274 | PB_POUT_OP_FAULT); | ||
1275 | } | ||
1276 | in_index++; | ||
1277 | } | 1123 | } |
1124 | }; | ||
1278 | 1125 | ||
1279 | /* | 1126 | /* Power attributes */ |
1280 | * Temperature sensors | ||
1281 | */ | ||
1282 | in_index = 1; | ||
1283 | for (page = 0; page < info->pages; page++) { | ||
1284 | int t; | ||
1285 | 1127 | ||
1286 | for (t = 0; t < ARRAY_SIZE(pmbus_temp_registers); t++) { | 1128 | static const struct pmbus_limit_attr pin_limit_attrs[] = { |
1287 | bool have_alarm = false; | 1129 | { |
1130 | .reg = PMBUS_PIN_OP_WARN_LIMIT, | ||
1131 | .attr = "max", | ||
1132 | .alarm = "alarm", | ||
1133 | .sbit = PB_PIN_OP_WARNING, | ||
1134 | } | ||
1135 | }; | ||
1288 | 1136 | ||
1289 | /* | 1137 | static const struct pmbus_limit_attr pout_limit_attrs[] = { |
1290 | * A PMBus chip may support any combination of | 1138 | { |
1291 | * temperature registers on any page. So we can not | 1139 | .reg = PMBUS_POUT_MAX, |
1292 | * abort after a failure to detect a register, but have | 1140 | .attr = "cap", |
1293 | * to continue checking for all registers on all pages. | 1141 | .alarm = "cap_alarm", |
1294 | */ | 1142 | .sbit = PB_POWER_LIMITING, |
1295 | if (!(info->func[page] & pmbus_temp_flags[t])) | 1143 | }, { |
1296 | continue; | 1144 | .reg = PMBUS_POUT_OP_WARN_LIMIT, |
1145 | .attr = "max", | ||
1146 | .alarm = "max_alarm", | ||
1147 | .sbit = PB_POUT_OP_WARNING, | ||
1148 | }, { | ||
1149 | .reg = PMBUS_POUT_OP_FAULT_LIMIT, | ||
1150 | .attr = "crit", | ||
1151 | .alarm = "crit_alarm", | ||
1152 | .sbit = PB_POUT_OP_FAULT, | ||
1153 | } | ||
1154 | }; | ||
1297 | 1155 | ||
1298 | if (!pmbus_check_word_register | 1156 | static const struct pmbus_sensor_attr power_attributes[] = { |
1299 | (client, page, pmbus_temp_registers[t])) | 1157 | { |
1300 | continue; | 1158 | .reg = PMBUS_READ_PIN, |
1159 | .class = PSC_POWER, | ||
1160 | .label = "pin", | ||
1161 | .func = PMBUS_HAVE_PIN, | ||
1162 | .sfunc = PMBUS_HAVE_STATUS_INPUT, | ||
1163 | .sbase = PB_STATUS_INPUT_BASE, | ||
1164 | .limit = pin_limit_attrs, | ||
1165 | .nlimit = ARRAY_SIZE(pin_limit_attrs), | ||
1166 | }, { | ||
1167 | .reg = PMBUS_READ_POUT, | ||
1168 | .class = PSC_POWER, | ||
1169 | .label = "pout", | ||
1170 | .paged = true, | ||
1171 | .func = PMBUS_HAVE_POUT, | ||
1172 | .sfunc = PMBUS_HAVE_STATUS_IOUT, | ||
1173 | .sbase = PB_STATUS_IOUT_BASE, | ||
1174 | .limit = pout_limit_attrs, | ||
1175 | .nlimit = ARRAY_SIZE(pout_limit_attrs), | ||
1176 | } | ||
1177 | }; | ||
1301 | 1178 | ||
1302 | i0 = data->num_sensors; | 1179 | /* Temperature atributes */ |
1303 | pmbus_add_sensor(data, "temp", "input", in_index, page, | 1180 | |
1304 | pmbus_temp_registers[t], | 1181 | static const struct pmbus_limit_attr temp_limit_attrs[] = { |
1305 | PSC_TEMPERATURE, true, true); | 1182 | { |
1183 | .reg = PMBUS_UT_WARN_LIMIT, | ||
1184 | .attr = "min", | ||
1185 | .alarm = "min_alarm", | ||
1186 | .sbit = PB_TEMP_UT_WARNING, | ||
1187 | }, { | ||
1188 | .reg = PMBUS_UT_FAULT_LIMIT, | ||
1189 | .attr = "lcrit", | ||
1190 | .alarm = "lcrit_alarm", | ||
1191 | .sbit = PB_TEMP_UT_FAULT, | ||
1192 | }, { | ||
1193 | .reg = PMBUS_OT_WARN_LIMIT, | ||
1194 | .attr = "max", | ||
1195 | .alarm = "max_alarm", | ||
1196 | .sbit = PB_TEMP_OT_WARNING, | ||
1197 | }, { | ||
1198 | .reg = PMBUS_OT_FAULT_LIMIT, | ||
1199 | .attr = "crit", | ||
1200 | .alarm = "crit_alarm", | ||
1201 | .sbit = PB_TEMP_OT_FAULT, | ||
1202 | } | ||
1203 | }; | ||
1306 | 1204 | ||
1307 | /* | 1205 | static const struct pmbus_sensor_attr temp_attributes[] = { |
1308 | * PMBus provides only one status register for TEMP1-3. | 1206 | { |
1309 | * Thus, we can not use the status register to determine | 1207 | .reg = PMBUS_READ_TEMPERATURE_1, |
1310 | * which of the three sensors actually caused an alarm. | 1208 | .class = PSC_TEMPERATURE, |
1311 | * Always compare current temperature against the limit | 1209 | .paged = true, |
1312 | * registers to determine alarm conditions for a | 1210 | .update = true, |
1313 | * specific sensor. | 1211 | .compare = true, |
1314 | * | 1212 | .func = PMBUS_HAVE_TEMP, |
1315 | * Since there is only one set of limit registers for | 1213 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1316 | * up to three temperature sensors, we need to update | 1214 | .sbase = PB_STATUS_TEMP_BASE, |
1317 | * all limit registers after the limit was changed for | 1215 | .gbit = PB_STATUS_TEMPERATURE, |
1318 | * one of the sensors. This ensures that correct limits | 1216 | .limit = temp_limit_attrs, |
1319 | * are reported for all temperature sensors. | 1217 | .nlimit = ARRAY_SIZE(temp_limit_attrs), |
1320 | */ | 1218 | }, { |
1321 | if (pmbus_check_word_register | 1219 | .reg = PMBUS_READ_TEMPERATURE_2, |
1322 | (client, page, PMBUS_UT_WARN_LIMIT)) { | 1220 | .class = PSC_TEMPERATURE, |
1323 | i1 = data->num_sensors; | 1221 | .paged = true, |
1324 | pmbus_add_sensor(data, "temp", "min", in_index, | 1222 | .update = true, |
1325 | page, PMBUS_UT_WARN_LIMIT, | 1223 | .compare = true, |
1326 | PSC_TEMPERATURE, true, false); | 1224 | .func = PMBUS_HAVE_TEMP2, |
1327 | if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { | 1225 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1328 | pmbus_add_boolean_cmp(data, "temp", | 1226 | .sbase = PB_STATUS_TEMP_BASE, |
1329 | "min_alarm", in_index, i1, i0, | 1227 | .gbit = PB_STATUS_TEMPERATURE, |
1330 | PB_STATUS_TEMP_BASE + page, | 1228 | .limit = temp_limit_attrs, |
1331 | PB_TEMP_UT_WARNING); | 1229 | .nlimit = ARRAY_SIZE(temp_limit_attrs), |
1332 | have_alarm = true; | 1230 | }, { |
1333 | } | 1231 | .reg = PMBUS_READ_TEMPERATURE_3, |
1334 | } | 1232 | .class = PSC_TEMPERATURE, |
1335 | if (pmbus_check_word_register(client, page, | 1233 | .paged = true, |
1336 | PMBUS_UT_FAULT_LIMIT)) { | 1234 | .update = true, |
1337 | i1 = data->num_sensors; | 1235 | .compare = true, |
1338 | pmbus_add_sensor(data, "temp", "lcrit", | 1236 | .func = PMBUS_HAVE_TEMP3, |
1339 | in_index, page, | 1237 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1340 | PMBUS_UT_FAULT_LIMIT, | 1238 | .sbase = PB_STATUS_TEMP_BASE, |
1341 | PSC_TEMPERATURE, true, false); | 1239 | .gbit = PB_STATUS_TEMPERATURE, |
1342 | if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { | 1240 | .limit = temp_limit_attrs, |
1343 | pmbus_add_boolean_cmp(data, "temp", | 1241 | .nlimit = ARRAY_SIZE(temp_limit_attrs), |
1344 | "lcrit_alarm", in_index, i1, i0, | ||
1345 | PB_STATUS_TEMP_BASE + page, | ||
1346 | PB_TEMP_UT_FAULT); | ||
1347 | have_alarm = true; | ||
1348 | } | ||
1349 | } | ||
1350 | if (pmbus_check_word_register | ||
1351 | (client, page, PMBUS_OT_WARN_LIMIT)) { | ||
1352 | i1 = data->num_sensors; | ||
1353 | pmbus_add_sensor(data, "temp", "max", in_index, | ||
1354 | page, PMBUS_OT_WARN_LIMIT, | ||
1355 | PSC_TEMPERATURE, true, false); | ||
1356 | if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { | ||
1357 | pmbus_add_boolean_cmp(data, "temp", | ||
1358 | "max_alarm", in_index, i0, i1, | ||
1359 | PB_STATUS_TEMP_BASE + page, | ||
1360 | PB_TEMP_OT_WARNING); | ||
1361 | have_alarm = true; | ||
1362 | } | ||
1363 | } | ||
1364 | if (pmbus_check_word_register(client, page, | ||
1365 | PMBUS_OT_FAULT_LIMIT)) { | ||
1366 | i1 = data->num_sensors; | ||
1367 | pmbus_add_sensor(data, "temp", "crit", in_index, | ||
1368 | page, PMBUS_OT_FAULT_LIMIT, | ||
1369 | PSC_TEMPERATURE, true, false); | ||
1370 | if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { | ||
1371 | pmbus_add_boolean_cmp(data, "temp", | ||
1372 | "crit_alarm", in_index, i0, i1, | ||
1373 | PB_STATUS_TEMP_BASE + page, | ||
1374 | PB_TEMP_OT_FAULT); | ||
1375 | have_alarm = true; | ||
1376 | } | ||
1377 | } | ||
1378 | /* | ||
1379 | * Last resort - we were not able to create any alarm | ||
1380 | * registers. Report alarm for all sensors using the | ||
1381 | * status register temperature alarm bit. | ||
1382 | */ | ||
1383 | if (!have_alarm) | ||
1384 | pmbus_add_boolean_reg(data, "temp", "alarm", | ||
1385 | in_index, | ||
1386 | PB_STATUS_BASE + page, | ||
1387 | PB_STATUS_TEMPERATURE); | ||
1388 | in_index++; | ||
1389 | } | ||
1390 | } | 1242 | } |
1243 | }; | ||
1244 | |||
1245 | static const int pmbus_fan_registers[] = { | ||
1246 | PMBUS_READ_FAN_SPEED_1, | ||
1247 | PMBUS_READ_FAN_SPEED_2, | ||
1248 | PMBUS_READ_FAN_SPEED_3, | ||
1249 | PMBUS_READ_FAN_SPEED_4 | ||
1250 | }; | ||
1251 | |||
1252 | static const int pmbus_fan_config_registers[] = { | ||
1253 | PMBUS_FAN_CONFIG_12, | ||
1254 | PMBUS_FAN_CONFIG_12, | ||
1255 | PMBUS_FAN_CONFIG_34, | ||
1256 | PMBUS_FAN_CONFIG_34 | ||
1257 | }; | ||
1258 | |||
1259 | static const int pmbus_fan_status_registers[] = { | ||
1260 | PMBUS_STATUS_FAN_12, | ||
1261 | PMBUS_STATUS_FAN_12, | ||
1262 | PMBUS_STATUS_FAN_34, | ||
1263 | PMBUS_STATUS_FAN_34 | ||
1264 | }; | ||
1265 | |||
1266 | static const u32 pmbus_fan_flags[] = { | ||
1267 | PMBUS_HAVE_FAN12, | ||
1268 | PMBUS_HAVE_FAN12, | ||
1269 | PMBUS_HAVE_FAN34, | ||
1270 | PMBUS_HAVE_FAN34 | ||
1271 | }; | ||
1272 | |||
1273 | static const u32 pmbus_fan_status_flags[] = { | ||
1274 | PMBUS_HAVE_STATUS_FAN12, | ||
1275 | PMBUS_HAVE_STATUS_FAN12, | ||
1276 | PMBUS_HAVE_STATUS_FAN34, | ||
1277 | PMBUS_HAVE_STATUS_FAN34 | ||
1278 | }; | ||
1279 | |||
1280 | /* Fans */ | ||
1281 | static void pmbus_add_fan_attributes(struct i2c_client *client, | ||
1282 | struct pmbus_data *data) | ||
1283 | { | ||
1284 | const struct pmbus_driver_info *info = data->info; | ||
1285 | int index = 1; | ||
1286 | int page; | ||
1391 | 1287 | ||
1392 | /* | ||
1393 | * Fans | ||
1394 | */ | ||
1395 | in_index = 1; | ||
1396 | for (page = 0; page < info->pages; page++) { | 1288 | for (page = 0; page < info->pages; page++) { |
1397 | int f; | 1289 | int f; |
1398 | 1290 | ||
@@ -1403,9 +1295,7 @@ static void pmbus_find_attributes(struct i2c_client *client, | |||
1403 | break; | 1295 | break; |
1404 | 1296 | ||
1405 | if (!pmbus_check_word_register(client, page, | 1297 | if (!pmbus_check_word_register(client, page, |
1406 | pmbus_fan_registers[f]) | 1298 | pmbus_fan_registers[f])) |
1407 | || !pmbus_check_byte_register(client, page, | ||
1408 | pmbus_fan_config_registers[f])) | ||
1409 | break; | 1299 | break; |
1410 | 1300 | ||
1411 | /* | 1301 | /* |
@@ -1413,14 +1303,13 @@ static void pmbus_find_attributes(struct i2c_client *client, | |||
1413 | * Each fan configuration register covers multiple fans, | 1303 | * Each fan configuration register covers multiple fans, |
1414 | * so we have to do some magic. | 1304 | * so we have to do some magic. |
1415 | */ | 1305 | */ |
1416 | regval = pmbus_read_byte_data(client, page, | 1306 | regval = _pmbus_read_byte_data(client, page, |
1417 | pmbus_fan_config_registers[f]); | 1307 | pmbus_fan_config_registers[f]); |
1418 | if (regval < 0 || | 1308 | if (regval < 0 || |
1419 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) | 1309 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) |
1420 | continue; | 1310 | continue; |
1421 | 1311 | ||
1422 | i0 = data->num_sensors; | 1312 | pmbus_add_sensor(data, "fan", "input", index, page, |
1423 | pmbus_add_sensor(data, "fan", "input", in_index, page, | ||
1424 | pmbus_fan_registers[f], PSC_FAN, true, | 1313 | pmbus_fan_registers[f], PSC_FAN, true, |
1425 | true); | 1314 | true); |
1426 | 1315 | ||
@@ -1438,17 +1327,40 @@ static void pmbus_find_attributes(struct i2c_client *client, | |||
1438 | else | 1327 | else |
1439 | base = PB_STATUS_FAN_BASE + page; | 1328 | base = PB_STATUS_FAN_BASE + page; |
1440 | pmbus_add_boolean_reg(data, "fan", "alarm", | 1329 | pmbus_add_boolean_reg(data, "fan", "alarm", |
1441 | in_index, base, | 1330 | index, base, |
1442 | PB_FAN_FAN1_WARNING >> (f & 1)); | 1331 | PB_FAN_FAN1_WARNING >> (f & 1)); |
1443 | pmbus_add_boolean_reg(data, "fan", "fault", | 1332 | pmbus_add_boolean_reg(data, "fan", "fault", |
1444 | in_index, base, | 1333 | index, base, |
1445 | PB_FAN_FAN1_FAULT >> (f & 1)); | 1334 | PB_FAN_FAN1_FAULT >> (f & 1)); |
1446 | } | 1335 | } |
1447 | in_index++; | 1336 | index++; |
1448 | } | 1337 | } |
1449 | } | 1338 | } |
1450 | } | 1339 | } |
1451 | 1340 | ||
1341 | static void pmbus_find_attributes(struct i2c_client *client, | ||
1342 | struct pmbus_data *data) | ||
1343 | { | ||
1344 | /* Voltage sensors */ | ||
1345 | pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, | ||
1346 | ARRAY_SIZE(voltage_attributes)); | ||
1347 | |||
1348 | /* Current sensors */ | ||
1349 | pmbus_add_sensor_attrs(client, data, "curr", current_attributes, | ||
1350 | ARRAY_SIZE(current_attributes)); | ||
1351 | |||
1352 | /* Power sensors */ | ||
1353 | pmbus_add_sensor_attrs(client, data, "power", power_attributes, | ||
1354 | ARRAY_SIZE(power_attributes)); | ||
1355 | |||
1356 | /* Temperature sensors */ | ||
1357 | pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, | ||
1358 | ARRAY_SIZE(temp_attributes)); | ||
1359 | |||
1360 | /* Fans */ | ||
1361 | pmbus_add_fan_attributes(client, data); | ||
1362 | } | ||
1363 | |||
1452 | /* | 1364 | /* |
1453 | * Identify chip parameters. | 1365 | * Identify chip parameters. |
1454 | * This function is called for all chips. | 1366 | * This function is called for all chips. |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index f4e617adb220..cf4330b352ef 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
@@ -1,6 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * sht15.c - support for the SHT15 Temperature and Humidity Sensor | 2 | * sht15.c - support for the SHT15 Temperature and Humidity Sensor |
3 | * | 3 | * |
4 | * Portions Copyright (c) 2010-2011 Savoir-faire Linux Inc. | ||
5 | * Jerome Oufella <jerome.oufella@savoirfairelinux.com> | ||
6 | * Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
7 | * | ||
4 | * Copyright (c) 2009 Jonathan Cameron | 8 | * Copyright (c) 2009 Jonathan Cameron |
5 | * | 9 | * |
6 | * Copyright (c) 2007 Wouter Horre | 10 | * Copyright (c) 2007 Wouter Horre |
@@ -9,16 +13,7 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
11 | * | 15 | * |
12 | * Currently ignoring checksum on readings. | 16 | * For further information, see the Documentation/hwmon/sht15 file. |
13 | * Default resolution only (14bit temp, 12bit humidity) | ||
14 | * Ignoring battery status. | ||
15 | * Heater not enabled. | ||
16 | * Timings are all conservative. | ||
17 | * | ||
18 | * Data sheet available (1/2009) at | ||
19 | * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf | ||
20 | * | ||
21 | * Regulator supply name = vcc | ||
22 | */ | 17 | */ |
23 | 18 | ||
24 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
@@ -39,17 +34,31 @@ | |||
39 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
40 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
41 | 36 | ||
42 | #define SHT15_MEASURE_TEMP 3 | 37 | /* Commands */ |
43 | #define SHT15_MEASURE_RH 5 | 38 | #define SHT15_MEASURE_TEMP 0x03 |
44 | 39 | #define SHT15_MEASURE_RH 0x05 | |
45 | #define SHT15_READING_NOTHING 0 | 40 | #define SHT15_WRITE_STATUS 0x06 |
46 | #define SHT15_READING_TEMP 1 | 41 | #define SHT15_READ_STATUS 0x07 |
47 | #define SHT15_READING_HUMID 2 | 42 | #define SHT15_SOFT_RESET 0x1E |
48 | 43 | ||
49 | /* Min timings in nsecs */ | 44 | /* Min timings */ |
50 | #define SHT15_TSCKL 100 /* clock low */ | 45 | #define SHT15_TSCKL 100 /* (nsecs) clock low */ |
51 | #define SHT15_TSCKH 100 /* clock high */ | 46 | #define SHT15_TSCKH 100 /* (nsecs) clock high */ |
52 | #define SHT15_TSU 150 /* data setup time */ | 47 | #define SHT15_TSU 150 /* (nsecs) data setup time */ |
48 | #define SHT15_TSRST 11 /* (msecs) soft reset time */ | ||
49 | |||
50 | /* Status Register Bits */ | ||
51 | #define SHT15_STATUS_LOW_RESOLUTION 0x01 | ||
52 | #define SHT15_STATUS_NO_OTP_RELOAD 0x02 | ||
53 | #define SHT15_STATUS_HEATER 0x04 | ||
54 | #define SHT15_STATUS_LOW_BATTERY 0x40 | ||
55 | |||
56 | /* Actions the driver may be doing */ | ||
57 | enum sht15_state { | ||
58 | SHT15_READING_NOTHING, | ||
59 | SHT15_READING_TEMP, | ||
60 | SHT15_READING_HUMID | ||
61 | }; | ||
53 | 62 | ||
54 | /** | 63 | /** |
55 | * struct sht15_temppair - elements of voltage dependent temp calc | 64 | * struct sht15_temppair - elements of voltage dependent temp calc |
@@ -61,9 +70,7 @@ struct sht15_temppair { | |||
61 | int d1; | 70 | int d1; |
62 | }; | 71 | }; |
63 | 72 | ||
64 | /* Table 9 from data sheet - relates temperature calculation | 73 | /* Table 9 from datasheet - relates temperature calculation to supply voltage */ |
65 | * to supply voltage. | ||
66 | */ | ||
67 | static const struct sht15_temppair temppoints[] = { | 74 | static const struct sht15_temppair temppoints[] = { |
68 | { 2500000, -39400 }, | 75 | { 2500000, -39400 }, |
69 | { 3000000, -39600 }, | 76 | { 3000000, -39600 }, |
@@ -72,29 +79,70 @@ static const struct sht15_temppair temppoints[] = { | |||
72 | { 5000000, -40100 }, | 79 | { 5000000, -40100 }, |
73 | }; | 80 | }; |
74 | 81 | ||
82 | /* Table from CRC datasheet, section 2.4 */ | ||
83 | static const u8 sht15_crc8_table[] = { | ||
84 | 0, 49, 98, 83, 196, 245, 166, 151, | ||
85 | 185, 136, 219, 234, 125, 76, 31, 46, | ||
86 | 67, 114, 33, 16, 135, 182, 229, 212, | ||
87 | 250, 203, 152, 169, 62, 15, 92, 109, | ||
88 | 134, 183, 228, 213, 66, 115, 32, 17, | ||
89 | 63, 14, 93, 108, 251, 202, 153, 168, | ||
90 | 197, 244, 167, 150, 1, 48, 99, 82, | ||
91 | 124, 77, 30, 47, 184, 137, 218, 235, | ||
92 | 61, 12, 95, 110, 249, 200, 155, 170, | ||
93 | 132, 181, 230, 215, 64, 113, 34, 19, | ||
94 | 126, 79, 28, 45, 186, 139, 216, 233, | ||
95 | 199, 246, 165, 148, 3, 50, 97, 80, | ||
96 | 187, 138, 217, 232, 127, 78, 29, 44, | ||
97 | 2, 51, 96, 81, 198, 247, 164, 149, | ||
98 | 248, 201, 154, 171, 60, 13, 94, 111, | ||
99 | 65, 112, 35, 18, 133, 180, 231, 214, | ||
100 | 122, 75, 24, 41, 190, 143, 220, 237, | ||
101 | 195, 242, 161, 144, 7, 54, 101, 84, | ||
102 | 57, 8, 91, 106, 253, 204, 159, 174, | ||
103 | 128, 177, 226, 211, 68, 117, 38, 23, | ||
104 | 252, 205, 158, 175, 56, 9, 90, 107, | ||
105 | 69, 116, 39, 22, 129, 176, 227, 210, | ||
106 | 191, 142, 221, 236, 123, 74, 25, 40, | ||
107 | 6, 55, 100, 85, 194, 243, 160, 145, | ||
108 | 71, 118, 37, 20, 131, 178, 225, 208, | ||
109 | 254, 207, 156, 173, 58, 11, 88, 105, | ||
110 | 4, 53, 102, 87, 192, 241, 162, 147, | ||
111 | 189, 140, 223, 238, 121, 72, 27, 42, | ||
112 | 193, 240, 163, 146, 5, 52, 103, 86, | ||
113 | 120, 73, 26, 43, 188, 141, 222, 239, | ||
114 | 130, 179, 224, 209, 70, 119, 36, 21, | ||
115 | 59, 10, 89, 104, 255, 206, 157, 172 | ||
116 | }; | ||
117 | |||
75 | /** | 118 | /** |
76 | * struct sht15_data - device instance specific data | 119 | * struct sht15_data - device instance specific data |
77 | * @pdata: platform data (gpio's etc) | 120 | * @pdata: platform data (gpio's etc). |
78 | * @read_work: bh of interrupt handler | 121 | * @read_work: bh of interrupt handler. |
79 | * @wait_queue: wait queue for getting values from device | 122 | * @wait_queue: wait queue for getting values from device. |
80 | * @val_temp: last temperature value read from device | 123 | * @val_temp: last temperature value read from device. |
81 | * @val_humid: last humidity value read from device | 124 | * @val_humid: last humidity value read from device. |
82 | * @flag: status flag used to identify what the last request was | 125 | * @val_status: last status register value read from device. |
83 | * @valid: are the current stored values valid (start condition) | 126 | * @checksum_ok: last value read from the device passed CRC validation. |
84 | * @last_updat: time of last update | 127 | * @checksumming: flag used to enable the data validation with CRC. |
85 | * @read_lock: mutex to ensure only one read in progress | 128 | * @state: state identifying the action the driver is doing. |
86 | * at a time. | 129 | * @measurements_valid: are the current stored measures valid (start condition). |
87 | * @dev: associate device structure | 130 | * @status_valid: is the current stored status valid (start condition). |
88 | * @hwmon_dev: device associated with hwmon subsystem | 131 | * @last_measurement: time of last measure. |
89 | * @reg: associated regulator (if specified) | 132 | * @last_status: time of last status reading. |
90 | * @nb: notifier block to handle notifications of voltage changes | 133 | * @read_lock: mutex to ensure only one read in progress at a time. |
91 | * @supply_uV: local copy of supply voltage used to allow | 134 | * @dev: associate device structure. |
92 | * use of regulator consumer if available | 135 | * @hwmon_dev: device associated with hwmon subsystem. |
93 | * @supply_uV_valid: indicates that an updated value has not yet | 136 | * @reg: associated regulator (if specified). |
94 | * been obtained from the regulator and so any calculations | 137 | * @nb: notifier block to handle notifications of voltage |
95 | * based upon it will be invalid. | 138 | * changes. |
96 | * @update_supply_work: work struct that is used to update the supply_uV | 139 | * @supply_uV: local copy of supply voltage used to allow use of |
97 | * @interrupt_handled: flag used to indicate a hander has been scheduled | 140 | * regulator consumer if available. |
141 | * @supply_uV_valid: indicates that an updated value has not yet been | ||
142 | * obtained from the regulator and so any calculations | ||
143 | * based upon it will be invalid. | ||
144 | * @update_supply_work: work struct that is used to update the supply_uV. | ||
145 | * @interrupt_handled: flag used to indicate a handler has been scheduled. | ||
98 | */ | 146 | */ |
99 | struct sht15_data { | 147 | struct sht15_data { |
100 | struct sht15_platform_data *pdata; | 148 | struct sht15_platform_data *pdata; |
@@ -102,21 +150,60 @@ struct sht15_data { | |||
102 | wait_queue_head_t wait_queue; | 150 | wait_queue_head_t wait_queue; |
103 | uint16_t val_temp; | 151 | uint16_t val_temp; |
104 | uint16_t val_humid; | 152 | uint16_t val_humid; |
105 | u8 flag; | 153 | u8 val_status; |
106 | u8 valid; | 154 | bool checksum_ok; |
107 | unsigned long last_updat; | 155 | bool checksumming; |
156 | enum sht15_state state; | ||
157 | bool measurements_valid; | ||
158 | bool status_valid; | ||
159 | unsigned long last_measurement; | ||
160 | unsigned long last_status; | ||
108 | struct mutex read_lock; | 161 | struct mutex read_lock; |
109 | struct device *dev; | 162 | struct device *dev; |
110 | struct device *hwmon_dev; | 163 | struct device *hwmon_dev; |
111 | struct regulator *reg; | 164 | struct regulator *reg; |
112 | struct notifier_block nb; | 165 | struct notifier_block nb; |
113 | int supply_uV; | 166 | int supply_uV; |
114 | int supply_uV_valid; | 167 | bool supply_uV_valid; |
115 | struct work_struct update_supply_work; | 168 | struct work_struct update_supply_work; |
116 | atomic_t interrupt_handled; | 169 | atomic_t interrupt_handled; |
117 | }; | 170 | }; |
118 | 171 | ||
119 | /** | 172 | /** |
173 | * sht15_reverse() - reverse a byte | ||
174 | * @byte: byte to reverse. | ||
175 | */ | ||
176 | static u8 sht15_reverse(u8 byte) | ||
177 | { | ||
178 | u8 i, c; | ||
179 | |||
180 | for (c = 0, i = 0; i < 8; i++) | ||
181 | c |= (!!(byte & (1 << i))) << (7 - i); | ||
182 | return c; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * sht15_crc8() - compute crc8 | ||
187 | * @data: sht15 specific data. | ||
188 | * @value: sht15 retrieved data. | ||
189 | * | ||
190 | * This implements section 2 of the CRC datasheet. | ||
191 | */ | ||
192 | static u8 sht15_crc8(struct sht15_data *data, | ||
193 | const u8 *value, | ||
194 | int len) | ||
195 | { | ||
196 | u8 crc = sht15_reverse(data->val_status & 0x0F); | ||
197 | |||
198 | while (len--) { | ||
199 | crc = sht15_crc8_table[*value ^ crc]; | ||
200 | value++; | ||
201 | } | ||
202 | |||
203 | return crc; | ||
204 | } | ||
205 | |||
206 | /** | ||
120 | * sht15_connection_reset() - reset the comms interface | 207 | * sht15_connection_reset() - reset the comms interface |
121 | * @data: sht15 specific data | 208 | * @data: sht15 specific data |
122 | * | 209 | * |
@@ -125,6 +212,7 @@ struct sht15_data { | |||
125 | static void sht15_connection_reset(struct sht15_data *data) | 212 | static void sht15_connection_reset(struct sht15_data *data) |
126 | { | 213 | { |
127 | int i; | 214 | int i; |
215 | |||
128 | gpio_direction_output(data->pdata->gpio_data, 1); | 216 | gpio_direction_output(data->pdata->gpio_data, 1); |
129 | ndelay(SHT15_TSCKL); | 217 | ndelay(SHT15_TSCKL); |
130 | gpio_set_value(data->pdata->gpio_sck, 0); | 218 | gpio_set_value(data->pdata->gpio_sck, 0); |
@@ -136,14 +224,14 @@ static void sht15_connection_reset(struct sht15_data *data) | |||
136 | ndelay(SHT15_TSCKL); | 224 | ndelay(SHT15_TSCKL); |
137 | } | 225 | } |
138 | } | 226 | } |
227 | |||
139 | /** | 228 | /** |
140 | * sht15_send_bit() - send an individual bit to the device | 229 | * sht15_send_bit() - send an individual bit to the device |
141 | * @data: device state data | 230 | * @data: device state data |
142 | * @val: value of bit to be sent | 231 | * @val: value of bit to be sent |
143 | **/ | 232 | */ |
144 | static inline void sht15_send_bit(struct sht15_data *data, int val) | 233 | static inline void sht15_send_bit(struct sht15_data *data, int val) |
145 | { | 234 | { |
146 | |||
147 | gpio_set_value(data->pdata->gpio_data, val); | 235 | gpio_set_value(data->pdata->gpio_data, val); |
148 | ndelay(SHT15_TSU); | 236 | ndelay(SHT15_TSU); |
149 | gpio_set_value(data->pdata->gpio_sck, 1); | 237 | gpio_set_value(data->pdata->gpio_sck, 1); |
@@ -154,12 +242,12 @@ static inline void sht15_send_bit(struct sht15_data *data, int val) | |||
154 | 242 | ||
155 | /** | 243 | /** |
156 | * sht15_transmission_start() - specific sequence for new transmission | 244 | * sht15_transmission_start() - specific sequence for new transmission |
157 | * | ||
158 | * @data: device state data | 245 | * @data: device state data |
246 | * | ||
159 | * Timings for this are not documented on the data sheet, so very | 247 | * Timings for this are not documented on the data sheet, so very |
160 | * conservative ones used in implementation. This implements | 248 | * conservative ones used in implementation. This implements |
161 | * figure 12 on the data sheet. | 249 | * figure 12 on the data sheet. |
162 | **/ | 250 | */ |
163 | static void sht15_transmission_start(struct sht15_data *data) | 251 | static void sht15_transmission_start(struct sht15_data *data) |
164 | { | 252 | { |
165 | /* ensure data is high and output */ | 253 | /* ensure data is high and output */ |
@@ -180,23 +268,26 @@ static void sht15_transmission_start(struct sht15_data *data) | |||
180 | gpio_set_value(data->pdata->gpio_sck, 0); | 268 | gpio_set_value(data->pdata->gpio_sck, 0); |
181 | ndelay(SHT15_TSCKL); | 269 | ndelay(SHT15_TSCKL); |
182 | } | 270 | } |
271 | |||
183 | /** | 272 | /** |
184 | * sht15_send_byte() - send a single byte to the device | 273 | * sht15_send_byte() - send a single byte to the device |
185 | * @data: device state | 274 | * @data: device state |
186 | * @byte: value to be sent | 275 | * @byte: value to be sent |
187 | **/ | 276 | */ |
188 | static void sht15_send_byte(struct sht15_data *data, u8 byte) | 277 | static void sht15_send_byte(struct sht15_data *data, u8 byte) |
189 | { | 278 | { |
190 | int i; | 279 | int i; |
280 | |||
191 | for (i = 0; i < 8; i++) { | 281 | for (i = 0; i < 8; i++) { |
192 | sht15_send_bit(data, !!(byte & 0x80)); | 282 | sht15_send_bit(data, !!(byte & 0x80)); |
193 | byte <<= 1; | 283 | byte <<= 1; |
194 | } | 284 | } |
195 | } | 285 | } |
286 | |||
196 | /** | 287 | /** |
197 | * sht15_wait_for_response() - checks for ack from device | 288 | * sht15_wait_for_response() - checks for ack from device |
198 | * @data: device state | 289 | * @data: device state |
199 | **/ | 290 | */ |
200 | static int sht15_wait_for_response(struct sht15_data *data) | 291 | static int sht15_wait_for_response(struct sht15_data *data) |
201 | { | 292 | { |
202 | gpio_direction_input(data->pdata->gpio_data); | 293 | gpio_direction_input(data->pdata->gpio_data); |
@@ -220,27 +311,199 @@ static int sht15_wait_for_response(struct sht15_data *data) | |||
220 | * | 311 | * |
221 | * On entry, sck is output low, data is output pull high | 312 | * On entry, sck is output low, data is output pull high |
222 | * and the interrupt disabled. | 313 | * and the interrupt disabled. |
223 | **/ | 314 | */ |
224 | static int sht15_send_cmd(struct sht15_data *data, u8 cmd) | 315 | static int sht15_send_cmd(struct sht15_data *data, u8 cmd) |
225 | { | 316 | { |
226 | int ret = 0; | 317 | int ret = 0; |
318 | |||
227 | sht15_transmission_start(data); | 319 | sht15_transmission_start(data); |
228 | sht15_send_byte(data, cmd); | 320 | sht15_send_byte(data, cmd); |
229 | ret = sht15_wait_for_response(data); | 321 | ret = sht15_wait_for_response(data); |
230 | return ret; | 322 | return ret; |
231 | } | 323 | } |
324 | |||
325 | /** | ||
326 | * sht15_soft_reset() - send a soft reset command | ||
327 | * @data: sht15 specific data. | ||
328 | * | ||
329 | * As described in section 3.2 of the datasheet. | ||
330 | */ | ||
331 | static int sht15_soft_reset(struct sht15_data *data) | ||
332 | { | ||
333 | int ret; | ||
334 | |||
335 | ret = sht15_send_cmd(data, SHT15_SOFT_RESET); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | msleep(SHT15_TSRST); | ||
339 | /* device resets default hardware status register value */ | ||
340 | data->val_status = 0; | ||
341 | |||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * sht15_ack() - send a ack | ||
347 | * @data: sht15 specific data. | ||
348 | * | ||
349 | * Each byte of data is acknowledged by pulling the data line | ||
350 | * low for one clock pulse. | ||
351 | */ | ||
352 | static void sht15_ack(struct sht15_data *data) | ||
353 | { | ||
354 | gpio_direction_output(data->pdata->gpio_data, 0); | ||
355 | ndelay(SHT15_TSU); | ||
356 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
357 | ndelay(SHT15_TSU); | ||
358 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
359 | ndelay(SHT15_TSU); | ||
360 | gpio_set_value(data->pdata->gpio_data, 1); | ||
361 | |||
362 | gpio_direction_input(data->pdata->gpio_data); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * sht15_end_transmission() - notify device of end of transmission | ||
367 | * @data: device state. | ||
368 | * | ||
369 | * This is basically a NAK (single clock pulse, data high). | ||
370 | */ | ||
371 | static void sht15_end_transmission(struct sht15_data *data) | ||
372 | { | ||
373 | gpio_direction_output(data->pdata->gpio_data, 1); | ||
374 | ndelay(SHT15_TSU); | ||
375 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
376 | ndelay(SHT15_TSCKH); | ||
377 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
378 | ndelay(SHT15_TSCKL); | ||
379 | } | ||
380 | |||
381 | /** | ||
382 | * sht15_read_byte() - Read a byte back from the device | ||
383 | * @data: device state. | ||
384 | */ | ||
385 | static u8 sht15_read_byte(struct sht15_data *data) | ||
386 | { | ||
387 | int i; | ||
388 | u8 byte = 0; | ||
389 | |||
390 | for (i = 0; i < 8; ++i) { | ||
391 | byte <<= 1; | ||
392 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
393 | ndelay(SHT15_TSCKH); | ||
394 | byte |= !!gpio_get_value(data->pdata->gpio_data); | ||
395 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
396 | ndelay(SHT15_TSCKL); | ||
397 | } | ||
398 | return byte; | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * sht15_send_status() - write the status register byte | ||
403 | * @data: sht15 specific data. | ||
404 | * @status: the byte to set the status register with. | ||
405 | * | ||
406 | * As described in figure 14 and table 5 of the datasheet. | ||
407 | */ | ||
408 | static int sht15_send_status(struct sht15_data *data, u8 status) | ||
409 | { | ||
410 | int ret; | ||
411 | |||
412 | ret = sht15_send_cmd(data, SHT15_WRITE_STATUS); | ||
413 | if (ret) | ||
414 | return ret; | ||
415 | gpio_direction_output(data->pdata->gpio_data, 1); | ||
416 | ndelay(SHT15_TSU); | ||
417 | sht15_send_byte(data, status); | ||
418 | ret = sht15_wait_for_response(data); | ||
419 | if (ret) | ||
420 | return ret; | ||
421 | |||
422 | data->val_status = status; | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * sht15_update_status() - get updated status register from device if too old | ||
428 | * @data: device instance specific data. | ||
429 | * | ||
430 | * As described in figure 15 and table 5 of the datasheet. | ||
431 | */ | ||
432 | static int sht15_update_status(struct sht15_data *data) | ||
433 | { | ||
434 | int ret = 0; | ||
435 | u8 status; | ||
436 | u8 previous_config; | ||
437 | u8 dev_checksum = 0; | ||
438 | u8 checksum_vals[2]; | ||
439 | int timeout = HZ; | ||
440 | |||
441 | mutex_lock(&data->read_lock); | ||
442 | if (time_after(jiffies, data->last_status + timeout) | ||
443 | || !data->status_valid) { | ||
444 | ret = sht15_send_cmd(data, SHT15_READ_STATUS); | ||
445 | if (ret) | ||
446 | goto error_ret; | ||
447 | status = sht15_read_byte(data); | ||
448 | |||
449 | if (data->checksumming) { | ||
450 | sht15_ack(data); | ||
451 | dev_checksum = sht15_reverse(sht15_read_byte(data)); | ||
452 | checksum_vals[0] = SHT15_READ_STATUS; | ||
453 | checksum_vals[1] = status; | ||
454 | data->checksum_ok = (sht15_crc8(data, checksum_vals, 2) | ||
455 | == dev_checksum); | ||
456 | } | ||
457 | |||
458 | sht15_end_transmission(data); | ||
459 | |||
460 | /* | ||
461 | * Perform checksum validation on the received data. | ||
462 | * Specification mentions that in case a checksum verification | ||
463 | * fails, a soft reset command must be sent to the device. | ||
464 | */ | ||
465 | if (data->checksumming && !data->checksum_ok) { | ||
466 | previous_config = data->val_status & 0x07; | ||
467 | ret = sht15_soft_reset(data); | ||
468 | if (ret) | ||
469 | goto error_ret; | ||
470 | if (previous_config) { | ||
471 | ret = sht15_send_status(data, previous_config); | ||
472 | if (ret) { | ||
473 | dev_err(data->dev, | ||
474 | "CRC validation failed, unable " | ||
475 | "to restore device settings\n"); | ||
476 | goto error_ret; | ||
477 | } | ||
478 | } | ||
479 | ret = -EAGAIN; | ||
480 | goto error_ret; | ||
481 | } | ||
482 | |||
483 | data->val_status = status; | ||
484 | data->status_valid = true; | ||
485 | data->last_status = jiffies; | ||
486 | } | ||
487 | error_ret: | ||
488 | mutex_unlock(&data->read_lock); | ||
489 | |||
490 | return ret; | ||
491 | } | ||
492 | |||
232 | /** | 493 | /** |
233 | * sht15_update_single_val() - get a new value from device | 494 | * sht15_measurement() - get a new value from device |
234 | * @data: device instance specific data | 495 | * @data: device instance specific data |
235 | * @command: command sent to request value | 496 | * @command: command sent to request value |
236 | * @timeout_msecs: timeout after which comms are assumed | 497 | * @timeout_msecs: timeout after which comms are assumed |
237 | * to have failed are reset. | 498 | * to have failed are reset. |
238 | **/ | 499 | */ |
239 | static inline int sht15_update_single_val(struct sht15_data *data, | 500 | static int sht15_measurement(struct sht15_data *data, |
240 | int command, | 501 | int command, |
241 | int timeout_msecs) | 502 | int timeout_msecs) |
242 | { | 503 | { |
243 | int ret; | 504 | int ret; |
505 | u8 previous_config; | ||
506 | |||
244 | ret = sht15_send_cmd(data, command); | 507 | ret = sht15_send_cmd(data, command); |
245 | if (ret) | 508 | if (ret) |
246 | return ret; | 509 | return ret; |
@@ -256,38 +519,61 @@ static inline int sht15_update_single_val(struct sht15_data *data, | |||
256 | schedule_work(&data->read_work); | 519 | schedule_work(&data->read_work); |
257 | } | 520 | } |
258 | ret = wait_event_timeout(data->wait_queue, | 521 | ret = wait_event_timeout(data->wait_queue, |
259 | (data->flag == SHT15_READING_NOTHING), | 522 | (data->state == SHT15_READING_NOTHING), |
260 | msecs_to_jiffies(timeout_msecs)); | 523 | msecs_to_jiffies(timeout_msecs)); |
261 | if (ret == 0) {/* timeout occurred */ | 524 | if (ret == 0) {/* timeout occurred */ |
262 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); | 525 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); |
263 | sht15_connection_reset(data); | 526 | sht15_connection_reset(data); |
264 | return -ETIME; | 527 | return -ETIME; |
265 | } | 528 | } |
529 | |||
530 | /* | ||
531 | * Perform checksum validation on the received data. | ||
532 | * Specification mentions that in case a checksum verification fails, | ||
533 | * a soft reset command must be sent to the device. | ||
534 | */ | ||
535 | if (data->checksumming && !data->checksum_ok) { | ||
536 | previous_config = data->val_status & 0x07; | ||
537 | ret = sht15_soft_reset(data); | ||
538 | if (ret) | ||
539 | return ret; | ||
540 | if (previous_config) { | ||
541 | ret = sht15_send_status(data, previous_config); | ||
542 | if (ret) { | ||
543 | dev_err(data->dev, | ||
544 | "CRC validation failed, unable " | ||
545 | "to restore device settings\n"); | ||
546 | return ret; | ||
547 | } | ||
548 | } | ||
549 | return -EAGAIN; | ||
550 | } | ||
551 | |||
266 | return 0; | 552 | return 0; |
267 | } | 553 | } |
268 | 554 | ||
269 | /** | 555 | /** |
270 | * sht15_update_vals() - get updated readings from device if too old | 556 | * sht15_update_measurements() - get updated measures from device if too old |
271 | * @data: device state | 557 | * @data: device state |
272 | **/ | 558 | */ |
273 | static int sht15_update_vals(struct sht15_data *data) | 559 | static int sht15_update_measurements(struct sht15_data *data) |
274 | { | 560 | { |
275 | int ret = 0; | 561 | int ret = 0; |
276 | int timeout = HZ; | 562 | int timeout = HZ; |
277 | 563 | ||
278 | mutex_lock(&data->read_lock); | 564 | mutex_lock(&data->read_lock); |
279 | if (time_after(jiffies, data->last_updat + timeout) | 565 | if (time_after(jiffies, data->last_measurement + timeout) |
280 | || !data->valid) { | 566 | || !data->measurements_valid) { |
281 | data->flag = SHT15_READING_HUMID; | 567 | data->state = SHT15_READING_HUMID; |
282 | ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160); | 568 | ret = sht15_measurement(data, SHT15_MEASURE_RH, 160); |
283 | if (ret) | 569 | if (ret) |
284 | goto error_ret; | 570 | goto error_ret; |
285 | data->flag = SHT15_READING_TEMP; | 571 | data->state = SHT15_READING_TEMP; |
286 | ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400); | 572 | ret = sht15_measurement(data, SHT15_MEASURE_TEMP, 400); |
287 | if (ret) | 573 | if (ret) |
288 | goto error_ret; | 574 | goto error_ret; |
289 | data->valid = 1; | 575 | data->measurements_valid = true; |
290 | data->last_updat = jiffies; | 576 | data->last_measurement = jiffies; |
291 | } | 577 | } |
292 | error_ret: | 578 | error_ret: |
293 | mutex_unlock(&data->read_lock); | 579 | mutex_unlock(&data->read_lock); |
@@ -300,10 +586,11 @@ error_ret: | |||
300 | * @data: device state | 586 | * @data: device state |
301 | * | 587 | * |
302 | * As per section 4.3 of the data sheet. | 588 | * As per section 4.3 of the data sheet. |
303 | **/ | 589 | */ |
304 | static inline int sht15_calc_temp(struct sht15_data *data) | 590 | static inline int sht15_calc_temp(struct sht15_data *data) |
305 | { | 591 | { |
306 | int d1 = temppoints[0].d1; | 592 | int d1 = temppoints[0].d1; |
593 | int d2 = (data->val_status & SHT15_STATUS_LOW_RESOLUTION) ? 40 : 10; | ||
307 | int i; | 594 | int i; |
308 | 595 | ||
309 | for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) | 596 | for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) |
@@ -316,7 +603,7 @@ static inline int sht15_calc_temp(struct sht15_data *data) | |||
316 | break; | 603 | break; |
317 | } | 604 | } |
318 | 605 | ||
319 | return data->val_temp*10 + d1; | 606 | return data->val_temp * d2 + d1; |
320 | } | 607 | } |
321 | 608 | ||
322 | /** | 609 | /** |
@@ -325,23 +612,102 @@ static inline int sht15_calc_temp(struct sht15_data *data) | |||
325 | * | 612 | * |
326 | * This is the temperature compensated version as per section 4.2 of | 613 | * This is the temperature compensated version as per section 4.2 of |
327 | * the data sheet. | 614 | * the data sheet. |
328 | **/ | 615 | * |
616 | * The sensor is assumed to be V3, which is compatible with V4. | ||
617 | * Humidity conversion coefficients are shown in table 7 of the datasheet. | ||
618 | */ | ||
329 | static inline int sht15_calc_humid(struct sht15_data *data) | 619 | static inline int sht15_calc_humid(struct sht15_data *data) |
330 | { | 620 | { |
331 | int RHlinear; /* milli percent */ | 621 | int rh_linear; /* milli percent */ |
332 | int temp = sht15_calc_temp(data); | 622 | int temp = sht15_calc_temp(data); |
333 | 623 | int c2, c3; | |
624 | int t2; | ||
334 | const int c1 = -4; | 625 | const int c1 = -4; |
335 | const int c2 = 40500; /* x 10 ^ -6 */ | ||
336 | const int c3 = -28; /* x 10 ^ -7 */ | ||
337 | 626 | ||
338 | RHlinear = c1*1000 | 627 | if (data->val_status & SHT15_STATUS_LOW_RESOLUTION) { |
339 | + c2 * data->val_humid/1000 | 628 | c2 = 648000; /* x 10 ^ -6 */ |
629 | c3 = -7200; /* x 10 ^ -7 */ | ||
630 | t2 = 1280; | ||
631 | } else { | ||
632 | c2 = 40500; /* x 10 ^ -6 */ | ||
633 | c3 = -28; /* x 10 ^ -7 */ | ||
634 | t2 = 80; | ||
635 | } | ||
636 | |||
637 | rh_linear = c1 * 1000 | ||
638 | + c2 * data->val_humid / 1000 | ||
340 | + (data->val_humid * data->val_humid * c3) / 10000; | 639 | + (data->val_humid * data->val_humid * c3) / 10000; |
341 | return (temp - 25000) * (10000 + 80 * data->val_humid) | 640 | return (temp - 25000) * (10000 + t2 * data->val_humid) |
342 | / 1000000 + RHlinear; | 641 | / 1000000 + rh_linear; |
642 | } | ||
643 | |||
644 | /** | ||
645 | * sht15_show_status() - show status information in sysfs | ||
646 | * @dev: device. | ||
647 | * @attr: device attribute. | ||
648 | * @buf: sysfs buffer where information is written to. | ||
649 | * | ||
650 | * Will be called on read access to temp1_fault, humidity1_fault | ||
651 | * and heater_enable sysfs attributes. | ||
652 | * Returns number of bytes written into buffer, negative errno on error. | ||
653 | */ | ||
654 | static ssize_t sht15_show_status(struct device *dev, | ||
655 | struct device_attribute *attr, | ||
656 | char *buf) | ||
657 | { | ||
658 | int ret; | ||
659 | struct sht15_data *data = dev_get_drvdata(dev); | ||
660 | u8 bit = to_sensor_dev_attr(attr)->index; | ||
661 | |||
662 | ret = sht15_update_status(data); | ||
663 | |||
664 | return ret ? ret : sprintf(buf, "%d\n", !!(data->val_status & bit)); | ||
665 | } | ||
666 | |||
667 | /** | ||
668 | * sht15_store_heater() - change heater state via sysfs | ||
669 | * @dev: device. | ||
670 | * @attr: device attribute. | ||
671 | * @buf: sysfs buffer to read the new heater state from. | ||
672 | * @count: length of the data. | ||
673 | * | ||
674 | * Will be called on read access to heater_enable sysfs attribute. | ||
675 | * Returns number of bytes actually decoded, negative errno on error. | ||
676 | */ | ||
677 | static ssize_t sht15_store_heater(struct device *dev, | ||
678 | struct device_attribute *attr, | ||
679 | const char *buf, size_t count) | ||
680 | { | ||
681 | int ret; | ||
682 | struct sht15_data *data = dev_get_drvdata(dev); | ||
683 | long value; | ||
684 | u8 status; | ||
685 | |||
686 | if (strict_strtol(buf, 10, &value)) | ||
687 | return -EINVAL; | ||
688 | |||
689 | mutex_lock(&data->read_lock); | ||
690 | status = data->val_status & 0x07; | ||
691 | if (!!value) | ||
692 | status |= SHT15_STATUS_HEATER; | ||
693 | else | ||
694 | status &= ~SHT15_STATUS_HEATER; | ||
695 | |||
696 | ret = sht15_send_status(data, status); | ||
697 | mutex_unlock(&data->read_lock); | ||
698 | |||
699 | return ret ? ret : count; | ||
343 | } | 700 | } |
344 | 701 | ||
702 | /** | ||
703 | * sht15_show_temp() - show temperature measurement value in sysfs | ||
704 | * @dev: device. | ||
705 | * @attr: device attribute. | ||
706 | * @buf: sysfs buffer where measurement values are written to. | ||
707 | * | ||
708 | * Will be called on read access to temp1_input sysfs attribute. | ||
709 | * Returns number of bytes written into buffer, negative errno on error. | ||
710 | */ | ||
345 | static ssize_t sht15_show_temp(struct device *dev, | 711 | static ssize_t sht15_show_temp(struct device *dev, |
346 | struct device_attribute *attr, | 712 | struct device_attribute *attr, |
347 | char *buf) | 713 | char *buf) |
@@ -350,12 +716,21 @@ static ssize_t sht15_show_temp(struct device *dev, | |||
350 | struct sht15_data *data = dev_get_drvdata(dev); | 716 | struct sht15_data *data = dev_get_drvdata(dev); |
351 | 717 | ||
352 | /* Technically no need to read humidity as well */ | 718 | /* Technically no need to read humidity as well */ |
353 | ret = sht15_update_vals(data); | 719 | ret = sht15_update_measurements(data); |
354 | 720 | ||
355 | return ret ? ret : sprintf(buf, "%d\n", | 721 | return ret ? ret : sprintf(buf, "%d\n", |
356 | sht15_calc_temp(data)); | 722 | sht15_calc_temp(data)); |
357 | } | 723 | } |
358 | 724 | ||
725 | /** | ||
726 | * sht15_show_humidity() - show humidity measurement value in sysfs | ||
727 | * @dev: device. | ||
728 | * @attr: device attribute. | ||
729 | * @buf: sysfs buffer where measurement values are written to. | ||
730 | * | ||
731 | * Will be called on read access to humidity1_input sysfs attribute. | ||
732 | * Returns number of bytes written into buffer, negative errno on error. | ||
733 | */ | ||
359 | static ssize_t sht15_show_humidity(struct device *dev, | 734 | static ssize_t sht15_show_humidity(struct device *dev, |
360 | struct device_attribute *attr, | 735 | struct device_attribute *attr, |
361 | char *buf) | 736 | char *buf) |
@@ -363,11 +738,11 @@ static ssize_t sht15_show_humidity(struct device *dev, | |||
363 | int ret; | 738 | int ret; |
364 | struct sht15_data *data = dev_get_drvdata(dev); | 739 | struct sht15_data *data = dev_get_drvdata(dev); |
365 | 740 | ||
366 | ret = sht15_update_vals(data); | 741 | ret = sht15_update_measurements(data); |
367 | 742 | ||
368 | return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data)); | 743 | return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data)); |
744 | } | ||
369 | 745 | ||
370 | }; | ||
371 | static ssize_t show_name(struct device *dev, | 746 | static ssize_t show_name(struct device *dev, |
372 | struct device_attribute *attr, | 747 | struct device_attribute *attr, |
373 | char *buf) | 748 | char *buf) |
@@ -376,16 +751,23 @@ static ssize_t show_name(struct device *dev, | |||
376 | return sprintf(buf, "%s\n", pdev->name); | 751 | return sprintf(buf, "%s\n", pdev->name); |
377 | } | 752 | } |
378 | 753 | ||
379 | static SENSOR_DEVICE_ATTR(temp1_input, | 754 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, |
380 | S_IRUGO, sht15_show_temp, | 755 | sht15_show_temp, NULL, 0); |
381 | NULL, 0); | 756 | static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, |
382 | static SENSOR_DEVICE_ATTR(humidity1_input, | 757 | sht15_show_humidity, NULL, 0); |
383 | S_IRUGO, sht15_show_humidity, | 758 | static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, sht15_show_status, NULL, |
384 | NULL, 0); | 759 | SHT15_STATUS_LOW_BATTERY); |
760 | static SENSOR_DEVICE_ATTR(humidity1_fault, S_IRUGO, sht15_show_status, NULL, | ||
761 | SHT15_STATUS_LOW_BATTERY); | ||
762 | static SENSOR_DEVICE_ATTR(heater_enable, S_IRUGO | S_IWUSR, sht15_show_status, | ||
763 | sht15_store_heater, SHT15_STATUS_HEATER); | ||
385 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 764 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
386 | static struct attribute *sht15_attrs[] = { | 765 | static struct attribute *sht15_attrs[] = { |
387 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 766 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
388 | &sensor_dev_attr_humidity1_input.dev_attr.attr, | 767 | &sensor_dev_attr_humidity1_input.dev_attr.attr, |
768 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | ||
769 | &sensor_dev_attr_humidity1_fault.dev_attr.attr, | ||
770 | &sensor_dev_attr_heater_enable.dev_attr.attr, | ||
389 | &dev_attr_name.attr, | 771 | &dev_attr_name.attr, |
390 | NULL, | 772 | NULL, |
391 | }; | 773 | }; |
@@ -397,59 +779,31 @@ static const struct attribute_group sht15_attr_group = { | |||
397 | static irqreturn_t sht15_interrupt_fired(int irq, void *d) | 779 | static irqreturn_t sht15_interrupt_fired(int irq, void *d) |
398 | { | 780 | { |
399 | struct sht15_data *data = d; | 781 | struct sht15_data *data = d; |
782 | |||
400 | /* First disable the interrupt */ | 783 | /* First disable the interrupt */ |
401 | disable_irq_nosync(irq); | 784 | disable_irq_nosync(irq); |
402 | atomic_inc(&data->interrupt_handled); | 785 | atomic_inc(&data->interrupt_handled); |
403 | /* Then schedule a reading work struct */ | 786 | /* Then schedule a reading work struct */ |
404 | if (data->flag != SHT15_READING_NOTHING) | 787 | if (data->state != SHT15_READING_NOTHING) |
405 | schedule_work(&data->read_work); | 788 | schedule_work(&data->read_work); |
406 | return IRQ_HANDLED; | 789 | return IRQ_HANDLED; |
407 | } | 790 | } |
408 | 791 | ||
409 | /* Each byte of data is acknowledged by pulling the data line | ||
410 | * low for one clock pulse. | ||
411 | */ | ||
412 | static void sht15_ack(struct sht15_data *data) | ||
413 | { | ||
414 | gpio_direction_output(data->pdata->gpio_data, 0); | ||
415 | ndelay(SHT15_TSU); | ||
416 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
417 | ndelay(SHT15_TSU); | ||
418 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
419 | ndelay(SHT15_TSU); | ||
420 | gpio_set_value(data->pdata->gpio_data, 1); | ||
421 | |||
422 | gpio_direction_input(data->pdata->gpio_data); | ||
423 | } | ||
424 | /** | ||
425 | * sht15_end_transmission() - notify device of end of transmission | ||
426 | * @data: device state | ||
427 | * | ||
428 | * This is basically a NAK. (single clock pulse, data high) | ||
429 | **/ | ||
430 | static void sht15_end_transmission(struct sht15_data *data) | ||
431 | { | ||
432 | gpio_direction_output(data->pdata->gpio_data, 1); | ||
433 | ndelay(SHT15_TSU); | ||
434 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
435 | ndelay(SHT15_TSCKH); | ||
436 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
437 | ndelay(SHT15_TSCKL); | ||
438 | } | ||
439 | |||
440 | static void sht15_bh_read_data(struct work_struct *work_s) | 792 | static void sht15_bh_read_data(struct work_struct *work_s) |
441 | { | 793 | { |
442 | int i; | ||
443 | uint16_t val = 0; | 794 | uint16_t val = 0; |
795 | u8 dev_checksum = 0; | ||
796 | u8 checksum_vals[3]; | ||
444 | struct sht15_data *data | 797 | struct sht15_data *data |
445 | = container_of(work_s, struct sht15_data, | 798 | = container_of(work_s, struct sht15_data, |
446 | read_work); | 799 | read_work); |
800 | |||
447 | /* Firstly, verify the line is low */ | 801 | /* Firstly, verify the line is low */ |
448 | if (gpio_get_value(data->pdata->gpio_data)) { | 802 | if (gpio_get_value(data->pdata->gpio_data)) { |
449 | /* If not, then start the interrupt again - care | 803 | /* |
450 | here as could have gone low in meantime so verify | 804 | * If not, then start the interrupt again - care here as could |
451 | it hasn't! | 805 | * have gone low in meantime so verify it hasn't! |
452 | */ | 806 | */ |
453 | atomic_set(&data->interrupt_handled, 0); | 807 | atomic_set(&data->interrupt_handled, 0); |
454 | enable_irq(gpio_to_irq(data->pdata->gpio_data)); | 808 | enable_irq(gpio_to_irq(data->pdata->gpio_data)); |
455 | /* If still not occurred or another handler has been scheduled */ | 809 | /* If still not occurred or another handler has been scheduled */ |
@@ -457,30 +811,43 @@ static void sht15_bh_read_data(struct work_struct *work_s) | |||
457 | || atomic_read(&data->interrupt_handled)) | 811 | || atomic_read(&data->interrupt_handled)) |
458 | return; | 812 | return; |
459 | } | 813 | } |
814 | |||
460 | /* Read the data back from the device */ | 815 | /* Read the data back from the device */ |
461 | for (i = 0; i < 16; ++i) { | 816 | val = sht15_read_byte(data); |
462 | val <<= 1; | 817 | val <<= 8; |
463 | gpio_set_value(data->pdata->gpio_sck, 1); | 818 | sht15_ack(data); |
464 | ndelay(SHT15_TSCKH); | 819 | val |= sht15_read_byte(data); |
465 | val |= !!gpio_get_value(data->pdata->gpio_data); | 820 | |
466 | gpio_set_value(data->pdata->gpio_sck, 0); | 821 | if (data->checksumming) { |
467 | ndelay(SHT15_TSCKL); | 822 | /* |
468 | if (i == 7) | 823 | * Ask the device for a checksum and read it back. |
469 | sht15_ack(data); | 824 | * Note: the device sends the checksum byte reversed. |
825 | */ | ||
826 | sht15_ack(data); | ||
827 | dev_checksum = sht15_reverse(sht15_read_byte(data)); | ||
828 | checksum_vals[0] = (data->state == SHT15_READING_TEMP) ? | ||
829 | SHT15_MEASURE_TEMP : SHT15_MEASURE_RH; | ||
830 | checksum_vals[1] = (u8) (val >> 8); | ||
831 | checksum_vals[2] = (u8) val; | ||
832 | data->checksum_ok | ||
833 | = (sht15_crc8(data, checksum_vals, 3) == dev_checksum); | ||
470 | } | 834 | } |
835 | |||
471 | /* Tell the device we are done */ | 836 | /* Tell the device we are done */ |
472 | sht15_end_transmission(data); | 837 | sht15_end_transmission(data); |
473 | 838 | ||
474 | switch (data->flag) { | 839 | switch (data->state) { |
475 | case SHT15_READING_TEMP: | 840 | case SHT15_READING_TEMP: |
476 | data->val_temp = val; | 841 | data->val_temp = val; |
477 | break; | 842 | break; |
478 | case SHT15_READING_HUMID: | 843 | case SHT15_READING_HUMID: |
479 | data->val_humid = val; | 844 | data->val_humid = val; |
480 | break; | 845 | break; |
846 | default: | ||
847 | break; | ||
481 | } | 848 | } |
482 | 849 | ||
483 | data->flag = SHT15_READING_NOTHING; | 850 | data->state = SHT15_READING_NOTHING; |
484 | wake_up(&data->wait_queue); | 851 | wake_up(&data->wait_queue); |
485 | } | 852 | } |
486 | 853 | ||
@@ -500,10 +867,10 @@ static void sht15_update_voltage(struct work_struct *work_s) | |||
500 | * | 867 | * |
501 | * Note that as the notification code holds the regulator lock, we have | 868 | * Note that as the notification code holds the regulator lock, we have |
502 | * to schedule an update of the supply voltage rather than getting it directly. | 869 | * to schedule an update of the supply voltage rather than getting it directly. |
503 | **/ | 870 | */ |
504 | static int sht15_invalidate_voltage(struct notifier_block *nb, | 871 | static int sht15_invalidate_voltage(struct notifier_block *nb, |
505 | unsigned long event, | 872 | unsigned long event, |
506 | void *ignored) | 873 | void *ignored) |
507 | { | 874 | { |
508 | struct sht15_data *data = container_of(nb, struct sht15_data, nb); | 875 | struct sht15_data *data = container_of(nb, struct sht15_data, nb); |
509 | 876 | ||
@@ -518,10 +885,11 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
518 | { | 885 | { |
519 | int ret = 0; | 886 | int ret = 0; |
520 | struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); | 887 | struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); |
888 | u8 status = 0; | ||
521 | 889 | ||
522 | if (!data) { | 890 | if (!data) { |
523 | ret = -ENOMEM; | 891 | ret = -ENOMEM; |
524 | dev_err(&pdev->dev, "kzalloc failed"); | 892 | dev_err(&pdev->dev, "kzalloc failed\n"); |
525 | goto error_ret; | 893 | goto error_ret; |
526 | } | 894 | } |
527 | 895 | ||
@@ -533,13 +901,22 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
533 | init_waitqueue_head(&data->wait_queue); | 901 | init_waitqueue_head(&data->wait_queue); |
534 | 902 | ||
535 | if (pdev->dev.platform_data == NULL) { | 903 | if (pdev->dev.platform_data == NULL) { |
536 | dev_err(&pdev->dev, "no platform data supplied"); | 904 | dev_err(&pdev->dev, "no platform data supplied\n"); |
537 | goto err_free_data; | 905 | goto err_free_data; |
538 | } | 906 | } |
539 | data->pdata = pdev->dev.platform_data; | 907 | data->pdata = pdev->dev.platform_data; |
540 | data->supply_uV = data->pdata->supply_mv*1000; | 908 | data->supply_uV = data->pdata->supply_mv * 1000; |
541 | 909 | if (data->pdata->checksum) | |
542 | /* If a regulator is available, query what the supply voltage actually is!*/ | 910 | data->checksumming = true; |
911 | if (data->pdata->no_otp_reload) | ||
912 | status |= SHT15_STATUS_NO_OTP_RELOAD; | ||
913 | if (data->pdata->low_resolution) | ||
914 | status |= SHT15_STATUS_LOW_RESOLUTION; | ||
915 | |||
916 | /* | ||
917 | * If a regulator is available, | ||
918 | * query what the supply voltage actually is! | ||
919 | */ | ||
543 | data->reg = regulator_get(data->dev, "vcc"); | 920 | data->reg = regulator_get(data->dev, "vcc"); |
544 | if (!IS_ERR(data->reg)) { | 921 | if (!IS_ERR(data->reg)) { |
545 | int voltage; | 922 | int voltage; |
@@ -549,28 +926,34 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
549 | data->supply_uV = voltage; | 926 | data->supply_uV = voltage; |
550 | 927 | ||
551 | regulator_enable(data->reg); | 928 | regulator_enable(data->reg); |
552 | /* setup a notifier block to update this if another device | 929 | /* |
553 | * causes the voltage to change */ | 930 | * Setup a notifier block to update this if another device |
931 | * causes the voltage to change | ||
932 | */ | ||
554 | data->nb.notifier_call = &sht15_invalidate_voltage; | 933 | data->nb.notifier_call = &sht15_invalidate_voltage; |
555 | ret = regulator_register_notifier(data->reg, &data->nb); | 934 | ret = regulator_register_notifier(data->reg, &data->nb); |
935 | if (ret) { | ||
936 | dev_err(&pdev->dev, | ||
937 | "regulator notifier request failed\n"); | ||
938 | regulator_disable(data->reg); | ||
939 | regulator_put(data->reg); | ||
940 | goto err_free_data; | ||
941 | } | ||
556 | } | 942 | } |
557 | /* Try requesting the GPIOs */ | 943 | |
944 | /* Try requesting the GPIOs */ | ||
558 | ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); | 945 | ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); |
559 | if (ret) { | 946 | if (ret) { |
560 | dev_err(&pdev->dev, "gpio request failed"); | 947 | dev_err(&pdev->dev, "gpio request failed\n"); |
561 | goto err_free_data; | 948 | goto err_release_reg; |
562 | } | 949 | } |
563 | gpio_direction_output(data->pdata->gpio_sck, 0); | 950 | gpio_direction_output(data->pdata->gpio_sck, 0); |
951 | |||
564 | ret = gpio_request(data->pdata->gpio_data, "SHT15 data"); | 952 | ret = gpio_request(data->pdata->gpio_data, "SHT15 data"); |
565 | if (ret) { | 953 | if (ret) { |
566 | dev_err(&pdev->dev, "gpio request failed"); | 954 | dev_err(&pdev->dev, "gpio request failed\n"); |
567 | goto err_release_gpio_sck; | 955 | goto err_release_gpio_sck; |
568 | } | 956 | } |
569 | ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); | ||
570 | if (ret) { | ||
571 | dev_err(&pdev->dev, "sysfs create failed"); | ||
572 | goto err_release_gpio_data; | ||
573 | } | ||
574 | 957 | ||
575 | ret = request_irq(gpio_to_irq(data->pdata->gpio_data), | 958 | ret = request_irq(gpio_to_irq(data->pdata->gpio_data), |
576 | sht15_interrupt_fired, | 959 | sht15_interrupt_fired, |
@@ -578,30 +961,53 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
578 | "sht15 data", | 961 | "sht15 data", |
579 | data); | 962 | data); |
580 | if (ret) { | 963 | if (ret) { |
581 | dev_err(&pdev->dev, "failed to get irq for data line"); | 964 | dev_err(&pdev->dev, "failed to get irq for data line\n"); |
582 | goto err_release_gpio_data; | 965 | goto err_release_gpio_data; |
583 | } | 966 | } |
584 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); | 967 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); |
585 | sht15_connection_reset(data); | 968 | sht15_connection_reset(data); |
586 | sht15_send_cmd(data, 0x1E); | 969 | ret = sht15_soft_reset(data); |
970 | if (ret) | ||
971 | goto err_release_irq; | ||
972 | |||
973 | /* write status with platform data options */ | ||
974 | if (status) { | ||
975 | ret = sht15_send_status(data, status); | ||
976 | if (ret) | ||
977 | goto err_release_irq; | ||
978 | } | ||
979 | |||
980 | ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); | ||
981 | if (ret) { | ||
982 | dev_err(&pdev->dev, "sysfs create failed\n"); | ||
983 | goto err_release_irq; | ||
984 | } | ||
587 | 985 | ||
588 | data->hwmon_dev = hwmon_device_register(data->dev); | 986 | data->hwmon_dev = hwmon_device_register(data->dev); |
589 | if (IS_ERR(data->hwmon_dev)) { | 987 | if (IS_ERR(data->hwmon_dev)) { |
590 | ret = PTR_ERR(data->hwmon_dev); | 988 | ret = PTR_ERR(data->hwmon_dev); |
591 | goto err_release_irq; | 989 | goto err_release_sysfs_group; |
592 | } | 990 | } |
991 | |||
593 | return 0; | 992 | return 0; |
594 | 993 | ||
994 | err_release_sysfs_group: | ||
995 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); | ||
595 | err_release_irq: | 996 | err_release_irq: |
596 | free_irq(gpio_to_irq(data->pdata->gpio_data), data); | 997 | free_irq(gpio_to_irq(data->pdata->gpio_data), data); |
597 | err_release_gpio_data: | 998 | err_release_gpio_data: |
598 | gpio_free(data->pdata->gpio_data); | 999 | gpio_free(data->pdata->gpio_data); |
599 | err_release_gpio_sck: | 1000 | err_release_gpio_sck: |
600 | gpio_free(data->pdata->gpio_sck); | 1001 | gpio_free(data->pdata->gpio_sck); |
1002 | err_release_reg: | ||
1003 | if (!IS_ERR(data->reg)) { | ||
1004 | regulator_unregister_notifier(data->reg, &data->nb); | ||
1005 | regulator_disable(data->reg); | ||
1006 | regulator_put(data->reg); | ||
1007 | } | ||
601 | err_free_data: | 1008 | err_free_data: |
602 | kfree(data); | 1009 | kfree(data); |
603 | error_ret: | 1010 | error_ret: |
604 | |||
605 | return ret; | 1011 | return ret; |
606 | } | 1012 | } |
607 | 1013 | ||
@@ -609,9 +1015,15 @@ static int __devexit sht15_remove(struct platform_device *pdev) | |||
609 | { | 1015 | { |
610 | struct sht15_data *data = platform_get_drvdata(pdev); | 1016 | struct sht15_data *data = platform_get_drvdata(pdev); |
611 | 1017 | ||
612 | /* Make sure any reads from the device are done and | 1018 | /* |
613 | * prevent new ones from beginning */ | 1019 | * Make sure any reads from the device are done and |
1020 | * prevent new ones beginning | ||
1021 | */ | ||
614 | mutex_lock(&data->read_lock); | 1022 | mutex_lock(&data->read_lock); |
1023 | if (sht15_soft_reset(data)) { | ||
1024 | mutex_unlock(&data->read_lock); | ||
1025 | return -EFAULT; | ||
1026 | } | ||
615 | hwmon_device_unregister(data->hwmon_dev); | 1027 | hwmon_device_unregister(data->hwmon_dev); |
616 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); | 1028 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); |
617 | if (!IS_ERR(data->reg)) { | 1029 | if (!IS_ERR(data->reg)) { |
@@ -625,10 +1037,10 @@ static int __devexit sht15_remove(struct platform_device *pdev) | |||
625 | gpio_free(data->pdata->gpio_sck); | 1037 | gpio_free(data->pdata->gpio_sck); |
626 | mutex_unlock(&data->read_lock); | 1038 | mutex_unlock(&data->read_lock); |
627 | kfree(data); | 1039 | kfree(data); |
1040 | |||
628 | return 0; | 1041 | return 0; |
629 | } | 1042 | } |
630 | 1043 | ||
631 | |||
632 | /* | 1044 | /* |
633 | * sht_drivers simultaneously refers to __devinit and __devexit function | 1045 | * sht_drivers simultaneously refers to __devinit and __devexit function |
634 | * which causes spurious section mismatch warning. So use __refdata to | 1046 | * which causes spurious section mismatch warning. So use __refdata to |
@@ -673,7 +1085,6 @@ static struct platform_driver __refdata sht_drivers[] = { | |||
673 | }, | 1085 | }, |
674 | }; | 1086 | }; |
675 | 1087 | ||
676 | |||
677 | static int __init sht15_init(void) | 1088 | static int __init sht15_init(void) |
678 | { | 1089 | { |
679 | int ret; | 1090 | int ret; |
diff --git a/drivers/hwmon/ucd9000.c b/drivers/hwmon/ucd9000.c new file mode 100644 index 000000000000..ace1c7319734 --- /dev/null +++ b/drivers/hwmon/ucd9000.c | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | * Hardware monitoring driver for UCD90xxx Sequencer and System Health | ||
3 | * Controller series | ||
4 | * | ||
5 | * Copyright (C) 2011 Ericsson AB. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/i2c/pmbus.h> | ||
29 | #include "pmbus.h" | ||
30 | |||
31 | enum chips { ucd9000, ucd90120, ucd90124, ucd9090, ucd90910 }; | ||
32 | |||
33 | #define UCD9000_MONITOR_CONFIG 0xd5 | ||
34 | #define UCD9000_NUM_PAGES 0xd6 | ||
35 | #define UCD9000_FAN_CONFIG_INDEX 0xe7 | ||
36 | #define UCD9000_FAN_CONFIG 0xe8 | ||
37 | #define UCD9000_DEVICE_ID 0xfd | ||
38 | |||
39 | #define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07) | ||
40 | #define UCD9000_MON_PAGE(x) ((x) & 0x0f) | ||
41 | |||
42 | #define UCD9000_MON_VOLTAGE 1 | ||
43 | #define UCD9000_MON_TEMPERATURE 2 | ||
44 | #define UCD9000_MON_CURRENT 3 | ||
45 | #define UCD9000_MON_VOLTAGE_HW 4 | ||
46 | |||
47 | #define UCD9000_NUM_FAN 4 | ||
48 | |||
49 | struct ucd9000_data { | ||
50 | u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; | ||
51 | struct pmbus_driver_info info; | ||
52 | }; | ||
53 | #define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info) | ||
54 | |||
55 | static int ucd9000_get_fan_config(struct i2c_client *client, int fan) | ||
56 | { | ||
57 | int fan_config = 0; | ||
58 | struct ucd9000_data *data | ||
59 | = to_ucd9000_data(pmbus_get_driver_info(client)); | ||
60 | |||
61 | if (data->fan_data[fan][3] & 1) | ||
62 | fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */ | ||
63 | |||
64 | /* Pulses/revolution */ | ||
65 | fan_config |= (data->fan_data[fan][3] & 0x06) >> 1; | ||
66 | |||
67 | return fan_config; | ||
68 | } | ||
69 | |||
70 | static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | int fan_config; | ||
74 | |||
75 | switch (reg) { | ||
76 | case PMBUS_FAN_CONFIG_12: | ||
77 | if (page) | ||
78 | return -EINVAL; | ||
79 | |||
80 | ret = ucd9000_get_fan_config(client, 0); | ||
81 | if (ret < 0) | ||
82 | return ret; | ||
83 | fan_config = ret << 4; | ||
84 | ret = ucd9000_get_fan_config(client, 1); | ||
85 | if (ret < 0) | ||
86 | return ret; | ||
87 | fan_config |= ret; | ||
88 | ret = fan_config; | ||
89 | break; | ||
90 | case PMBUS_FAN_CONFIG_34: | ||
91 | if (page) | ||
92 | return -EINVAL; | ||
93 | |||
94 | ret = ucd9000_get_fan_config(client, 2); | ||
95 | if (ret < 0) | ||
96 | return ret; | ||
97 | fan_config = ret << 4; | ||
98 | ret = ucd9000_get_fan_config(client, 3); | ||
99 | if (ret < 0) | ||
100 | return ret; | ||
101 | fan_config |= ret; | ||
102 | ret = fan_config; | ||
103 | break; | ||
104 | default: | ||
105 | ret = -ENODATA; | ||
106 | break; | ||
107 | } | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | static const struct i2c_device_id ucd9000_id[] = { | ||
112 | {"ucd9000", ucd9000}, | ||
113 | {"ucd90120", ucd90120}, | ||
114 | {"ucd90124", ucd90124}, | ||
115 | {"ucd9090", ucd9090}, | ||
116 | {"ucd90910", ucd90910}, | ||
117 | {} | ||
118 | }; | ||
119 | MODULE_DEVICE_TABLE(i2c, ucd9000_id); | ||
120 | |||
121 | static int ucd9000_probe(struct i2c_client *client, | ||
122 | const struct i2c_device_id *id) | ||
123 | { | ||
124 | u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; | ||
125 | struct ucd9000_data *data; | ||
126 | struct pmbus_driver_info *info; | ||
127 | const struct i2c_device_id *mid; | ||
128 | int i, ret; | ||
129 | |||
130 | if (!i2c_check_functionality(client->adapter, | ||
131 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
132 | I2C_FUNC_SMBUS_BLOCK_DATA)) | ||
133 | return -ENODEV; | ||
134 | |||
135 | ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID, | ||
136 | block_buffer); | ||
137 | if (ret < 0) { | ||
138 | dev_err(&client->dev, "Failed to read device ID\n"); | ||
139 | return ret; | ||
140 | } | ||
141 | block_buffer[ret] = '\0'; | ||
142 | dev_info(&client->dev, "Device ID %s\n", block_buffer); | ||
143 | |||
144 | mid = NULL; | ||
145 | for (i = 0; i < ARRAY_SIZE(ucd9000_id); i++) { | ||
146 | mid = &ucd9000_id[i]; | ||
147 | if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) | ||
148 | break; | ||
149 | } | ||
150 | if (!mid || !strlen(mid->name)) { | ||
151 | dev_err(&client->dev, "Unsupported device\n"); | ||
152 | return -ENODEV; | ||
153 | } | ||
154 | |||
155 | if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data) | ||
156 | dev_notice(&client->dev, | ||
157 | "Device mismatch: Configured %s, detected %s\n", | ||
158 | id->name, mid->name); | ||
159 | |||
160 | data = kzalloc(sizeof(struct ucd9000_data), GFP_KERNEL); | ||
161 | if (!data) | ||
162 | return -ENOMEM; | ||
163 | info = &data->info; | ||
164 | |||
165 | ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES); | ||
166 | if (ret < 0) { | ||
167 | dev_err(&client->dev, | ||
168 | "Failed to read number of active pages\n"); | ||
169 | goto out; | ||
170 | } | ||
171 | info->pages = ret; | ||
172 | if (!info->pages) { | ||
173 | dev_err(&client->dev, "No pages configured\n"); | ||
174 | ret = -ENODEV; | ||
175 | goto out; | ||
176 | } | ||
177 | |||
178 | /* The internal temperature sensor is always active */ | ||
179 | info->func[0] = PMBUS_HAVE_TEMP; | ||
180 | |||
181 | /* Everything else is configurable */ | ||
182 | ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG, | ||
183 | block_buffer); | ||
184 | if (ret <= 0) { | ||
185 | dev_err(&client->dev, "Failed to read configuration data\n"); | ||
186 | ret = -ENODEV; | ||
187 | goto out; | ||
188 | } | ||
189 | for (i = 0; i < ret; i++) { | ||
190 | int page = UCD9000_MON_PAGE(block_buffer[i]); | ||
191 | |||
192 | if (page >= info->pages) | ||
193 | continue; | ||
194 | |||
195 | switch (UCD9000_MON_TYPE(block_buffer[i])) { | ||
196 | case UCD9000_MON_VOLTAGE: | ||
197 | case UCD9000_MON_VOLTAGE_HW: | ||
198 | info->func[page] |= PMBUS_HAVE_VOUT | ||
199 | | PMBUS_HAVE_STATUS_VOUT; | ||
200 | break; | ||
201 | case UCD9000_MON_TEMPERATURE: | ||
202 | info->func[page] |= PMBUS_HAVE_TEMP2 | ||
203 | | PMBUS_HAVE_STATUS_TEMP; | ||
204 | break; | ||
205 | case UCD9000_MON_CURRENT: | ||
206 | info->func[page] |= PMBUS_HAVE_IOUT | ||
207 | | PMBUS_HAVE_STATUS_IOUT; | ||
208 | break; | ||
209 | default: | ||
210 | break; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | /* Fan configuration */ | ||
215 | if (mid->driver_data == ucd90124) { | ||
216 | for (i = 0; i < UCD9000_NUM_FAN; i++) { | ||
217 | i2c_smbus_write_byte_data(client, | ||
218 | UCD9000_FAN_CONFIG_INDEX, i); | ||
219 | ret = i2c_smbus_read_block_data(client, | ||
220 | UCD9000_FAN_CONFIG, | ||
221 | data->fan_data[i]); | ||
222 | if (ret < 0) | ||
223 | goto out; | ||
224 | } | ||
225 | i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0); | ||
226 | |||
227 | info->read_byte_data = ucd9000_read_byte_data; | ||
228 | info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | ||
229 | | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; | ||
230 | } | ||
231 | |||
232 | ret = pmbus_do_probe(client, mid, info); | ||
233 | if (ret < 0) | ||
234 | goto out; | ||
235 | return 0; | ||
236 | |||
237 | out: | ||
238 | kfree(data); | ||
239 | return ret; | ||
240 | } | ||
241 | |||
242 | static int ucd9000_remove(struct i2c_client *client) | ||
243 | { | ||
244 | int ret; | ||
245 | struct ucd9000_data *data; | ||
246 | |||
247 | data = to_ucd9000_data(pmbus_get_driver_info(client)); | ||
248 | ret = pmbus_do_remove(client); | ||
249 | kfree(data); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | |||
254 | /* This is the driver that will be inserted */ | ||
255 | static struct i2c_driver ucd9000_driver = { | ||
256 | .driver = { | ||
257 | .name = "ucd9000", | ||
258 | }, | ||
259 | .probe = ucd9000_probe, | ||
260 | .remove = ucd9000_remove, | ||
261 | .id_table = ucd9000_id, | ||
262 | }; | ||
263 | |||
264 | static int __init ucd9000_init(void) | ||
265 | { | ||
266 | return i2c_add_driver(&ucd9000_driver); | ||
267 | } | ||
268 | |||
269 | static void __exit ucd9000_exit(void) | ||
270 | { | ||
271 | i2c_del_driver(&ucd9000_driver); | ||
272 | } | ||
273 | |||
274 | MODULE_AUTHOR("Guenter Roeck"); | ||
275 | MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); | ||
276 | MODULE_LICENSE("GPL"); | ||
277 | module_init(ucd9000_init); | ||
278 | module_exit(ucd9000_exit); | ||
diff --git a/drivers/hwmon/ucd9200.c b/drivers/hwmon/ucd9200.c new file mode 100644 index 000000000000..ffcc1cf3609d --- /dev/null +++ b/drivers/hwmon/ucd9200.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | * Hardware monitoring driver for ucd9200 series Digital PWM System Controllers | ||
3 | * | ||
4 | * Copyright (C) 2011 Ericsson AB. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/i2c/pmbus.h> | ||
28 | #include "pmbus.h" | ||
29 | |||
30 | #define UCD9200_PHASE_INFO 0xd2 | ||
31 | #define UCD9200_DEVICE_ID 0xfd | ||
32 | |||
33 | enum chips { ucd9200, ucd9220, ucd9222, ucd9224, ucd9240, ucd9244, ucd9246, | ||
34 | ucd9248 }; | ||
35 | |||
36 | static const struct i2c_device_id ucd9200_id[] = { | ||
37 | {"ucd9200", ucd9200}, | ||
38 | {"ucd9220", ucd9220}, | ||
39 | {"ucd9222", ucd9222}, | ||
40 | {"ucd9224", ucd9224}, | ||
41 | {"ucd9240", ucd9240}, | ||
42 | {"ucd9244", ucd9244}, | ||
43 | {"ucd9246", ucd9246}, | ||
44 | {"ucd9248", ucd9248}, | ||
45 | {} | ||
46 | }; | ||
47 | MODULE_DEVICE_TABLE(i2c, ucd9200_id); | ||
48 | |||
49 | static int ucd9200_probe(struct i2c_client *client, | ||
50 | const struct i2c_device_id *id) | ||
51 | { | ||
52 | u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; | ||
53 | struct pmbus_driver_info *info; | ||
54 | const struct i2c_device_id *mid; | ||
55 | int i, j, ret; | ||
56 | |||
57 | if (!i2c_check_functionality(client->adapter, | ||
58 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
59 | I2C_FUNC_SMBUS_BLOCK_DATA)) | ||
60 | return -ENODEV; | ||
61 | |||
62 | ret = i2c_smbus_read_block_data(client, UCD9200_DEVICE_ID, | ||
63 | block_buffer); | ||
64 | if (ret < 0) { | ||
65 | dev_err(&client->dev, "Failed to read device ID\n"); | ||
66 | return ret; | ||
67 | } | ||
68 | block_buffer[ret] = '\0'; | ||
69 | dev_info(&client->dev, "Device ID %s\n", block_buffer); | ||
70 | |||
71 | mid = NULL; | ||
72 | for (i = 0; i < ARRAY_SIZE(ucd9200_id); i++) { | ||
73 | mid = &ucd9200_id[i]; | ||
74 | if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) | ||
75 | break; | ||
76 | } | ||
77 | if (!mid || !strlen(mid->name)) { | ||
78 | dev_err(&client->dev, "Unsupported device\n"); | ||
79 | return -ENODEV; | ||
80 | } | ||
81 | if (id->driver_data != ucd9200 && id->driver_data != mid->driver_data) | ||
82 | dev_notice(&client->dev, | ||
83 | "Device mismatch: Configured %s, detected %s\n", | ||
84 | id->name, mid->name); | ||
85 | |||
86 | info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); | ||
87 | if (!info) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | ret = i2c_smbus_read_block_data(client, UCD9200_PHASE_INFO, | ||
91 | block_buffer); | ||
92 | if (ret < 0) { | ||
93 | dev_err(&client->dev, "Failed to read phase information\n"); | ||
94 | goto out; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Calculate number of configured pages (rails) from PHASE_INFO | ||
99 | * register. | ||
100 | * Rails have to be sequential, so we can abort after finding | ||
101 | * the first unconfigured rail. | ||
102 | */ | ||
103 | info->pages = 0; | ||
104 | for (i = 0; i < ret; i++) { | ||
105 | if (!block_buffer[i]) | ||
106 | break; | ||
107 | info->pages++; | ||
108 | } | ||
109 | if (!info->pages) { | ||
110 | dev_err(&client->dev, "No rails configured\n"); | ||
111 | ret = -ENODEV; | ||
112 | goto out; | ||
113 | } | ||
114 | dev_info(&client->dev, "%d rails configured\n", info->pages); | ||
115 | |||
116 | /* | ||
117 | * Set PHASE registers on all pages to 0xff to ensure that phase | ||
118 | * specific commands will apply to all phases of a given page (rail). | ||
119 | * This only affects the READ_IOUT and READ_TEMPERATURE2 registers. | ||
120 | * READ_IOUT will return the sum of currents of all phases of a rail, | ||
121 | * and READ_TEMPERATURE2 will return the maximum temperature detected | ||
122 | * for the the phases of the rail. | ||
123 | */ | ||
124 | for (i = 0; i < info->pages; i++) { | ||
125 | /* | ||
126 | * Setting PAGE & PHASE fails once in a while for no obvious | ||
127 | * reason, so we need to retry a couple of times. | ||
128 | */ | ||
129 | for (j = 0; j < 3; j++) { | ||
130 | ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i); | ||
131 | if (ret < 0) | ||
132 | continue; | ||
133 | ret = i2c_smbus_write_byte_data(client, PMBUS_PHASE, | ||
134 | 0xff); | ||
135 | if (ret < 0) | ||
136 | continue; | ||
137 | break; | ||
138 | } | ||
139 | if (ret < 0) { | ||
140 | dev_err(&client->dev, | ||
141 | "Failed to initialize PHASE registers\n"); | ||
142 | goto out; | ||
143 | } | ||
144 | } | ||
145 | if (info->pages > 1) | ||
146 | i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); | ||
147 | |||
148 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | | ||
149 | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | | ||
150 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | | ||
151 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | | ||
152 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | | ||
153 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | ||
154 | |||
155 | for (i = 1; i < info->pages; i++) | ||
156 | info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | | ||
157 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | | ||
158 | PMBUS_HAVE_POUT | | ||
159 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | ||
160 | |||
161 | /* ucd9240 supports a single fan */ | ||
162 | if (mid->driver_data == ucd9240) | ||
163 | info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12; | ||
164 | |||
165 | ret = pmbus_do_probe(client, mid, info); | ||
166 | if (ret < 0) | ||
167 | goto out; | ||
168 | return 0; | ||
169 | out: | ||
170 | kfree(info); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static int ucd9200_remove(struct i2c_client *client) | ||
175 | { | ||
176 | int ret; | ||
177 | const struct pmbus_driver_info *info; | ||
178 | |||
179 | info = pmbus_get_driver_info(client); | ||
180 | ret = pmbus_do_remove(client); | ||
181 | kfree(info); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | |||
186 | /* This is the driver that will be inserted */ | ||
187 | static struct i2c_driver ucd9200_driver = { | ||
188 | .driver = { | ||
189 | .name = "ucd9200", | ||
190 | }, | ||
191 | .probe = ucd9200_probe, | ||
192 | .remove = ucd9200_remove, | ||
193 | .id_table = ucd9200_id, | ||
194 | }; | ||
195 | |||
196 | static int __init ucd9200_init(void) | ||
197 | { | ||
198 | return i2c_add_driver(&ucd9200_driver); | ||
199 | } | ||
200 | |||
201 | static void __exit ucd9200_exit(void) | ||
202 | { | ||
203 | i2c_del_driver(&ucd9200_driver); | ||
204 | } | ||
205 | |||
206 | MODULE_AUTHOR("Guenter Roeck"); | ||
207 | MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x"); | ||
208 | MODULE_LICENSE("GPL"); | ||
209 | module_init(ucd9200_init); | ||
210 | module_exit(ucd9200_exit); | ||
diff --git a/include/linux/sht15.h b/include/linux/sht15.h index 046bce05ecab..f85c7c523da0 100644 --- a/include/linux/sht15.h +++ b/include/linux/sht15.h | |||
@@ -8,17 +8,27 @@ | |||
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | ||
12 | * For further information, see the Documentation/hwmon/sht15 file. | ||
11 | */ | 13 | */ |
12 | 14 | ||
13 | /** | 15 | /** |
14 | * struct sht15_platform_data - sht15 connectivity info | 16 | * struct sht15_platform_data - sht15 connectivity info |
15 | * @gpio_data: no. of gpio to which bidirectional data line is connected | 17 | * @gpio_data: no. of gpio to which bidirectional data line is |
16 | * @gpio_sck: no. of gpio to which the data clock is connected. | 18 | * connected. |
17 | * @supply_mv: supply voltage in mv. Overridden by regulator if available. | 19 | * @gpio_sck: no. of gpio to which the data clock is connected. |
18 | **/ | 20 | * @supply_mv: supply voltage in mv. Overridden by regulator if |
21 | * available. | ||
22 | * @checksum: flag to indicate the checksum should be validated. | ||
23 | * @no_otp_reload: flag to indicate no reload from OTP. | ||
24 | * @low_resolution: flag to indicate the temp/humidity resolution to use. | ||
25 | */ | ||
19 | struct sht15_platform_data { | 26 | struct sht15_platform_data { |
20 | int gpio_data; | 27 | int gpio_data; |
21 | int gpio_sck; | 28 | int gpio_sck; |
22 | int supply_mv; | 29 | int supply_mv; |
30 | bool checksum; | ||
31 | bool no_otp_reload; | ||
32 | bool low_resolution; | ||
23 | }; | 33 | }; |
24 | 34 | ||