diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-04 13:56:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-04 13:56:14 -0400 |
commit | 77b0a4aa0732f1856aef85b8db085864e5971a14 (patch) | |
tree | 3b55b24d79afbc1fb358bc63e03469ec770d2150 | |
parent | f80fa1822d6ccca369578108dc70576cff6c67a0 (diff) | |
parent | 7ce4190c4ca466ccd609845b97dce665317aee2a (diff) |
Merge tag 'hwmon-for-linus-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon updates from Guenter Roeck:
- New hwmon registration API, including ports of several drivers to the
new API
- New hwmon driver for APM X-Gene SoC
- Added support for UCD90160, DPS-460, DPS-800, and SGD009 PMBUs chips
- Various cleanups, minor improvements, and fixes in several drivers
* tag 'hwmon-for-linus-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (54 commits)
hwmon: (nct6775) Add support for multiple virtual temperature sources
hwmon: (adt7470) No need for additional synchronization on kthread_stop()
hwmon: (lm95241) Update module description to include LM95231
hwmon: (lm95245) Select REGMAP_I2C
hwmon: (ibmpowernv) Fix label for cores numbers not threads
hwmon: (adt7470) Allow faster removal
hwmon: (adt7470) Add write support to alarm_mask
hwmon: (xgene) access mailbox as RAM
hwmon: (lm95245) Use new hwmon registration API
hwmon: (lm95241) Convert to use new hwmon registration API
hwmon: (jc42) Convert to use new hwmon registration API
hwmon: (max31790) Convert to use new hwmon registration API
hwmon: (nct7904) Convert to use new hwmon registration API
hwmon: (ltc4245) Convert to use new hwmon registration API
hwmon: (tmp421) Convert to use new hwmon registration API
hwmon: (tmp102) Convert to use new hwmon registration API
hwmon: (lm90) Convert to use new hwmon registration API
hwmon: (lm75) Convert to use new hwmon registration API
hwmon: (xgene) Fix crash when alarm occurs before driver probe
hwmon: (iio_hwmon) defer probe when no channel is found
...
36 files changed, 4620 insertions, 2156 deletions
diff --git a/Documentation/devicetree/bindings/hwmon/ltc4151.txt b/Documentation/devicetree/bindings/hwmon/ltc4151.txt new file mode 100644 index 000000000000..d008a5ef525a --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ltc4151.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | LTC4151 High Voltage I2C Current and Voltage Monitor | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Must be "lltc,ltc4151" | ||
5 | - reg: I2C address | ||
6 | |||
7 | Optional properties: | ||
8 | - shunt-resistor-micro-ohms | ||
9 | Shunt resistor value in micro-Ohms | ||
10 | Defaults to <1000> if unset. | ||
11 | |||
12 | Example: | ||
13 | |||
14 | ltc4151@6e { | ||
15 | compatible = "lltc,ltc4151"; | ||
16 | reg = <0x6e>; | ||
17 | shunt-resistor-micro-ohms = <1500>; | ||
18 | }; | ||
diff --git a/Documentation/devicetree/bindings/hwmon/max6650.txt b/Documentation/devicetree/bindings/hwmon/max6650.txt new file mode 100644 index 000000000000..f6bd87d8e284 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/max6650.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | Bindings for MAX6651 and MAX6650 I2C fan controllers | ||
2 | |||
3 | Reference: | ||
4 | [1] https://datasheets.maximintegrated.com/en/ds/MAX6650-MAX6651.pdf | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : One of "maxim,max6650" or "maxim,max6651" | ||
8 | - reg : I2C address, one of 0x1b, 0x1f, 0x4b, 0x48. | ||
9 | |||
10 | Optional properties, default is to retain the chip's current setting: | ||
11 | - maxim,fan-microvolt : The supply voltage of the fan, either 5000000 uV or | ||
12 | 12000000 uV. | ||
13 | - maxim,fan-prescale : Pre-scaling value, as per datasheet [1]. Lower values | ||
14 | allow more fine-grained control of slower fans. | ||
15 | Valid: 1, 2, 4, 8, 16. | ||
16 | - maxim,fan-target-rpm: Initial requested fan rotation speed. If specified, the | ||
17 | driver selects closed-loop mode and the requested speed. | ||
18 | This ensures the fan is already running before userspace | ||
19 | takes over. | ||
20 | |||
21 | Example: | ||
22 | fan-max6650: max6650@1b { | ||
23 | reg = <0x1b>; | ||
24 | compatible = "maxim,max6650"; | ||
25 | maxim,fan-microvolt = <12000000>; | ||
26 | maxim,fan-prescale = <4>; | ||
27 | maxim,fan-target-rpm = <1200>; | ||
28 | }; | ||
diff --git a/Documentation/hwmon/adt7470 b/Documentation/hwmon/adt7470 index 8ce4aa0a0f55..fe68e18a0c8d 100644 --- a/Documentation/hwmon/adt7470 +++ b/Documentation/hwmon/adt7470 | |||
@@ -65,6 +65,23 @@ from 0 (off) to 255 (full speed). Fan speed will be set to maximum when the | |||
65 | temperature sensor associated with the PWM control exceeds | 65 | temperature sensor associated with the PWM control exceeds |
66 | pwm#_auto_point2_temp. | 66 | pwm#_auto_point2_temp. |
67 | 67 | ||
68 | The driver also allows control of the PWM frequency: | ||
69 | |||
70 | * pwm1_freq | ||
71 | |||
72 | The PWM frequency is rounded to the nearest one of: | ||
73 | |||
74 | * 11.0 Hz | ||
75 | * 14.7 Hz | ||
76 | * 22.1 Hz | ||
77 | * 29.4 Hz | ||
78 | * 35.3 Hz | ||
79 | * 44.1 Hz | ||
80 | * 58.8 Hz | ||
81 | * 88.2 Hz | ||
82 | * 1.4 kHz | ||
83 | * 22.5 kHz | ||
84 | |||
68 | Notes | 85 | Notes |
69 | ----- | 86 | ----- |
70 | 87 | ||
diff --git a/Documentation/hwmon/hwmon-kernel-api.txt b/Documentation/hwmon/hwmon-kernel-api.txt index 2ecdbfc85ecf..ef9d74947f5c 100644 --- a/Documentation/hwmon/hwmon-kernel-api.txt +++ b/Documentation/hwmon/hwmon-kernel-api.txt | |||
@@ -34,6 +34,19 @@ devm_hwmon_device_register_with_groups(struct device *dev, | |||
34 | const char *name, void *drvdata, | 34 | const char *name, void *drvdata, |
35 | const struct attribute_group **groups); | 35 | const struct attribute_group **groups); |
36 | 36 | ||
37 | struct device * | ||
38 | hwmon_device_register_with_info(struct device *dev, | ||
39 | const char *name, void *drvdata, | ||
40 | const struct hwmon_chip_info *info, | ||
41 | const struct attribute_group **groups); | ||
42 | |||
43 | struct device * | ||
44 | devm_hwmon_device_register_with_info(struct device *dev, | ||
45 | const char *name, | ||
46 | void *drvdata, | ||
47 | const struct hwmon_chip_info *info, | ||
48 | const struct attribute_group **groups); | ||
49 | |||
37 | void hwmon_device_unregister(struct device *dev); | 50 | void hwmon_device_unregister(struct device *dev); |
38 | void devm_hwmon_device_unregister(struct device *dev); | 51 | void devm_hwmon_device_unregister(struct device *dev); |
39 | 52 | ||
@@ -60,15 +73,229 @@ devm_hwmon_device_register_with_groups is similar to | |||
60 | hwmon_device_register_with_groups. However, it is device managed, meaning the | 73 | hwmon_device_register_with_groups. However, it is device managed, meaning the |
61 | hwmon device does not have to be removed explicitly by the removal function. | 74 | hwmon device does not have to be removed explicitly by the removal function. |
62 | 75 | ||
76 | hwmon_device_register_with_info is the most comprehensive and preferred means | ||
77 | to register a hardware monitoring device. It creates the standard sysfs | ||
78 | attributes in the hardware monitoring core, letting the driver focus on reading | ||
79 | from and writing to the chip instead of having to bother with sysfs attributes. | ||
80 | Its parameters are described in more detail below. | ||
81 | |||
82 | devm_hwmon_device_register_with_info is similar to | ||
83 | hwmon_device_register_with_info. However, it is device managed, meaning the | ||
84 | hwmon device does not have to be removed explicitly by the removal function. | ||
85 | |||
63 | hwmon_device_unregister deregisters a registered hardware monitoring device. | 86 | hwmon_device_unregister deregisters a registered hardware monitoring device. |
64 | The parameter of this function is the pointer to the registered hardware | 87 | The parameter of this function is the pointer to the registered hardware |
65 | monitoring device structure. This function must be called from the driver | 88 | monitoring device structure. This function must be called from the driver |
66 | remove function if the hardware monitoring device was registered with | 89 | remove function if the hardware monitoring device was registered with |
67 | hwmon_device_register or with hwmon_device_register_with_groups. | 90 | hwmon_device_register, hwmon_device_register_with_groups, or |
91 | hwmon_device_register_with_info. | ||
68 | 92 | ||
69 | devm_hwmon_device_unregister does not normally have to be called. It is only | 93 | devm_hwmon_device_unregister does not normally have to be called. It is only |
70 | needed for error handling, and only needed if the driver probe fails after | 94 | needed for error handling, and only needed if the driver probe fails after |
71 | the call to devm_hwmon_device_register_with_groups. | 95 | the call to devm_hwmon_device_register_with_groups and if the automatic |
96 | (device managed) removal would be too late. | ||
97 | |||
98 | Using devm_hwmon_device_register_with_info() | ||
99 | -------------------------------------------- | ||
100 | |||
101 | hwmon_device_register_with_info() registers a hardware monitoring device. | ||
102 | The parameters to this function are | ||
103 | |||
104 | struct device *dev Pointer to parent device | ||
105 | const char *name Device name | ||
106 | void *drvdata Driver private data | ||
107 | const struct hwmon_chip_info *info | ||
108 | Pointer to chip description. | ||
109 | const struct attribute_group **groups | ||
110 | Null-terminated list of additional sysfs attribute | ||
111 | groups. | ||
112 | |||
113 | This function returns a pointer to the created hardware monitoring device | ||
114 | on success and a negative error code for failure. | ||
115 | |||
116 | The hwmon_chip_info structure looks as follows. | ||
117 | |||
118 | struct hwmon_chip_info { | ||
119 | const struct hwmon_ops *ops; | ||
120 | const struct hwmon_channel_info **info; | ||
121 | }; | ||
122 | |||
123 | It contains the following fields: | ||
124 | |||
125 | * ops: Pointer to device operations. | ||
126 | * info: NULL-terminated list of device channel descriptors. | ||
127 | |||
128 | The list of hwmon operations is defined as: | ||
129 | |||
130 | struct hwmon_ops { | ||
131 | umode_t (*is_visible)(const void *, enum hwmon_sensor_types type, | ||
132 | u32 attr, int); | ||
133 | int (*read)(struct device *, enum hwmon_sensor_types type, | ||
134 | u32 attr, int, long *); | ||
135 | int (*write)(struct device *, enum hwmon_sensor_types type, | ||
136 | u32 attr, int, long); | ||
137 | }; | ||
138 | |||
139 | It defines the following operations. | ||
140 | |||
141 | * is_visible: Pointer to a function to return the file mode for each supported | ||
142 | attribute. This function is mandatory. | ||
143 | |||
144 | * read: Pointer to a function for reading a value from the chip. This function | ||
145 | is optional, but must be provided if any readable attributes exist. | ||
146 | |||
147 | * write: Pointer to a function for writing a value to the chip. This function is | ||
148 | optional, but must be provided if any writeable attributes exist. | ||
149 | |||
150 | Each sensor channel is described with struct hwmon_channel_info, which is | ||
151 | defined as follows. | ||
152 | |||
153 | struct hwmon_channel_info { | ||
154 | enum hwmon_sensor_types type; | ||
155 | u32 *config; | ||
156 | }; | ||
157 | |||
158 | It contains following fields: | ||
159 | |||
160 | * type: The hardware monitoring sensor type. | ||
161 | Supported sensor types are | ||
162 | * hwmon_chip A virtual sensor type, used to describe attributes | ||
163 | which apply to the entire chip. | ||
164 | * hwmon_temp Temperature sensor | ||
165 | * hwmon_in Voltage sensor | ||
166 | * hwmon_curr Current sensor | ||
167 | * hwmon_power Power sensor | ||
168 | * hwmon_energy Energy sensor | ||
169 | * hwmon_humidity Humidity sensor | ||
170 | * hwmon_fan Fan speed sensor | ||
171 | * hwmon_pwm PWM control | ||
172 | |||
173 | * config: Pointer to a 0-terminated list of configuration values for each | ||
174 | sensor of the given type. Each value is a combination of bit values | ||
175 | describing the attributes supposed by a single sensor. | ||
176 | |||
177 | As an example, here is the complete description file for a LM75 compatible | ||
178 | sensor chip. The chip has a single temperature sensor. The driver wants to | ||
179 | register with the thermal subsystem (HWMON_C_REGISTER_TZ), and it supports | ||
180 | the update_interval attribute (HWMON_C_UPDATE_INTERVAL). The chip supports | ||
181 | reading the temperature (HWMON_T_INPUT), it has a maximum temperature | ||
182 | register (HWMON_T_MAX) as well as a maximum temperature hysteresis register | ||
183 | (HWMON_T_MAX_HYST). | ||
184 | |||
185 | static const u32 lm75_chip_config[] = { | ||
186 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL, | ||
187 | 0 | ||
188 | }; | ||
189 | |||
190 | static const struct hwmon_channel_info lm75_chip = { | ||
191 | .type = hwmon_chip, | ||
192 | .config = lm75_chip_config, | ||
193 | }; | ||
194 | |||
195 | static const u32 lm75_temp_config[] = { | ||
196 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST, | ||
197 | 0 | ||
198 | }; | ||
199 | |||
200 | static const struct hwmon_channel_info lm75_temp = { | ||
201 | .type = hwmon_temp, | ||
202 | .config = lm75_temp_config, | ||
203 | }; | ||
204 | |||
205 | static const struct hwmon_channel_info *lm75_info[] = { | ||
206 | &lm75_chip, | ||
207 | &lm75_temp, | ||
208 | NULL | ||
209 | }; | ||
210 | |||
211 | static const struct hwmon_ops lm75_hwmon_ops = { | ||
212 | .is_visible = lm75_is_visible, | ||
213 | .read = lm75_read, | ||
214 | .write = lm75_write, | ||
215 | }; | ||
216 | |||
217 | static const struct hwmon_chip_info lm75_chip_info = { | ||
218 | .ops = &lm75_hwmon_ops, | ||
219 | .info = lm75_info, | ||
220 | }; | ||
221 | |||
222 | A complete list of bit values indicating individual attribute support | ||
223 | is defined in include/linux/hwmon.h. Definition prefixes are as follows. | ||
224 | |||
225 | HWMON_C_xxxx Chip attributes, for use with hwmon_chip. | ||
226 | HWMON_T_xxxx Temperature attributes, for use with hwmon_temp. | ||
227 | HWMON_I_xxxx Voltage attributes, for use with hwmon_in. | ||
228 | HWMON_C_xxxx Current attributes, for use with hwmon_curr. | ||
229 | Notice the prefix overlap with chip attributes. | ||
230 | HWMON_P_xxxx Power attributes, for use with hwmon_power. | ||
231 | HWMON_E_xxxx Energy attributes, for use with hwmon_energy. | ||
232 | HWMON_H_xxxx Humidity attributes, for use with hwmon_humidity. | ||
233 | HWMON_F_xxxx Fan speed attributes, for use with hwmon_fan. | ||
234 | HWMON_PWM_xxxx PWM control attributes, for use with hwmon_pwm. | ||
235 | |||
236 | Driver callback functions | ||
237 | ------------------------- | ||
238 | |||
239 | Each driver provides is_visible, read, and write functions. Parameters | ||
240 | and return values for those functions are as follows. | ||
241 | |||
242 | umode_t is_visible_func(const void *data, enum hwmon_sensor_types type, | ||
243 | u32 attr, int channel) | ||
244 | |||
245 | Parameters: | ||
246 | data: Pointer to device private data structure. | ||
247 | type: The sensor type. | ||
248 | attr: Attribute identifier associated with a specific attribute. | ||
249 | For example, the attribute value for HWMON_T_INPUT would be | ||
250 | hwmon_temp_input. For complete mappings of bit fields to | ||
251 | attribute values please see include/linux/hwmon.h. | ||
252 | channel:The sensor channel number. | ||
253 | |||
254 | Return value: | ||
255 | The file mode for this attribute. Typically, this will be 0 (the | ||
256 | attribute will not be created), S_IRUGO, or 'S_IRUGO | S_IWUSR'. | ||
257 | |||
258 | int read_func(struct device *dev, enum hwmon_sensor_types type, | ||
259 | u32 attr, int channel, long *val) | ||
260 | |||
261 | Parameters: | ||
262 | dev: Pointer to the hardware monitoring device. | ||
263 | type: The sensor type. | ||
264 | attr: Attribute identifier associated with a specific attribute. | ||
265 | For example, the attribute value for HWMON_T_INPUT would be | ||
266 | hwmon_temp_input. For complete mappings please see | ||
267 | include/linux/hwmon.h. | ||
268 | channel:The sensor channel number. | ||
269 | val: Pointer to attribute value. | ||
270 | |||
271 | Return value: | ||
272 | 0 on success, a negative error number otherwise. | ||
273 | |||
274 | int write_func(struct device *dev, enum hwmon_sensor_types type, | ||
275 | u32 attr, int channel, long val) | ||
276 | |||
277 | Parameters: | ||
278 | dev: Pointer to the hardware monitoring device. | ||
279 | type: The sensor type. | ||
280 | attr: Attribute identifier associated with a specific attribute. | ||
281 | For example, the attribute value for HWMON_T_INPUT would be | ||
282 | hwmon_temp_input. For complete mappings please see | ||
283 | include/linux/hwmon.h. | ||
284 | channel:The sensor channel number. | ||
285 | val: The value to write to the chip. | ||
286 | |||
287 | Return value: | ||
288 | 0 on success, a negative error number otherwise. | ||
289 | |||
290 | |||
291 | Driver-provided sysfs attributes | ||
292 | -------------------------------- | ||
293 | |||
294 | If the hardware monitoring device is registered with | ||
295 | hwmon_device_register_with_info or devm_hwmon_device_register_with_info, | ||
296 | it is most likely not necessary to provide sysfs attributes. Only non-standard | ||
297 | sysfs attributes need to be provided when one of those registration functions | ||
298 | is used. | ||
72 | 299 | ||
73 | The header file linux/hwmon-sysfs.h provides a number of useful macros to | 300 | The header file linux/hwmon-sysfs.h provides a number of useful macros to |
74 | declare and use hardware monitoring sysfs attributes. | 301 | declare and use hardware monitoring sysfs attributes. |
diff --git a/Documentation/hwmon/max6650 b/Documentation/hwmon/max6650 index 58d9644a2bde..dff1d296a48b 100644 --- a/Documentation/hwmon/max6650 +++ b/Documentation/hwmon/max6650 | |||
@@ -34,6 +34,7 @@ fan3_input ro " | |||
34 | fan4_input ro " | 34 | fan4_input ro " |
35 | fan1_target rw desired fan speed in RPM (closed loop mode only) | 35 | fan1_target rw desired fan speed in RPM (closed loop mode only) |
36 | pwm1_enable rw regulator mode, 0=full on, 1=open loop, 2=closed loop | 36 | pwm1_enable rw regulator mode, 0=full on, 1=open loop, 2=closed loop |
37 | 3=off | ||
37 | pwm1 rw relative speed (0-255), 255=max. speed. | 38 | pwm1 rw relative speed (0-255), 255=max. speed. |
38 | Used in open loop mode only. | 39 | Used in open loop mode only. |
39 | fan1_div rw sets the speed range the inputs can handle. Legal | 40 | fan1_div rw sets the speed range the inputs can handle. Legal |
diff --git a/Documentation/hwmon/ucd9000 b/Documentation/hwmon/ucd9000 index 805e33edb978..262e713e60ff 100644 --- a/Documentation/hwmon/ucd9000 +++ b/Documentation/hwmon/ucd9000 | |||
@@ -2,12 +2,13 @@ Kernel driver ucd9000 | |||
2 | ===================== | 2 | ===================== |
3 | 3 | ||
4 | Supported chips: | 4 | Supported chips: |
5 | * TI UCD90120, UCD90124, UCD9090, and UCD90910 | 5 | * TI UCD90120, UCD90124, UCD90160, UCD9090, and UCD90910 |
6 | Prefixes: 'ucd90120', 'ucd90124', 'ucd9090', 'ucd90910' | 6 | Prefixes: 'ucd90120', 'ucd90124', 'ucd90160', 'ucd9090', 'ucd90910' |
7 | Addresses scanned: - | 7 | Addresses scanned: - |
8 | Datasheets: | 8 | Datasheets: |
9 | http://focus.ti.com/lit/ds/symlink/ucd90120.pdf | 9 | http://focus.ti.com/lit/ds/symlink/ucd90120.pdf |
10 | http://focus.ti.com/lit/ds/symlink/ucd90124.pdf | 10 | http://focus.ti.com/lit/ds/symlink/ucd90124.pdf |
11 | http://focus.ti.com/lit/ds/symlink/ucd90160.pdf | ||
11 | http://focus.ti.com/lit/ds/symlink/ucd9090.pdf | 12 | http://focus.ti.com/lit/ds/symlink/ucd9090.pdf |
12 | http://focus.ti.com/lit/ds/symlink/ucd90910.pdf | 13 | http://focus.ti.com/lit/ds/symlink/ucd90910.pdf |
13 | 14 | ||
@@ -32,6 +33,13 @@ 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 | functionality. Using these pins, the UCD90124 offers support for fan control, |
33 | margining, and general-purpose PWM functions. | 34 | margining, and general-purpose PWM functions. |
34 | 35 | ||
36 | The UCD90160 is a 16-rail PMBus/I2C addressable power-supply sequencer and | ||
37 | monitor. The device integrates a 12-bit ADC for monitoring up to 16 power-supply | ||
38 | voltage inputs. Twenty-six GPIO pins can be used for power supply enables, | ||
39 | power-on reset signals, external interrupts, cascading, or other system | ||
40 | functions. Twelve of these pins offer PWM functionality. Using these pins, the | ||
41 | UCD90160 offers support for margining, and general-purpose PWM functions. | ||
42 | |||
35 | The UCD9090 is a 10-rail PMBus/I2C addressable power-supply sequencer and | 43 | 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 | 44 | 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, | 45 | voltage inputs. Twenty-three GPIO pins can be used for power supply enables, |
diff --git a/Documentation/hwmon/xgene-hwmon b/Documentation/hwmon/xgene-hwmon new file mode 100644 index 000000000000..6ec50ed7cc8f --- /dev/null +++ b/Documentation/hwmon/xgene-hwmon | |||
@@ -0,0 +1,30 @@ | |||
1 | Kernel driver xgene-hwmon | ||
2 | ======================== | ||
3 | |||
4 | Supported chips: | ||
5 | * APM X-Gene SoC | ||
6 | |||
7 | Description | ||
8 | ----------- | ||
9 | |||
10 | This driver adds hardware temperature and power reading support for | ||
11 | APM X-Gene SoC using the mailbox communication interface. | ||
12 | For device tree, it is the standard DT mailbox. | ||
13 | For ACPI, it is the PCC mailbox. | ||
14 | |||
15 | The following sensors are supported | ||
16 | |||
17 | * Temperature | ||
18 | - SoC on-die temperature in milli-degree C | ||
19 | - Alarm when high/over temperature occurs | ||
20 | * Power | ||
21 | - CPU power in uW | ||
22 | - IO power in uW | ||
23 | |||
24 | sysfs-Interface | ||
25 | --------------- | ||
26 | |||
27 | temp0_input - SoC on-die temperature (milli-degree C) | ||
28 | temp0_critical_alarm - An 1 would indicates on-die temperature exceeded threshold | ||
29 | power0_input - CPU power in (uW) | ||
30 | power1_input - IO power in (uW) | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index eaf2f916d48c..45cef3d2c75c 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -969,7 +969,6 @@ config SENSORS_LM73 | |||
969 | config SENSORS_LM75 | 969 | config SENSORS_LM75 |
970 | tristate "National Semiconductor LM75 and compatibles" | 970 | tristate "National Semiconductor LM75 and compatibles" |
971 | depends on I2C | 971 | depends on I2C |
972 | depends on THERMAL || !THERMAL_OF | ||
973 | select REGMAP_I2C | 972 | select REGMAP_I2C |
974 | help | 973 | help |
975 | If you say yes here you get support for one common type of | 974 | If you say yes here you get support for one common type of |
@@ -1119,6 +1118,7 @@ config SENSORS_LM95241 | |||
1119 | config SENSORS_LM95245 | 1118 | config SENSORS_LM95245 |
1120 | tristate "National Semiconductor LM95245 and compatibles" | 1119 | tristate "National Semiconductor LM95245 and compatibles" |
1121 | depends on I2C | 1120 | depends on I2C |
1121 | select REGMAP_I2C | ||
1122 | help | 1122 | help |
1123 | If you say yes here you get support for LM95235 and LM95245 | 1123 | If you say yes here you get support for LM95235 and LM95245 |
1124 | temperature sensor chips. | 1124 | temperature sensor chips. |
@@ -1572,7 +1572,6 @@ config SENSORS_THMC50 | |||
1572 | config SENSORS_TMP102 | 1572 | config SENSORS_TMP102 |
1573 | tristate "Texas Instruments TMP102" | 1573 | tristate "Texas Instruments TMP102" |
1574 | depends on I2C | 1574 | depends on I2C |
1575 | depends on THERMAL || !THERMAL_OF | ||
1576 | select REGMAP_I2C | 1575 | select REGMAP_I2C |
1577 | help | 1576 | help |
1578 | If you say yes here you get support for Texas Instruments TMP102 | 1577 | If you say yes here you get support for Texas Instruments TMP102 |
@@ -1823,6 +1822,13 @@ config SENSORS_ULTRA45 | |||
1823 | This driver provides support for the Ultra45 workstation environmental | 1822 | This driver provides support for the Ultra45 workstation environmental |
1824 | sensors. | 1823 | sensors. |
1825 | 1824 | ||
1825 | config SENSORS_XGENE | ||
1826 | tristate "APM X-Gene SoC hardware monitoring driver" | ||
1827 | depends on XGENE_SLIMPRO_MBOX || PCC | ||
1828 | help | ||
1829 | If you say yes here you get support for the temperature | ||
1830 | and power sensors for APM X-Gene SoC. | ||
1831 | |||
1826 | if ACPI | 1832 | if ACPI |
1827 | 1833 | ||
1828 | comment "ACPI drivers" | 1834 | comment "ACPI drivers" |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index fe87d2895a97..aecf4ba17460 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -165,6 +165,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o | |||
165 | obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o | 165 | obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o |
166 | obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o | 166 | obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o |
167 | obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o | 167 | obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o |
168 | obj-$(CONFIG_SENSORS_XGENE) += xgene-hwmon.o | ||
168 | 169 | ||
169 | obj-$(CONFIG_PMBUS) += pmbus/ | 170 | obj-$(CONFIG_PMBUS) += pmbus/ |
170 | 171 | ||
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index fc1e65a263a4..812fbc00f693 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c | |||
@@ -7,8 +7,7 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * TODO: SPI, support for external temperature sensor | 10 | * TODO: SPI, use power-down mode for suspend?, interrupt handling? |
11 | * use power-down mode for suspend?, interrupt handling? | ||
12 | */ | 11 | */ |
13 | 12 | ||
14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
@@ -31,6 +30,7 @@ | |||
31 | #define ADT7411_REG_CFG1 0x18 | 30 | #define ADT7411_REG_CFG1 0x18 |
32 | #define ADT7411_CFG1_START_MONITOR (1 << 0) | 31 | #define ADT7411_CFG1_START_MONITOR (1 << 0) |
33 | #define ADT7411_CFG1_RESERVED_BIT1 (1 << 1) | 32 | #define ADT7411_CFG1_RESERVED_BIT1 (1 << 1) |
33 | #define ADT7411_CFG1_EXT_TDM (1 << 2) | ||
34 | #define ADT7411_CFG1_RESERVED_BIT3 (1 << 3) | 34 | #define ADT7411_CFG1_RESERVED_BIT3 (1 << 3) |
35 | 35 | ||
36 | #define ADT7411_REG_CFG2 0x19 | 36 | #define ADT7411_REG_CFG2 0x19 |
@@ -57,6 +57,7 @@ struct adt7411_data { | |||
57 | unsigned long next_update; | 57 | unsigned long next_update; |
58 | int vref_cached; | 58 | int vref_cached; |
59 | struct i2c_client *client; | 59 | struct i2c_client *client; |
60 | bool use_ext_temp; | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | /* | 63 | /* |
@@ -127,11 +128,20 @@ static ssize_t adt7411_show_vdd(struct device *dev, | |||
127 | static ssize_t adt7411_show_temp(struct device *dev, | 128 | static ssize_t adt7411_show_temp(struct device *dev, |
128 | struct device_attribute *attr, char *buf) | 129 | struct device_attribute *attr, char *buf) |
129 | { | 130 | { |
131 | int nr = to_sensor_dev_attr(attr)->index; | ||
130 | struct adt7411_data *data = dev_get_drvdata(dev); | 132 | struct adt7411_data *data = dev_get_drvdata(dev); |
131 | struct i2c_client *client = data->client; | 133 | struct i2c_client *client = data->client; |
132 | int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB, | 134 | int val; |
133 | ADT7411_REG_INT_TEMP_MSB, 0); | 135 | struct { |
134 | 136 | u8 low; | |
137 | u8 high; | ||
138 | } reg[2] = { | ||
139 | { ADT7411_REG_INT_TEMP_VDD_LSB, ADT7411_REG_INT_TEMP_MSB }, | ||
140 | { ADT7411_REG_EXT_TEMP_AIN14_LSB, | ||
141 | ADT7411_REG_EXT_TEMP_AIN1_MSB }, | ||
142 | }; | ||
143 | |||
144 | val = adt7411_read_10_bit(client, reg[nr].low, reg[nr].high, 0); | ||
135 | if (val < 0) | 145 | if (val < 0) |
136 | return val; | 146 | return val; |
137 | 147 | ||
@@ -218,11 +228,13 @@ static ssize_t adt7411_set_bit(struct device *dev, | |||
218 | return ret < 0 ? ret : count; | 228 | return ret < 0 ? ret : count; |
219 | } | 229 | } |
220 | 230 | ||
231 | |||
221 | #define ADT7411_BIT_ATTR(__name, __reg, __bit) \ | 232 | #define ADT7411_BIT_ATTR(__name, __reg, __bit) \ |
222 | SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \ | 233 | SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \ |
223 | adt7411_set_bit, __bit, __reg) | 234 | adt7411_set_bit, __bit, __reg) |
224 | 235 | ||
225 | static DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL); | 236 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL, 0); |
237 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, adt7411_show_temp, NULL, 1); | ||
226 | static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL); | 238 | static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL); |
227 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0); | 239 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0); |
228 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1); | 240 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1); |
@@ -237,7 +249,8 @@ static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_22 | |||
237 | static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD); | 249 | static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD); |
238 | 250 | ||
239 | static struct attribute *adt7411_attrs[] = { | 251 | static struct attribute *adt7411_attrs[] = { |
240 | &dev_attr_temp1_input.attr, | 252 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
253 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
241 | &dev_attr_in0_input.attr, | 254 | &dev_attr_in0_input.attr, |
242 | &sensor_dev_attr_in1_input.dev_attr.attr, | 255 | &sensor_dev_attr_in1_input.dev_attr.attr, |
243 | &sensor_dev_attr_in2_input.dev_attr.attr, | 256 | &sensor_dev_attr_in2_input.dev_attr.attr, |
@@ -253,7 +266,27 @@ static struct attribute *adt7411_attrs[] = { | |||
253 | NULL | 266 | NULL |
254 | }; | 267 | }; |
255 | 268 | ||
256 | ATTRIBUTE_GROUPS(adt7411); | 269 | static umode_t adt7411_attrs_visible(struct kobject *kobj, |
270 | struct attribute *attr, int index) | ||
271 | { | ||
272 | struct device *dev = container_of(kobj, struct device, kobj); | ||
273 | struct adt7411_data *data = dev_get_drvdata(dev); | ||
274 | bool visible = true; | ||
275 | |||
276 | if (attr == &sensor_dev_attr_temp2_input.dev_attr.attr) | ||
277 | visible = data->use_ext_temp; | ||
278 | else if (attr == &sensor_dev_attr_in1_input.dev_attr.attr || | ||
279 | attr == &sensor_dev_attr_in2_input.dev_attr.attr) | ||
280 | visible = !data->use_ext_temp; | ||
281 | |||
282 | return visible ? attr->mode : 0; | ||
283 | } | ||
284 | |||
285 | static const struct attribute_group adt7411_group = { | ||
286 | .attrs = adt7411_attrs, | ||
287 | .is_visible = adt7411_attrs_visible, | ||
288 | }; | ||
289 | __ATTRIBUTE_GROUPS(adt7411); | ||
257 | 290 | ||
258 | static int adt7411_detect(struct i2c_client *client, | 291 | static int adt7411_detect(struct i2c_client *client, |
259 | struct i2c_board_info *info) | 292 | struct i2c_board_info *info) |
@@ -309,6 +342,8 @@ static int adt7411_init_device(struct adt7411_data *data) | |||
309 | if (ret < 0) | 342 | if (ret < 0) |
310 | return ret; | 343 | return ret; |
311 | 344 | ||
345 | data->use_ext_temp = ret & ADT7411_CFG1_EXT_TDM; | ||
346 | |||
312 | /* | 347 | /* |
313 | * We must only write zero to bit 1 and only one to bit 3 according to | 348 | * We must only write zero to bit 1 and only one to bit 3 according to |
314 | * the datasheet. | 349 | * the datasheet. |
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index f5da39a68929..6e60ca53406e 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/log2.h> | 32 | #include <linux/log2.h> |
33 | #include <linux/kthread.h> | 33 | #include <linux/kthread.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/util_macros.h> | ||
35 | 36 | ||
36 | /* Addresses to scan */ | 37 | /* Addresses to scan */ |
37 | static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; | 38 | static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; |
@@ -83,6 +84,7 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; | |||
83 | #define ADT7470_REG_PWM_MIN_MAX_ADDR 0x6D | 84 | #define ADT7470_REG_PWM_MIN_MAX_ADDR 0x6D |
84 | #define ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR 0x6E | 85 | #define ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR 0x6E |
85 | #define ADT7470_REG_PWM_TEMP_MIN_MAX_ADDR 0x71 | 86 | #define ADT7470_REG_PWM_TEMP_MIN_MAX_ADDR 0x71 |
87 | #define ADT7470_REG_CFG_2 0x74 | ||
86 | #define ADT7470_REG_ACOUSTICS12 0x75 | 88 | #define ADT7470_REG_ACOUSTICS12 0x75 |
87 | #define ADT7470_REG_ACOUSTICS34 0x76 | 89 | #define ADT7470_REG_ACOUSTICS34 0x76 |
88 | #define ADT7470_REG_DEVICE 0x3D | 90 | #define ADT7470_REG_DEVICE 0x3D |
@@ -142,6 +144,11 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; | |||
142 | #define FAN_PERIOD_INVALID 65535 | 144 | #define FAN_PERIOD_INVALID 65535 |
143 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 145 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
144 | 146 | ||
147 | /* Config registers 1 and 2 include fields for selecting the PWM frequency */ | ||
148 | #define ADT7470_CFG_LF 0x40 | ||
149 | #define ADT7470_FREQ_MASK 0x70 | ||
150 | #define ADT7470_FREQ_SHIFT 4 | ||
151 | |||
145 | struct adt7470_data { | 152 | struct adt7470_data { |
146 | struct i2c_client *client; | 153 | struct i2c_client *client; |
147 | struct mutex lock; | 154 | struct mutex lock; |
@@ -170,7 +177,6 @@ struct adt7470_data { | |||
170 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; | 177 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; |
171 | 178 | ||
172 | struct task_struct *auto_update; | 179 | struct task_struct *auto_update; |
173 | struct completion auto_update_stop; | ||
174 | unsigned int auto_update_interval; | 180 | unsigned int auto_update_interval; |
175 | }; | 181 | }; |
176 | 182 | ||
@@ -266,12 +272,14 @@ static int adt7470_update_thread(void *p) | |||
266 | mutex_lock(&data->lock); | 272 | mutex_lock(&data->lock); |
267 | adt7470_read_temperatures(client, data); | 273 | adt7470_read_temperatures(client, data); |
268 | mutex_unlock(&data->lock); | 274 | mutex_unlock(&data->lock); |
275 | |||
276 | set_current_state(TASK_INTERRUPTIBLE); | ||
269 | if (kthread_should_stop()) | 277 | if (kthread_should_stop()) |
270 | break; | 278 | break; |
271 | msleep_interruptible(data->auto_update_interval); | 279 | |
280 | schedule_timeout(msecs_to_jiffies(data->auto_update_interval)); | ||
272 | } | 281 | } |
273 | 282 | ||
274 | complete_all(&data->auto_update_stop); | ||
275 | return 0; | 283 | return 0; |
276 | } | 284 | } |
277 | 285 | ||
@@ -538,6 +546,28 @@ static ssize_t show_alarm_mask(struct device *dev, | |||
538 | return sprintf(buf, "%x\n", data->alarms_mask); | 546 | return sprintf(buf, "%x\n", data->alarms_mask); |
539 | } | 547 | } |
540 | 548 | ||
549 | static ssize_t set_alarm_mask(struct device *dev, | ||
550 | struct device_attribute *devattr, | ||
551 | const char *buf, | ||
552 | size_t count) | ||
553 | { | ||
554 | struct adt7470_data *data = dev_get_drvdata(dev); | ||
555 | long mask; | ||
556 | |||
557 | if (kstrtoul(buf, 0, &mask)) | ||
558 | return -EINVAL; | ||
559 | |||
560 | if (mask & ~0xffff) | ||
561 | return -EINVAL; | ||
562 | |||
563 | mutex_lock(&data->lock); | ||
564 | data->alarms_mask = mask; | ||
565 | adt7470_write_word_data(data->client, ADT7470_REG_ALARM1_MASK, mask); | ||
566 | mutex_unlock(&data->lock); | ||
567 | |||
568 | return count; | ||
569 | } | ||
570 | |||
541 | static ssize_t show_fan_max(struct device *dev, | 571 | static ssize_t show_fan_max(struct device *dev, |
542 | struct device_attribute *devattr, | 572 | struct device_attribute *devattr, |
543 | char *buf) | 573 | char *buf) |
@@ -688,6 +718,70 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
688 | return count; | 718 | return count; |
689 | } | 719 | } |
690 | 720 | ||
721 | /* These are the valid PWM frequencies to the nearest Hz */ | ||
722 | static const int adt7470_freq_map[] = { | ||
723 | 11, 15, 22, 29, 35, 44, 59, 88, 1400, 22500 | ||
724 | }; | ||
725 | |||
726 | static ssize_t show_pwm_freq(struct device *dev, | ||
727 | struct device_attribute *devattr, char *buf) | ||
728 | { | ||
729 | struct adt7470_data *data = adt7470_update_device(dev); | ||
730 | unsigned char cfg_reg_1; | ||
731 | unsigned char cfg_reg_2; | ||
732 | int index; | ||
733 | |||
734 | mutex_lock(&data->lock); | ||
735 | cfg_reg_1 = i2c_smbus_read_byte_data(data->client, ADT7470_REG_CFG); | ||
736 | cfg_reg_2 = i2c_smbus_read_byte_data(data->client, ADT7470_REG_CFG_2); | ||
737 | mutex_unlock(&data->lock); | ||
738 | |||
739 | index = (cfg_reg_2 & ADT7470_FREQ_MASK) >> ADT7470_FREQ_SHIFT; | ||
740 | if (!(cfg_reg_1 & ADT7470_CFG_LF)) | ||
741 | index += 8; | ||
742 | if (index >= ARRAY_SIZE(adt7470_freq_map)) | ||
743 | index = ARRAY_SIZE(adt7470_freq_map) - 1; | ||
744 | |||
745 | return scnprintf(buf, PAGE_SIZE, "%d\n", adt7470_freq_map[index]); | ||
746 | } | ||
747 | |||
748 | static ssize_t set_pwm_freq(struct device *dev, | ||
749 | struct device_attribute *devattr, | ||
750 | const char *buf, size_t count) | ||
751 | { | ||
752 | struct adt7470_data *data = dev_get_drvdata(dev); | ||
753 | struct i2c_client *client = data->client; | ||
754 | long freq; | ||
755 | int index; | ||
756 | int low_freq = ADT7470_CFG_LF; | ||
757 | unsigned char val; | ||
758 | |||
759 | if (kstrtol(buf, 10, &freq)) | ||
760 | return -EINVAL; | ||
761 | |||
762 | /* Round the user value given to the closest available frequency */ | ||
763 | index = find_closest(freq, adt7470_freq_map, | ||
764 | ARRAY_SIZE(adt7470_freq_map)); | ||
765 | |||
766 | if (index >= 8) { | ||
767 | index -= 8; | ||
768 | low_freq = 0; | ||
769 | } | ||
770 | |||
771 | mutex_lock(&data->lock); | ||
772 | /* Configuration Register 1 */ | ||
773 | val = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | ||
774 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, | ||
775 | (val & ~ADT7470_CFG_LF) | low_freq); | ||
776 | /* Configuration Register 2 */ | ||
777 | val = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG_2); | ||
778 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG_2, | ||
779 | (val & ~ADT7470_FREQ_MASK) | (index << ADT7470_FREQ_SHIFT)); | ||
780 | mutex_unlock(&data->lock); | ||
781 | |||
782 | return count; | ||
783 | } | ||
784 | |||
691 | static ssize_t show_pwm_max(struct device *dev, | 785 | static ssize_t show_pwm_max(struct device *dev, |
692 | struct device_attribute *devattr, | 786 | struct device_attribute *devattr, |
693 | char *buf) | 787 | char *buf) |
@@ -918,7 +1012,8 @@ static ssize_t show_alarm(struct device *dev, | |||
918 | return sprintf(buf, "0\n"); | 1012 | return sprintf(buf, "0\n"); |
919 | } | 1013 | } |
920 | 1014 | ||
921 | static DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarm_mask, NULL); | 1015 | static DEVICE_ATTR(alarm_mask, S_IWUSR | S_IRUGO, show_alarm_mask, |
1016 | set_alarm_mask); | ||
922 | static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, | 1017 | static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, |
923 | set_num_temp_sensors); | 1018 | set_num_temp_sensors); |
924 | static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO, | 1019 | static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO, |
@@ -1038,6 +1133,8 @@ static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); | |||
1038 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); | 1133 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); |
1039 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); | 1134 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); |
1040 | 1135 | ||
1136 | static DEVICE_ATTR(pwm1_freq, S_IWUSR | S_IRUGO, show_pwm_freq, set_pwm_freq); | ||
1137 | |||
1041 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | 1138 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, |
1042 | show_pwm_min, set_pwm_min, 0); | 1139 | show_pwm_min, set_pwm_min, 0); |
1043 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | 1140 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, |
@@ -1154,6 +1251,7 @@ static struct attribute *adt7470_attrs[] = { | |||
1154 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | 1251 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
1155 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, | 1252 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, |
1156 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1253 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1254 | &dev_attr_pwm1_freq.attr, | ||
1157 | &sensor_dev_attr_pwm2.dev_attr.attr, | 1255 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1158 | &sensor_dev_attr_pwm3.dev_attr.attr, | 1256 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1159 | &sensor_dev_attr_pwm4.dev_attr.attr, | 1257 | &sensor_dev_attr_pwm4.dev_attr.attr, |
@@ -1256,7 +1354,6 @@ static int adt7470_probe(struct i2c_client *client, | |||
1256 | if (IS_ERR(hwmon_dev)) | 1354 | if (IS_ERR(hwmon_dev)) |
1257 | return PTR_ERR(hwmon_dev); | 1355 | return PTR_ERR(hwmon_dev); |
1258 | 1356 | ||
1259 | init_completion(&data->auto_update_stop); | ||
1260 | data->auto_update = kthread_run(adt7470_update_thread, client, "%s", | 1357 | data->auto_update = kthread_run(adt7470_update_thread, client, "%s", |
1261 | dev_name(hwmon_dev)); | 1358 | dev_name(hwmon_dev)); |
1262 | if (IS_ERR(data->auto_update)) { | 1359 | if (IS_ERR(data->auto_update)) { |
@@ -1271,7 +1368,6 @@ static int adt7470_remove(struct i2c_client *client) | |||
1271 | struct adt7470_data *data = i2c_get_clientdata(client); | 1368 | struct adt7470_data *data = i2c_get_clientdata(client); |
1272 | 1369 | ||
1273 | kthread_stop(data->auto_update); | 1370 | kthread_stop(data->auto_update); |
1274 | wait_for_completion(&data->auto_update_stop); | ||
1275 | return 0; | 1371 | return 0; |
1276 | } | 1372 | } |
1277 | 1373 | ||
diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index 48633e541dc3..0f0277e7aae5 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c | |||
@@ -36,6 +36,10 @@ | |||
36 | #define FTS_EVENT_STATUS_REG 0x0006 | 36 | #define FTS_EVENT_STATUS_REG 0x0006 |
37 | #define FTS_GLOBAL_CONTROL_REG 0x0007 | 37 | #define FTS_GLOBAL_CONTROL_REG 0x0007 |
38 | 38 | ||
39 | #define FTS_DEVICE_DETECT_REG_1 0x0C | ||
40 | #define FTS_DEVICE_DETECT_REG_2 0x0D | ||
41 | #define FTS_DEVICE_DETECT_REG_3 0x0E | ||
42 | |||
39 | #define FTS_SENSOR_EVENT_REG 0x0010 | 43 | #define FTS_SENSOR_EVENT_REG 0x0010 |
40 | 44 | ||
41 | #define FTS_FAN_EVENT_REG 0x0014 | 45 | #define FTS_FAN_EVENT_REG 0x0014 |
@@ -54,6 +58,8 @@ | |||
54 | #define FTS_NO_TEMP_SENSORS 0x10 | 58 | #define FTS_NO_TEMP_SENSORS 0x10 |
55 | #define FTS_NO_VOLT_SENSORS 0x04 | 59 | #define FTS_NO_VOLT_SENSORS 0x04 |
56 | 60 | ||
61 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; | ||
62 | |||
57 | static struct i2c_device_id fts_id[] = { | 63 | static struct i2c_device_id fts_id[] = { |
58 | { "ftsteutates", 0 }, | 64 | { "ftsteutates", 0 }, |
59 | { } | 65 | { } |
@@ -734,6 +740,42 @@ static const struct attribute_group *fts_attr_groups[] = { | |||
734 | /*****************************************************************************/ | 740 | /*****************************************************************************/ |
735 | /* Module initialization / remove functions */ | 741 | /* Module initialization / remove functions */ |
736 | /*****************************************************************************/ | 742 | /*****************************************************************************/ |
743 | static int fts_detect(struct i2c_client *client, | ||
744 | struct i2c_board_info *info) | ||
745 | { | ||
746 | int val; | ||
747 | |||
748 | /* detection works with revsion greater or equal to 0x2b */ | ||
749 | val = i2c_smbus_read_byte_data(client, FTS_DEVICE_REVISION_REG); | ||
750 | if (val < 0x2b) | ||
751 | return -ENODEV; | ||
752 | |||
753 | /* Device Detect Regs must have 0x17 0x34 and 0x54 */ | ||
754 | val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_1); | ||
755 | if (val != 0x17) | ||
756 | return -ENODEV; | ||
757 | |||
758 | val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_2); | ||
759 | if (val != 0x34) | ||
760 | return -ENODEV; | ||
761 | |||
762 | val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_3); | ||
763 | if (val != 0x54) | ||
764 | return -ENODEV; | ||
765 | |||
766 | /* | ||
767 | * 0x10 == Baseboard Management Controller, 0x01 == Teutates | ||
768 | * Device ID Reg needs to be 0x11 | ||
769 | */ | ||
770 | val = i2c_smbus_read_byte_data(client, FTS_DEVICE_ID_REG); | ||
771 | if (val != 0x11) | ||
772 | return -ENODEV; | ||
773 | |||
774 | strlcpy(info->type, fts_id[0].name, I2C_NAME_SIZE); | ||
775 | info->flags = 0; | ||
776 | return 0; | ||
777 | } | ||
778 | |||
737 | static int fts_remove(struct i2c_client *client) | 779 | static int fts_remove(struct i2c_client *client) |
738 | { | 780 | { |
739 | struct fts_data *data = dev_get_drvdata(&client->dev); | 781 | struct fts_data *data = dev_get_drvdata(&client->dev); |
@@ -804,12 +846,15 @@ static int fts_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
804 | /* Module Details */ | 846 | /* Module Details */ |
805 | /*****************************************************************************/ | 847 | /*****************************************************************************/ |
806 | static struct i2c_driver fts_driver = { | 848 | static struct i2c_driver fts_driver = { |
849 | .class = I2C_CLASS_HWMON, | ||
807 | .driver = { | 850 | .driver = { |
808 | .name = "ftsteutates", | 851 | .name = "ftsteutates", |
809 | }, | 852 | }, |
810 | .id_table = fts_id, | 853 | .id_table = fts_id, |
811 | .probe = fts_probe, | 854 | .probe = fts_probe, |
812 | .remove = fts_remove, | 855 | .remove = fts_remove, |
856 | .detect = fts_detect, | ||
857 | .address_list = normal_i2c, | ||
813 | }; | 858 | }; |
814 | 859 | ||
815 | module_i2c_driver(fts_driver); | 860 | module_i2c_driver(fts_driver); |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index a26c385a435b..adae6848ffb2 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -12,17 +12,17 @@ | |||
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/bitops.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/kdev_t.h> | ||
20 | #include <linux/idr.h> | ||
21 | #include <linux/hwmon.h> | ||
22 | #include <linux/gfp.h> | 18 | #include <linux/gfp.h> |
23 | #include <linux/spinlock.h> | 19 | #include <linux/hwmon.h> |
20 | #include <linux/idr.h> | ||
21 | #include <linux/module.h> | ||
24 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/slab.h> | ||
25 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/thermal.h> | ||
26 | 26 | ||
27 | #define HWMON_ID_PREFIX "hwmon" | 27 | #define HWMON_ID_PREFIX "hwmon" |
28 | #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" | 28 | #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" |
@@ -30,9 +30,35 @@ | |||
30 | struct hwmon_device { | 30 | struct hwmon_device { |
31 | const char *name; | 31 | const char *name; |
32 | struct device dev; | 32 | struct device dev; |
33 | const struct hwmon_chip_info *chip; | ||
34 | |||
35 | struct attribute_group group; | ||
36 | const struct attribute_group **groups; | ||
33 | }; | 37 | }; |
38 | |||
34 | #define to_hwmon_device(d) container_of(d, struct hwmon_device, dev) | 39 | #define to_hwmon_device(d) container_of(d, struct hwmon_device, dev) |
35 | 40 | ||
41 | struct hwmon_device_attribute { | ||
42 | struct device_attribute dev_attr; | ||
43 | const struct hwmon_ops *ops; | ||
44 | enum hwmon_sensor_types type; | ||
45 | u32 attr; | ||
46 | int index; | ||
47 | }; | ||
48 | |||
49 | #define to_hwmon_attr(d) \ | ||
50 | container_of(d, struct hwmon_device_attribute, dev_attr) | ||
51 | |||
52 | /* | ||
53 | * Thermal zone information | ||
54 | * In addition to the reference to the hwmon device, | ||
55 | * also provides the sensor index. | ||
56 | */ | ||
57 | struct hwmon_thermal_data { | ||
58 | struct hwmon_device *hwdev; /* Reference to hwmon device */ | ||
59 | int index; /* sensor index */ | ||
60 | }; | ||
61 | |||
36 | static ssize_t | 62 | static ssize_t |
37 | show_name(struct device *dev, struct device_attribute *attr, char *buf) | 63 | show_name(struct device *dev, struct device_attribute *attr, char *buf) |
38 | { | 64 | { |
@@ -80,25 +106,409 @@ static struct class hwmon_class = { | |||
80 | 106 | ||
81 | static DEFINE_IDA(hwmon_ida); | 107 | static DEFINE_IDA(hwmon_ida); |
82 | 108 | ||
83 | /** | 109 | /* Thermal zone handling */ |
84 | * hwmon_device_register_with_groups - register w/ hwmon | 110 | |
85 | * @dev: the parent device | 111 | /* |
86 | * @name: hwmon name attribute | 112 | * The complex conditional is necessary to avoid a cyclic dependency |
87 | * @drvdata: driver data to attach to created device | 113 | * between hwmon and thermal_sys modules. |
88 | * @groups: List of attribute groups to create | ||
89 | * | ||
90 | * hwmon_device_unregister() must be called when the device is no | ||
91 | * longer needed. | ||
92 | * | ||
93 | * Returns the pointer to the new device. | ||
94 | */ | 114 | */ |
95 | struct device * | 115 | #if IS_REACHABLE(CONFIG_THERMAL) && defined(CONFIG_THERMAL_OF) && \ |
96 | hwmon_device_register_with_groups(struct device *dev, const char *name, | 116 | (!defined(CONFIG_THERMAL_HWMON) || \ |
97 | void *drvdata, | 117 | !(defined(MODULE) && IS_MODULE(CONFIG_THERMAL))) |
98 | const struct attribute_group **groups) | 118 | static int hwmon_thermal_get_temp(void *data, int *temp) |
119 | { | ||
120 | struct hwmon_thermal_data *tdata = data; | ||
121 | struct hwmon_device *hwdev = tdata->hwdev; | ||
122 | int ret; | ||
123 | long t; | ||
124 | |||
125 | ret = hwdev->chip->ops->read(&hwdev->dev, hwmon_temp, hwmon_temp_input, | ||
126 | tdata->index, &t); | ||
127 | if (ret < 0) | ||
128 | return ret; | ||
129 | |||
130 | *temp = t; | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static struct thermal_zone_of_device_ops hwmon_thermal_ops = { | ||
136 | .get_temp = hwmon_thermal_get_temp, | ||
137 | }; | ||
138 | |||
139 | static int hwmon_thermal_add_sensor(struct device *dev, | ||
140 | struct hwmon_device *hwdev, int index) | ||
141 | { | ||
142 | struct hwmon_thermal_data *tdata; | ||
143 | |||
144 | tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); | ||
145 | if (!tdata) | ||
146 | return -ENOMEM; | ||
147 | |||
148 | tdata->hwdev = hwdev; | ||
149 | tdata->index = index; | ||
150 | |||
151 | devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, | ||
152 | &hwmon_thermal_ops); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | #else | ||
157 | static int hwmon_thermal_add_sensor(struct device *dev, | ||
158 | struct hwmon_device *hwdev, int index) | ||
159 | { | ||
160 | return 0; | ||
161 | } | ||
162 | #endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */ | ||
163 | |||
164 | /* sysfs attribute management */ | ||
165 | |||
166 | static ssize_t hwmon_attr_show(struct device *dev, | ||
167 | struct device_attribute *devattr, char *buf) | ||
168 | { | ||
169 | struct hwmon_device_attribute *hattr = to_hwmon_attr(devattr); | ||
170 | long val; | ||
171 | int ret; | ||
172 | |||
173 | ret = hattr->ops->read(dev, hattr->type, hattr->attr, hattr->index, | ||
174 | &val); | ||
175 | if (ret < 0) | ||
176 | return ret; | ||
177 | |||
178 | return sprintf(buf, "%ld\n", val); | ||
179 | } | ||
180 | |||
181 | static ssize_t hwmon_attr_store(struct device *dev, | ||
182 | struct device_attribute *devattr, | ||
183 | const char *buf, size_t count) | ||
184 | { | ||
185 | struct hwmon_device_attribute *hattr = to_hwmon_attr(devattr); | ||
186 | long val; | ||
187 | int ret; | ||
188 | |||
189 | ret = kstrtol(buf, 10, &val); | ||
190 | if (ret < 0) | ||
191 | return ret; | ||
192 | |||
193 | ret = hattr->ops->write(dev, hattr->type, hattr->attr, hattr->index, | ||
194 | val); | ||
195 | if (ret < 0) | ||
196 | return ret; | ||
197 | |||
198 | return count; | ||
199 | } | ||
200 | |||
201 | static int hwmon_attr_base(enum hwmon_sensor_types type) | ||
202 | { | ||
203 | if (type == hwmon_in) | ||
204 | return 0; | ||
205 | return 1; | ||
206 | } | ||
207 | |||
208 | static struct attribute *hwmon_genattr(struct device *dev, | ||
209 | const void *drvdata, | ||
210 | enum hwmon_sensor_types type, | ||
211 | u32 attr, | ||
212 | int index, | ||
213 | const char *template, | ||
214 | const struct hwmon_ops *ops) | ||
215 | { | ||
216 | struct hwmon_device_attribute *hattr; | ||
217 | struct device_attribute *dattr; | ||
218 | struct attribute *a; | ||
219 | umode_t mode; | ||
220 | char *name; | ||
221 | |||
222 | /* The attribute is invisible if there is no template string */ | ||
223 | if (!template) | ||
224 | return ERR_PTR(-ENOENT); | ||
225 | |||
226 | mode = ops->is_visible(drvdata, type, attr, index); | ||
227 | if (!mode) | ||
228 | return ERR_PTR(-ENOENT); | ||
229 | |||
230 | if ((mode & S_IRUGO) && !ops->read) | ||
231 | return ERR_PTR(-EINVAL); | ||
232 | if ((mode & S_IWUGO) && !ops->write) | ||
233 | return ERR_PTR(-EINVAL); | ||
234 | |||
235 | if (type == hwmon_chip) { | ||
236 | name = (char *)template; | ||
237 | } else { | ||
238 | name = devm_kzalloc(dev, strlen(template) + 16, GFP_KERNEL); | ||
239 | if (!name) | ||
240 | return ERR_PTR(-ENOMEM); | ||
241 | scnprintf(name, strlen(template) + 16, template, | ||
242 | index + hwmon_attr_base(type)); | ||
243 | } | ||
244 | |||
245 | hattr = devm_kzalloc(dev, sizeof(*hattr), GFP_KERNEL); | ||
246 | if (!hattr) | ||
247 | return ERR_PTR(-ENOMEM); | ||
248 | |||
249 | hattr->type = type; | ||
250 | hattr->attr = attr; | ||
251 | hattr->index = index; | ||
252 | hattr->ops = ops; | ||
253 | |||
254 | dattr = &hattr->dev_attr; | ||
255 | dattr->show = hwmon_attr_show; | ||
256 | dattr->store = hwmon_attr_store; | ||
257 | |||
258 | a = &dattr->attr; | ||
259 | sysfs_attr_init(a); | ||
260 | a->name = name; | ||
261 | a->mode = mode; | ||
262 | |||
263 | return a; | ||
264 | } | ||
265 | |||
266 | static const char * const hwmon_chip_attr_templates[] = { | ||
267 | [hwmon_chip_temp_reset_history] = "temp_reset_history", | ||
268 | [hwmon_chip_in_reset_history] = "in_reset_history", | ||
269 | [hwmon_chip_curr_reset_history] = "curr_reset_history", | ||
270 | [hwmon_chip_power_reset_history] = "power_reset_history", | ||
271 | [hwmon_chip_update_interval] = "update_interval", | ||
272 | [hwmon_chip_alarms] = "alarms", | ||
273 | }; | ||
274 | |||
275 | static const char * const hwmon_temp_attr_templates[] = { | ||
276 | [hwmon_temp_input] = "temp%d_input", | ||
277 | [hwmon_temp_type] = "temp%d_type", | ||
278 | [hwmon_temp_lcrit] = "temp%d_lcrit", | ||
279 | [hwmon_temp_lcrit_hyst] = "temp%d_lcrit_hyst", | ||
280 | [hwmon_temp_min] = "temp%d_min", | ||
281 | [hwmon_temp_min_hyst] = "temp%d_min_hyst", | ||
282 | [hwmon_temp_max] = "temp%d_max", | ||
283 | [hwmon_temp_max_hyst] = "temp%d_max_hyst", | ||
284 | [hwmon_temp_crit] = "temp%d_crit", | ||
285 | [hwmon_temp_crit_hyst] = "temp%d_crit_hyst", | ||
286 | [hwmon_temp_emergency] = "temp%d_emergency", | ||
287 | [hwmon_temp_emergency_hyst] = "temp%d_emergency_hyst", | ||
288 | [hwmon_temp_alarm] = "temp%d_alarm", | ||
289 | [hwmon_temp_lcrit_alarm] = "temp%d_lcrit_alarm", | ||
290 | [hwmon_temp_min_alarm] = "temp%d_min_alarm", | ||
291 | [hwmon_temp_max_alarm] = "temp%d_max_alarm", | ||
292 | [hwmon_temp_crit_alarm] = "temp%d_crit_alarm", | ||
293 | [hwmon_temp_emergency_alarm] = "temp%d_emergency_alarm", | ||
294 | [hwmon_temp_fault] = "temp%d_fault", | ||
295 | [hwmon_temp_offset] = "temp%d_offset", | ||
296 | [hwmon_temp_label] = "temp%d_label", | ||
297 | [hwmon_temp_lowest] = "temp%d_lowest", | ||
298 | [hwmon_temp_highest] = "temp%d_highest", | ||
299 | [hwmon_temp_reset_history] = "temp%d_reset_history", | ||
300 | }; | ||
301 | |||
302 | static const char * const hwmon_in_attr_templates[] = { | ||
303 | [hwmon_in_input] = "in%d_input", | ||
304 | [hwmon_in_min] = "in%d_min", | ||
305 | [hwmon_in_max] = "in%d_max", | ||
306 | [hwmon_in_lcrit] = "in%d_lcrit", | ||
307 | [hwmon_in_crit] = "in%d_crit", | ||
308 | [hwmon_in_average] = "in%d_average", | ||
309 | [hwmon_in_lowest] = "in%d_lowest", | ||
310 | [hwmon_in_highest] = "in%d_highest", | ||
311 | [hwmon_in_reset_history] = "in%d_reset_history", | ||
312 | [hwmon_in_label] = "in%d_label", | ||
313 | [hwmon_in_alarm] = "in%d_alarm", | ||
314 | [hwmon_in_min_alarm] = "in%d_min_alarm", | ||
315 | [hwmon_in_max_alarm] = "in%d_max_alarm", | ||
316 | [hwmon_in_lcrit_alarm] = "in%d_lcrit_alarm", | ||
317 | [hwmon_in_crit_alarm] = "in%d_crit_alarm", | ||
318 | }; | ||
319 | |||
320 | static const char * const hwmon_curr_attr_templates[] = { | ||
321 | [hwmon_curr_input] = "curr%d_input", | ||
322 | [hwmon_curr_min] = "curr%d_min", | ||
323 | [hwmon_curr_max] = "curr%d_max", | ||
324 | [hwmon_curr_lcrit] = "curr%d_lcrit", | ||
325 | [hwmon_curr_crit] = "curr%d_crit", | ||
326 | [hwmon_curr_average] = "curr%d_average", | ||
327 | [hwmon_curr_lowest] = "curr%d_lowest", | ||
328 | [hwmon_curr_highest] = "curr%d_highest", | ||
329 | [hwmon_curr_reset_history] = "curr%d_reset_history", | ||
330 | [hwmon_curr_label] = "curr%d_label", | ||
331 | [hwmon_curr_alarm] = "curr%d_alarm", | ||
332 | [hwmon_curr_min_alarm] = "curr%d_min_alarm", | ||
333 | [hwmon_curr_max_alarm] = "curr%d_max_alarm", | ||
334 | [hwmon_curr_lcrit_alarm] = "curr%d_lcrit_alarm", | ||
335 | [hwmon_curr_crit_alarm] = "curr%d_crit_alarm", | ||
336 | }; | ||
337 | |||
338 | static const char * const hwmon_power_attr_templates[] = { | ||
339 | [hwmon_power_average] = "power%d_average", | ||
340 | [hwmon_power_average_interval] = "power%d_average_interval", | ||
341 | [hwmon_power_average_interval_max] = "power%d_interval_max", | ||
342 | [hwmon_power_average_interval_min] = "power%d_interval_min", | ||
343 | [hwmon_power_average_highest] = "power%d_average_highest", | ||
344 | [hwmon_power_average_lowest] = "power%d_average_lowest", | ||
345 | [hwmon_power_average_max] = "power%d_average_max", | ||
346 | [hwmon_power_average_min] = "power%d_average_min", | ||
347 | [hwmon_power_input] = "power%d_input", | ||
348 | [hwmon_power_input_highest] = "power%d_input_highest", | ||
349 | [hwmon_power_input_lowest] = "power%d_input_lowest", | ||
350 | [hwmon_power_reset_history] = "power%d_reset_history", | ||
351 | [hwmon_power_accuracy] = "power%d_accuracy", | ||
352 | [hwmon_power_cap] = "power%d_cap", | ||
353 | [hwmon_power_cap_hyst] = "power%d_cap_hyst", | ||
354 | [hwmon_power_cap_max] = "power%d_cap_max", | ||
355 | [hwmon_power_cap_min] = "power%d_cap_min", | ||
356 | [hwmon_power_max] = "power%d_max", | ||
357 | [hwmon_power_crit] = "power%d_crit", | ||
358 | [hwmon_power_label] = "power%d_label", | ||
359 | [hwmon_power_alarm] = "power%d_alarm", | ||
360 | [hwmon_power_cap_alarm] = "power%d_cap_alarm", | ||
361 | [hwmon_power_max_alarm] = "power%d_max_alarm", | ||
362 | [hwmon_power_crit_alarm] = "power%d_crit_alarm", | ||
363 | }; | ||
364 | |||
365 | static const char * const hwmon_energy_attr_templates[] = { | ||
366 | [hwmon_energy_input] = "energy%d_input", | ||
367 | [hwmon_energy_label] = "energy%d_label", | ||
368 | }; | ||
369 | |||
370 | static const char * const hwmon_humidity_attr_templates[] = { | ||
371 | [hwmon_humidity_input] = "humidity%d_input", | ||
372 | [hwmon_humidity_label] = "humidity%d_label", | ||
373 | [hwmon_humidity_min] = "humidity%d_min", | ||
374 | [hwmon_humidity_min_hyst] = "humidity%d_min_hyst", | ||
375 | [hwmon_humidity_max] = "humidity%d_max", | ||
376 | [hwmon_humidity_max_hyst] = "humidity%d_max_hyst", | ||
377 | [hwmon_humidity_alarm] = "humidity%d_alarm", | ||
378 | [hwmon_humidity_fault] = "humidity%d_fault", | ||
379 | }; | ||
380 | |||
381 | static const char * const hwmon_fan_attr_templates[] = { | ||
382 | [hwmon_fan_input] = "fan%d_input", | ||
383 | [hwmon_fan_label] = "fan%d_label", | ||
384 | [hwmon_fan_min] = "fan%d_min", | ||
385 | [hwmon_fan_max] = "fan%d_max", | ||
386 | [hwmon_fan_div] = "fan%d_div", | ||
387 | [hwmon_fan_pulses] = "fan%d_pulses", | ||
388 | [hwmon_fan_target] = "fan%d_target", | ||
389 | [hwmon_fan_alarm] = "fan%d_alarm", | ||
390 | [hwmon_fan_min_alarm] = "fan%d_min_alarm", | ||
391 | [hwmon_fan_max_alarm] = "fan%d_max_alarm", | ||
392 | [hwmon_fan_fault] = "fan%d_fault", | ||
393 | }; | ||
394 | |||
395 | static const char * const hwmon_pwm_attr_templates[] = { | ||
396 | [hwmon_pwm_input] = "pwm%d", | ||
397 | [hwmon_pwm_enable] = "pwm%d_enable", | ||
398 | [hwmon_pwm_mode] = "pwm%d_mode", | ||
399 | [hwmon_pwm_freq] = "pwm%d_freq", | ||
400 | }; | ||
401 | |||
402 | static const char * const *__templates[] = { | ||
403 | [hwmon_chip] = hwmon_chip_attr_templates, | ||
404 | [hwmon_temp] = hwmon_temp_attr_templates, | ||
405 | [hwmon_in] = hwmon_in_attr_templates, | ||
406 | [hwmon_curr] = hwmon_curr_attr_templates, | ||
407 | [hwmon_power] = hwmon_power_attr_templates, | ||
408 | [hwmon_energy] = hwmon_energy_attr_templates, | ||
409 | [hwmon_humidity] = hwmon_humidity_attr_templates, | ||
410 | [hwmon_fan] = hwmon_fan_attr_templates, | ||
411 | [hwmon_pwm] = hwmon_pwm_attr_templates, | ||
412 | }; | ||
413 | |||
414 | static const int __templates_size[] = { | ||
415 | [hwmon_chip] = ARRAY_SIZE(hwmon_chip_attr_templates), | ||
416 | [hwmon_temp] = ARRAY_SIZE(hwmon_temp_attr_templates), | ||
417 | [hwmon_in] = ARRAY_SIZE(hwmon_in_attr_templates), | ||
418 | [hwmon_curr] = ARRAY_SIZE(hwmon_curr_attr_templates), | ||
419 | [hwmon_power] = ARRAY_SIZE(hwmon_power_attr_templates), | ||
420 | [hwmon_energy] = ARRAY_SIZE(hwmon_energy_attr_templates), | ||
421 | [hwmon_humidity] = ARRAY_SIZE(hwmon_humidity_attr_templates), | ||
422 | [hwmon_fan] = ARRAY_SIZE(hwmon_fan_attr_templates), | ||
423 | [hwmon_pwm] = ARRAY_SIZE(hwmon_pwm_attr_templates), | ||
424 | }; | ||
425 | |||
426 | static int hwmon_num_channel_attrs(const struct hwmon_channel_info *info) | ||
427 | { | ||
428 | int i, n; | ||
429 | |||
430 | for (i = n = 0; info->config[i]; i++) | ||
431 | n += hweight32(info->config[i]); | ||
432 | |||
433 | return n; | ||
434 | } | ||
435 | |||
436 | static int hwmon_genattrs(struct device *dev, | ||
437 | const void *drvdata, | ||
438 | struct attribute **attrs, | ||
439 | const struct hwmon_ops *ops, | ||
440 | const struct hwmon_channel_info *info) | ||
441 | { | ||
442 | const char * const *templates; | ||
443 | int template_size; | ||
444 | int i, aindex = 0; | ||
445 | |||
446 | if (info->type >= ARRAY_SIZE(__templates)) | ||
447 | return -EINVAL; | ||
448 | |||
449 | templates = __templates[info->type]; | ||
450 | template_size = __templates_size[info->type]; | ||
451 | |||
452 | for (i = 0; info->config[i]; i++) { | ||
453 | u32 attr_mask = info->config[i]; | ||
454 | u32 attr; | ||
455 | |||
456 | while (attr_mask) { | ||
457 | struct attribute *a; | ||
458 | |||
459 | attr = __ffs(attr_mask); | ||
460 | attr_mask &= ~BIT(attr); | ||
461 | if (attr >= template_size) | ||
462 | return -EINVAL; | ||
463 | a = hwmon_genattr(dev, drvdata, info->type, attr, i, | ||
464 | templates[attr], ops); | ||
465 | if (IS_ERR(a)) { | ||
466 | if (PTR_ERR(a) != -ENOENT) | ||
467 | return PTR_ERR(a); | ||
468 | continue; | ||
469 | } | ||
470 | attrs[aindex++] = a; | ||
471 | } | ||
472 | } | ||
473 | return aindex; | ||
474 | } | ||
475 | |||
476 | static struct attribute ** | ||
477 | __hwmon_create_attrs(struct device *dev, const void *drvdata, | ||
478 | const struct hwmon_chip_info *chip) | ||
479 | { | ||
480 | int ret, i, aindex = 0, nattrs = 0; | ||
481 | struct attribute **attrs; | ||
482 | |||
483 | for (i = 0; chip->info[i]; i++) | ||
484 | nattrs += hwmon_num_channel_attrs(chip->info[i]); | ||
485 | |||
486 | if (nattrs == 0) | ||
487 | return ERR_PTR(-EINVAL); | ||
488 | |||
489 | attrs = devm_kcalloc(dev, nattrs + 1, sizeof(*attrs), GFP_KERNEL); | ||
490 | if (!attrs) | ||
491 | return ERR_PTR(-ENOMEM); | ||
492 | |||
493 | for (i = 0; chip->info[i]; i++) { | ||
494 | ret = hwmon_genattrs(dev, drvdata, &attrs[aindex], chip->ops, | ||
495 | chip->info[i]); | ||
496 | if (ret < 0) | ||
497 | return ERR_PTR(ret); | ||
498 | aindex += ret; | ||
499 | } | ||
500 | |||
501 | return attrs; | ||
502 | } | ||
503 | |||
504 | static struct device * | ||
505 | __hwmon_device_register(struct device *dev, const char *name, void *drvdata, | ||
506 | const struct hwmon_chip_info *chip, | ||
507 | const struct attribute_group **groups) | ||
99 | { | 508 | { |
100 | struct hwmon_device *hwdev; | 509 | struct hwmon_device *hwdev; |
101 | int err, id; | 510 | struct device *hdev; |
511 | int i, j, err, id; | ||
102 | 512 | ||
103 | /* Do not accept invalid characters in hwmon name attribute */ | 513 | /* Do not accept invalid characters in hwmon name attribute */ |
104 | if (name && (!strlen(name) || strpbrk(name, "-* \t\n"))) | 514 | if (name && (!strlen(name) || strpbrk(name, "-* \t\n"))) |
@@ -114,28 +524,128 @@ hwmon_device_register_with_groups(struct device *dev, const char *name, | |||
114 | goto ida_remove; | 524 | goto ida_remove; |
115 | } | 525 | } |
116 | 526 | ||
527 | hdev = &hwdev->dev; | ||
528 | |||
529 | if (chip && chip->ops->is_visible) { | ||
530 | struct attribute **attrs; | ||
531 | int ngroups = 2; | ||
532 | |||
533 | if (groups) | ||
534 | for (i = 0; groups[i]; i++) | ||
535 | ngroups++; | ||
536 | |||
537 | hwdev->groups = devm_kcalloc(dev, ngroups, sizeof(*groups), | ||
538 | GFP_KERNEL); | ||
539 | if (!hwdev->groups) | ||
540 | return ERR_PTR(-ENOMEM); | ||
541 | |||
542 | attrs = __hwmon_create_attrs(dev, drvdata, chip); | ||
543 | if (IS_ERR(attrs)) { | ||
544 | err = PTR_ERR(attrs); | ||
545 | goto free_hwmon; | ||
546 | } | ||
547 | |||
548 | hwdev->group.attrs = attrs; | ||
549 | ngroups = 0; | ||
550 | hwdev->groups[ngroups++] = &hwdev->group; | ||
551 | |||
552 | if (groups) { | ||
553 | for (i = 0; groups[i]; i++) | ||
554 | hwdev->groups[ngroups++] = groups[i]; | ||
555 | } | ||
556 | |||
557 | hdev->groups = hwdev->groups; | ||
558 | } else { | ||
559 | hdev->groups = groups; | ||
560 | } | ||
561 | |||
117 | hwdev->name = name; | 562 | hwdev->name = name; |
118 | hwdev->dev.class = &hwmon_class; | 563 | hdev->class = &hwmon_class; |
119 | hwdev->dev.parent = dev; | 564 | hdev->parent = dev; |
120 | hwdev->dev.groups = groups; | 565 | hdev->of_node = dev ? dev->of_node : NULL; |
121 | hwdev->dev.of_node = dev ? dev->of_node : NULL; | 566 | hwdev->chip = chip; |
122 | dev_set_drvdata(&hwdev->dev, drvdata); | 567 | dev_set_drvdata(hdev, drvdata); |
123 | dev_set_name(&hwdev->dev, HWMON_ID_FORMAT, id); | 568 | dev_set_name(hdev, HWMON_ID_FORMAT, id); |
124 | err = device_register(&hwdev->dev); | 569 | err = device_register(hdev); |
125 | if (err) | 570 | if (err) |
126 | goto free; | 571 | goto free_hwmon; |
572 | |||
573 | if (chip && chip->ops->is_visible && chip->ops->read && | ||
574 | chip->info[0]->type == hwmon_chip && | ||
575 | (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) { | ||
576 | const struct hwmon_channel_info **info = chip->info; | ||
577 | |||
578 | for (i = 1; info[i]; i++) { | ||
579 | if (info[i]->type != hwmon_temp) | ||
580 | continue; | ||
581 | |||
582 | for (j = 0; info[i]->config[j]; j++) { | ||
583 | if (!chip->ops->is_visible(drvdata, hwmon_temp, | ||
584 | hwmon_temp_input, j)) | ||
585 | continue; | ||
586 | if (info[i]->config[j] & HWMON_T_INPUT) | ||
587 | hwmon_thermal_add_sensor(dev, hwdev, j); | ||
588 | } | ||
589 | } | ||
590 | } | ||
127 | 591 | ||
128 | return &hwdev->dev; | 592 | return hdev; |
129 | 593 | ||
130 | free: | 594 | free_hwmon: |
131 | kfree(hwdev); | 595 | kfree(hwdev); |
132 | ida_remove: | 596 | ida_remove: |
133 | ida_simple_remove(&hwmon_ida, id); | 597 | ida_simple_remove(&hwmon_ida, id); |
134 | return ERR_PTR(err); | 598 | return ERR_PTR(err); |
135 | } | 599 | } |
600 | |||
601 | /** | ||
602 | * hwmon_device_register_with_groups - register w/ hwmon | ||
603 | * @dev: the parent device | ||
604 | * @name: hwmon name attribute | ||
605 | * @drvdata: driver data to attach to created device | ||
606 | * @groups: List of attribute groups to create | ||
607 | * | ||
608 | * hwmon_device_unregister() must be called when the device is no | ||
609 | * longer needed. | ||
610 | * | ||
611 | * Returns the pointer to the new device. | ||
612 | */ | ||
613 | struct device * | ||
614 | hwmon_device_register_with_groups(struct device *dev, const char *name, | ||
615 | void *drvdata, | ||
616 | const struct attribute_group **groups) | ||
617 | { | ||
618 | return __hwmon_device_register(dev, name, drvdata, NULL, groups); | ||
619 | } | ||
136 | EXPORT_SYMBOL_GPL(hwmon_device_register_with_groups); | 620 | EXPORT_SYMBOL_GPL(hwmon_device_register_with_groups); |
137 | 621 | ||
138 | /** | 622 | /** |
623 | * hwmon_device_register_with_info - register w/ hwmon | ||
624 | * @dev: the parent device | ||
625 | * @name: hwmon name attribute | ||
626 | * @drvdata: driver data to attach to created device | ||
627 | * @info: Pointer to hwmon chip information | ||
628 | * @groups - pointer to list of driver specific attribute groups | ||
629 | * | ||
630 | * hwmon_device_unregister() must be called when the device is no | ||
631 | * longer needed. | ||
632 | * | ||
633 | * Returns the pointer to the new device. | ||
634 | */ | ||
635 | struct device * | ||
636 | hwmon_device_register_with_info(struct device *dev, const char *name, | ||
637 | void *drvdata, | ||
638 | const struct hwmon_chip_info *chip, | ||
639 | const struct attribute_group **groups) | ||
640 | { | ||
641 | if (chip && (!chip->ops || !chip->info)) | ||
642 | return ERR_PTR(-EINVAL); | ||
643 | |||
644 | return __hwmon_device_register(dev, name, drvdata, chip, groups); | ||
645 | } | ||
646 | EXPORT_SYMBOL_GPL(hwmon_device_register_with_info); | ||
647 | |||
648 | /** | ||
139 | * hwmon_device_register - register w/ hwmon | 649 | * hwmon_device_register - register w/ hwmon |
140 | * @dev: the device to register | 650 | * @dev: the device to register |
141 | * | 651 | * |
@@ -213,6 +723,48 @@ error: | |||
213 | } | 723 | } |
214 | EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups); | 724 | EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups); |
215 | 725 | ||
726 | /** | ||
727 | * devm_hwmon_device_register_with_info - register w/ hwmon | ||
728 | * @dev: the parent device | ||
729 | * @name: hwmon name attribute | ||
730 | * @drvdata: driver data to attach to created device | ||
731 | * @info: Pointer to hwmon chip information | ||
732 | * @groups - pointer to list of driver specific attribute groups | ||
733 | * | ||
734 | * Returns the pointer to the new device. The new device is automatically | ||
735 | * unregistered with the parent device. | ||
736 | */ | ||
737 | struct device * | ||
738 | devm_hwmon_device_register_with_info(struct device *dev, const char *name, | ||
739 | void *drvdata, | ||
740 | const struct hwmon_chip_info *chip, | ||
741 | const struct attribute_group **groups) | ||
742 | { | ||
743 | struct device **ptr, *hwdev; | ||
744 | |||
745 | if (!dev) | ||
746 | return ERR_PTR(-EINVAL); | ||
747 | |||
748 | ptr = devres_alloc(devm_hwmon_release, sizeof(*ptr), GFP_KERNEL); | ||
749 | if (!ptr) | ||
750 | return ERR_PTR(-ENOMEM); | ||
751 | |||
752 | hwdev = hwmon_device_register_with_info(dev, name, drvdata, chip, | ||
753 | groups); | ||
754 | if (IS_ERR(hwdev)) | ||
755 | goto error; | ||
756 | |||
757 | *ptr = hwdev; | ||
758 | devres_add(dev, ptr); | ||
759 | |||
760 | return hwdev; | ||
761 | |||
762 | error: | ||
763 | devres_free(ptr); | ||
764 | return hwdev; | ||
765 | } | ||
766 | EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_info); | ||
767 | |||
216 | static int devm_hwmon_match(struct device *dev, void *res, void *data) | 768 | static int devm_hwmon_match(struct device *dev, void *res, void *data) |
217 | { | 769 | { |
218 | struct device **hwdev = res; | 770 | struct device **hwdev = res; |
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index 55b5a8ff1cfe..6d2e6605751c 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c | |||
@@ -143,13 +143,11 @@ static void __init make_sensor_label(struct device_node *np, | |||
143 | if (cpuid >= 0) | 143 | if (cpuid >= 0) |
144 | /* | 144 | /* |
145 | * The digital thermal sensors are associated | 145 | * The digital thermal sensors are associated |
146 | * with a core. Let's print out the range of | 146 | * with a core. |
147 | * cpu ids corresponding to the hardware | ||
148 | * threads of the core. | ||
149 | */ | 147 | */ |
150 | n += snprintf(sdata->label + n, | 148 | n += snprintf(sdata->label + n, |
151 | sizeof(sdata->label) - n, " %d-%d", | 149 | sizeof(sdata->label) - n, " %d", |
152 | cpuid, cpuid + threads_per_core - 1); | 150 | cpuid); |
153 | else | 151 | else |
154 | n += snprintf(sdata->label + n, | 152 | n += snprintf(sdata->label + n, |
155 | sizeof(sdata->label) - n, " phy%d", id); | 153 | sizeof(sdata->label) - n, " phy%d", id); |
diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index 89449871bca7..f6a76679c650 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c | |||
@@ -73,8 +73,11 @@ static int iio_hwmon_probe(struct platform_device *pdev) | |||
73 | name = dev->of_node->name; | 73 | name = dev->of_node->name; |
74 | 74 | ||
75 | channels = iio_channel_get_all(dev); | 75 | channels = iio_channel_get_all(dev); |
76 | if (IS_ERR(channels)) | 76 | if (IS_ERR(channels)) { |
77 | if (PTR_ERR(channels) == -ENODEV) | ||
78 | return -EPROBE_DEFER; | ||
77 | return PTR_ERR(channels); | 79 | return PTR_ERR(channels); |
80 | } | ||
78 | 81 | ||
79 | st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); | 82 | st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); |
80 | if (st == NULL) { | 83 | if (st == NULL) { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 4667012b46b7..ad82cb28d87a 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -2011,10 +2011,10 @@ static struct attribute *it87_attributes_in[] = { | |||
2011 | &sensor_dev_attr_in7_beep.dev_attr.attr, /* 39 */ | 2011 | &sensor_dev_attr_in7_beep.dev_attr.attr, /* 39 */ |
2012 | 2012 | ||
2013 | &sensor_dev_attr_in8_input.dev_attr.attr, /* 40 */ | 2013 | &sensor_dev_attr_in8_input.dev_attr.attr, /* 40 */ |
2014 | &sensor_dev_attr_in9_input.dev_attr.attr, /* 41 */ | 2014 | &sensor_dev_attr_in9_input.dev_attr.attr, |
2015 | &sensor_dev_attr_in10_input.dev_attr.attr, /* 41 */ | 2015 | &sensor_dev_attr_in10_input.dev_attr.attr, |
2016 | &sensor_dev_attr_in11_input.dev_attr.attr, /* 41 */ | 2016 | &sensor_dev_attr_in11_input.dev_attr.attr, |
2017 | &sensor_dev_attr_in12_input.dev_attr.attr, /* 41 */ | 2017 | &sensor_dev_attr_in12_input.dev_attr.attr, |
2018 | NULL | 2018 | NULL |
2019 | }; | 2019 | }; |
2020 | 2020 | ||
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 9d5f85f3384f..1bf22eff0b08 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/jiffies.h> | 28 | #include <linux/jiffies.h> |
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/hwmon.h> | 30 | #include <linux/hwmon.h> |
31 | #include <linux/hwmon-sysfs.h> | ||
32 | #include <linux/err.h> | 31 | #include <linux/err.h> |
33 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
34 | #include <linux/of.h> | 33 | #include <linux/of.h> |
@@ -254,170 +253,148 @@ abort: | |||
254 | return ret; | 253 | return ret; |
255 | } | 254 | } |
256 | 255 | ||
257 | /* sysfs functions */ | 256 | static int jc42_read(struct device *dev, enum hwmon_sensor_types type, |
258 | 257 | u32 attr, int channel, long *val) | |
259 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
260 | char *buf) | ||
261 | { | ||
262 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
263 | struct jc42_data *data = jc42_update_device(dev); | ||
264 | if (IS_ERR(data)) | ||
265 | return PTR_ERR(data); | ||
266 | return sprintf(buf, "%d\n", | ||
267 | jc42_temp_from_reg(data->temp[attr->index])); | ||
268 | } | ||
269 | |||
270 | static ssize_t show_temp_hyst(struct device *dev, | ||
271 | struct device_attribute *devattr, char *buf) | ||
272 | { | 258 | { |
273 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
274 | struct jc42_data *data = jc42_update_device(dev); | 259 | struct jc42_data *data = jc42_update_device(dev); |
275 | int temp, hyst; | 260 | int temp, hyst; |
276 | 261 | ||
277 | if (IS_ERR(data)) | 262 | if (IS_ERR(data)) |
278 | return PTR_ERR(data); | 263 | return PTR_ERR(data); |
279 | 264 | ||
280 | temp = jc42_temp_from_reg(data->temp[attr->index]); | 265 | switch (attr) { |
281 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) | 266 | case hwmon_temp_input: |
282 | >> JC42_CFG_HYST_SHIFT]; | 267 | *val = jc42_temp_from_reg(data->temp[t_input]); |
283 | return sprintf(buf, "%d\n", temp - hyst); | 268 | return 0; |
269 | case hwmon_temp_min: | ||
270 | *val = jc42_temp_from_reg(data->temp[t_min]); | ||
271 | return 0; | ||
272 | case hwmon_temp_max: | ||
273 | *val = jc42_temp_from_reg(data->temp[t_max]); | ||
274 | return 0; | ||
275 | case hwmon_temp_crit: | ||
276 | *val = jc42_temp_from_reg(data->temp[t_crit]); | ||
277 | return 0; | ||
278 | case hwmon_temp_max_hyst: | ||
279 | temp = jc42_temp_from_reg(data->temp[t_max]); | ||
280 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) | ||
281 | >> JC42_CFG_HYST_SHIFT]; | ||
282 | *val = temp - hyst; | ||
283 | return 0; | ||
284 | case hwmon_temp_crit_hyst: | ||
285 | temp = jc42_temp_from_reg(data->temp[t_crit]); | ||
286 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) | ||
287 | >> JC42_CFG_HYST_SHIFT]; | ||
288 | *val = temp - hyst; | ||
289 | return 0; | ||
290 | case hwmon_temp_min_alarm: | ||
291 | *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1; | ||
292 | return 0; | ||
293 | case hwmon_temp_max_alarm: | ||
294 | *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1; | ||
295 | return 0; | ||
296 | case hwmon_temp_crit_alarm: | ||
297 | *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1; | ||
298 | return 0; | ||
299 | default: | ||
300 | return -EOPNOTSUPP; | ||
301 | } | ||
284 | } | 302 | } |
285 | 303 | ||
286 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | 304 | static int jc42_write(struct device *dev, enum hwmon_sensor_types type, |
287 | const char *buf, size_t count) | 305 | u32 attr, int channel, long val) |
288 | { | 306 | { |
289 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
290 | struct jc42_data *data = dev_get_drvdata(dev); | 307 | struct jc42_data *data = dev_get_drvdata(dev); |
291 | int err, ret = count; | 308 | struct i2c_client *client = data->client; |
292 | int nr = attr->index; | 309 | int diff, hyst; |
293 | long val; | 310 | int ret; |
294 | 311 | ||
295 | if (kstrtol(buf, 10, &val) < 0) | ||
296 | return -EINVAL; | ||
297 | mutex_lock(&data->update_lock); | 312 | mutex_lock(&data->update_lock); |
298 | data->temp[nr] = jc42_temp_to_reg(val, data->extended); | ||
299 | err = i2c_smbus_write_word_swapped(data->client, temp_regs[nr], | ||
300 | data->temp[nr]); | ||
301 | if (err < 0) | ||
302 | ret = err; | ||
303 | mutex_unlock(&data->update_lock); | ||
304 | return ret; | ||
305 | } | ||
306 | 313 | ||
307 | /* | 314 | switch (attr) { |
308 | * JC42.4 compliant chips only support four hysteresis values. | 315 | case hwmon_temp_min: |
309 | * Pick best choice and go from there. | 316 | data->temp[t_min] = jc42_temp_to_reg(val, data->extended); |
310 | */ | 317 | ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min], |
311 | static ssize_t set_temp_crit_hyst(struct device *dev, | 318 | data->temp[t_min]); |
312 | struct device_attribute *attr, | 319 | break; |
313 | const char *buf, size_t count) | 320 | case hwmon_temp_max: |
314 | { | 321 | data->temp[t_max] = jc42_temp_to_reg(val, data->extended); |
315 | struct jc42_data *data = dev_get_drvdata(dev); | 322 | ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max], |
316 | long val; | 323 | data->temp[t_max]); |
317 | int diff, hyst; | 324 | break; |
318 | int err; | 325 | case hwmon_temp_crit: |
319 | int ret = count; | 326 | data->temp[t_crit] = jc42_temp_to_reg(val, data->extended); |
320 | 327 | ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit], | |
321 | if (kstrtol(buf, 10, &val) < 0) | 328 | data->temp[t_crit]); |
322 | return -EINVAL; | 329 | break; |
323 | 330 | case hwmon_temp_crit_hyst: | |
324 | val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED : | 331 | /* |
325 | JC42_TEMP_MIN) - 6000, JC42_TEMP_MAX); | 332 | * JC42.4 compliant chips only support four hysteresis values. |
326 | diff = jc42_temp_from_reg(data->temp[t_crit]) - val; | 333 | * Pick best choice and go from there. |
327 | 334 | */ | |
328 | hyst = 0; | 335 | val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED |
329 | if (diff > 0) { | 336 | : JC42_TEMP_MIN) - 6000, |
330 | if (diff < 2250) | 337 | JC42_TEMP_MAX); |
331 | hyst = 1; /* 1.5 degrees C */ | 338 | diff = jc42_temp_from_reg(data->temp[t_crit]) - val; |
332 | else if (diff < 4500) | 339 | hyst = 0; |
333 | hyst = 2; /* 3.0 degrees C */ | 340 | if (diff > 0) { |
334 | else | 341 | if (diff < 2250) |
335 | hyst = 3; /* 6.0 degrees C */ | 342 | hyst = 1; /* 1.5 degrees C */ |
343 | else if (diff < 4500) | ||
344 | hyst = 2; /* 3.0 degrees C */ | ||
345 | else | ||
346 | hyst = 3; /* 6.0 degrees C */ | ||
347 | } | ||
348 | data->config = (data->config & ~JC42_CFG_HYST_MASK) | | ||
349 | (hyst << JC42_CFG_HYST_SHIFT); | ||
350 | ret = i2c_smbus_write_word_swapped(data->client, | ||
351 | JC42_REG_CONFIG, | ||
352 | data->config); | ||
353 | break; | ||
354 | default: | ||
355 | ret = -EOPNOTSUPP; | ||
356 | break; | ||
336 | } | 357 | } |
337 | 358 | ||
338 | mutex_lock(&data->update_lock); | ||
339 | data->config = (data->config & ~JC42_CFG_HYST_MASK) | ||
340 | | (hyst << JC42_CFG_HYST_SHIFT); | ||
341 | err = i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, | ||
342 | data->config); | ||
343 | if (err < 0) | ||
344 | ret = err; | ||
345 | mutex_unlock(&data->update_lock); | 359 | mutex_unlock(&data->update_lock); |
346 | return ret; | ||
347 | } | ||
348 | 360 | ||
349 | static ssize_t show_alarm(struct device *dev, | 361 | return ret; |
350 | struct device_attribute *attr, char *buf) | ||
351 | { | ||
352 | u16 bit = to_sensor_dev_attr(attr)->index; | ||
353 | struct jc42_data *data = jc42_update_device(dev); | ||
354 | u16 val; | ||
355 | |||
356 | if (IS_ERR(data)) | ||
357 | return PTR_ERR(data); | ||
358 | |||
359 | val = data->temp[t_input]; | ||
360 | if (bit != JC42_ALARM_CRIT_BIT && (data->config & JC42_CFG_CRIT_ONLY)) | ||
361 | val = 0; | ||
362 | return sprintf(buf, "%u\n", (val >> bit) & 1); | ||
363 | } | 362 | } |
364 | 363 | ||
365 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); | 364 | static umode_t jc42_is_visible(const void *_data, enum hwmon_sensor_types type, |
366 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, set_temp, t_crit); | 365 | u32 attr, int channel) |
367 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp, set_temp, t_min); | ||
368 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, set_temp, t_max); | ||
369 | |||
370 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_hyst, | ||
371 | set_temp_crit_hyst, t_crit); | ||
372 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max); | ||
373 | |||
374 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
375 | JC42_ALARM_CRIT_BIT); | ||
376 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, | ||
377 | JC42_ALARM_MIN_BIT); | ||
378 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | ||
379 | JC42_ALARM_MAX_BIT); | ||
380 | |||
381 | static struct attribute *jc42_attributes[] = { | ||
382 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
383 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
384 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
385 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
386 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
387 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
388 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
389 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
390 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
391 | NULL | ||
392 | }; | ||
393 | |||
394 | static umode_t jc42_attribute_mode(struct kobject *kobj, | ||
395 | struct attribute *attr, int index) | ||
396 | { | 366 | { |
397 | struct device *dev = container_of(kobj, struct device, kobj); | 367 | const struct jc42_data *data = _data; |
398 | struct jc42_data *data = dev_get_drvdata(dev); | ||
399 | unsigned int config = data->config; | 368 | unsigned int config = data->config; |
400 | bool readonly; | 369 | umode_t mode = S_IRUGO; |
401 | 370 | ||
402 | if (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr) | 371 | switch (attr) { |
403 | readonly = config & JC42_CFG_TCRIT_LOCK; | 372 | case hwmon_temp_min: |
404 | else if (attr == &sensor_dev_attr_temp1_min.dev_attr.attr || | 373 | case hwmon_temp_max: |
405 | attr == &sensor_dev_attr_temp1_max.dev_attr.attr) | 374 | if (!(config & JC42_CFG_EVENT_LOCK)) |
406 | readonly = config & JC42_CFG_EVENT_LOCK; | 375 | mode |= S_IWUSR; |
407 | else if (attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr) | 376 | break; |
408 | readonly = config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK); | 377 | case hwmon_temp_crit: |
409 | else | 378 | if (!(config & JC42_CFG_TCRIT_LOCK)) |
410 | readonly = true; | 379 | mode |= S_IWUSR; |
411 | 380 | break; | |
412 | return S_IRUGO | (readonly ? 0 : S_IWUSR); | 381 | case hwmon_temp_crit_hyst: |
382 | if (!(config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK))) | ||
383 | mode |= S_IWUSR; | ||
384 | break; | ||
385 | case hwmon_temp_input: | ||
386 | case hwmon_temp_max_hyst: | ||
387 | case hwmon_temp_min_alarm: | ||
388 | case hwmon_temp_max_alarm: | ||
389 | case hwmon_temp_crit_alarm: | ||
390 | break; | ||
391 | default: | ||
392 | mode = 0; | ||
393 | break; | ||
394 | } | ||
395 | return mode; | ||
413 | } | 396 | } |
414 | 397 | ||
415 | static const struct attribute_group jc42_group = { | ||
416 | .attrs = jc42_attributes, | ||
417 | .is_visible = jc42_attribute_mode, | ||
418 | }; | ||
419 | __ATTRIBUTE_GROUPS(jc42); | ||
420 | |||
421 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 398 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
422 | static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) | 399 | static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) |
423 | { | 400 | { |
@@ -450,6 +427,34 @@ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
450 | return -ENODEV; | 427 | return -ENODEV; |
451 | } | 428 | } |
452 | 429 | ||
430 | static const u32 jc42_temp_config[] = { | ||
431 | HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_CRIT | | ||
432 | HWMON_T_MAX_HYST | HWMON_T_CRIT_HYST | | ||
433 | HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM, | ||
434 | 0 | ||
435 | }; | ||
436 | |||
437 | static const struct hwmon_channel_info jc42_temp = { | ||
438 | .type = hwmon_temp, | ||
439 | .config = jc42_temp_config, | ||
440 | }; | ||
441 | |||
442 | static const struct hwmon_channel_info *jc42_info[] = { | ||
443 | &jc42_temp, | ||
444 | NULL | ||
445 | }; | ||
446 | |||
447 | static const struct hwmon_ops jc42_hwmon_ops = { | ||
448 | .is_visible = jc42_is_visible, | ||
449 | .read = jc42_read, | ||
450 | .write = jc42_write, | ||
451 | }; | ||
452 | |||
453 | static const struct hwmon_chip_info jc42_chip_info = { | ||
454 | .ops = &jc42_hwmon_ops, | ||
455 | .info = jc42_info, | ||
456 | }; | ||
457 | |||
453 | static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) | 458 | static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) |
454 | { | 459 | { |
455 | struct device *dev = &client->dev; | 460 | struct device *dev = &client->dev; |
@@ -482,9 +487,9 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
482 | } | 487 | } |
483 | data->config = config; | 488 | data->config = config; |
484 | 489 | ||
485 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 490 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
486 | data, | 491 | data, &jc42_chip_info, |
487 | jc42_groups); | 492 | NULL); |
488 | return PTR_ERR_OR_ZERO(hwmon_dev); | 493 | return PTR_ERR_OR_ZERO(hwmon_dev); |
489 | } | 494 | } |
490 | 495 | ||
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 92f9d4bbf597..eff3b24d8473 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/of.h> | 29 | #include <linux/of.h> |
30 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
31 | #include <linux/thermal.h> | ||
32 | #include "lm75.h" | 31 | #include "lm75.h" |
33 | 32 | ||
34 | 33 | ||
@@ -88,56 +87,75 @@ static inline long lm75_reg_to_mc(s16 temp, u8 resolution) | |||
88 | return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); | 87 | return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); |
89 | } | 88 | } |
90 | 89 | ||
91 | /* sysfs attributes for hwmon */ | 90 | static int lm75_read(struct device *dev, enum hwmon_sensor_types type, |
92 | 91 | u32 attr, int channel, long *val) | |
93 | static int lm75_read_temp(void *dev, int *temp) | ||
94 | { | 92 | { |
95 | struct lm75_data *data = dev_get_drvdata(dev); | 93 | struct lm75_data *data = dev_get_drvdata(dev); |
96 | unsigned int _temp; | 94 | unsigned int regval; |
97 | int err; | 95 | int err, reg; |
98 | 96 | ||
99 | err = regmap_read(data->regmap, LM75_REG_TEMP, &_temp); | 97 | switch (type) { |
100 | if (err < 0) | 98 | case hwmon_chip: |
101 | return err; | 99 | switch (attr) { |
102 | 100 | case hwmon_chip_update_interval: | |
103 | *temp = lm75_reg_to_mc(_temp, data->resolution); | 101 | *val = data->sample_time; |
104 | 102 | break;; | |
103 | default: | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | break; | ||
107 | case hwmon_temp: | ||
108 | switch (attr) { | ||
109 | case hwmon_temp_input: | ||
110 | reg = LM75_REG_TEMP; | ||
111 | break; | ||
112 | case hwmon_temp_max: | ||
113 | reg = LM75_REG_MAX; | ||
114 | break; | ||
115 | case hwmon_temp_max_hyst: | ||
116 | reg = LM75_REG_HYST; | ||
117 | break; | ||
118 | default: | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | err = regmap_read(data->regmap, reg, ®val); | ||
122 | if (err < 0) | ||
123 | return err; | ||
124 | |||
125 | *val = lm75_reg_to_mc(regval, data->resolution); | ||
126 | break; | ||
127 | default: | ||
128 | return -EINVAL; | ||
129 | } | ||
105 | return 0; | 130 | return 0; |
106 | } | 131 | } |
107 | 132 | ||
108 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, | 133 | static int lm75_write(struct device *dev, enum hwmon_sensor_types type, |
109 | char *buf) | 134 | u32 attr, int channel, long temp) |
110 | { | 135 | { |
111 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
112 | struct lm75_data *data = dev_get_drvdata(dev); | 136 | struct lm75_data *data = dev_get_drvdata(dev); |
113 | unsigned int temp = 0; | ||
114 | int err; | ||
115 | |||
116 | err = regmap_read(data->regmap, attr->index, &temp); | ||
117 | if (err < 0) | ||
118 | return err; | ||
119 | |||
120 | return sprintf(buf, "%ld\n", lm75_reg_to_mc(temp, data->resolution)); | ||
121 | } | ||
122 | |||
123 | static ssize_t set_temp(struct device *dev, struct device_attribute *da, | ||
124 | const char *buf, size_t count) | ||
125 | { | ||
126 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
127 | struct lm75_data *data = dev_get_drvdata(dev); | ||
128 | long temp; | ||
129 | int error; | ||
130 | u8 resolution; | 137 | u8 resolution; |
138 | int reg; | ||
139 | |||
140 | if (type != hwmon_temp) | ||
141 | return -EINVAL; | ||
131 | 142 | ||
132 | error = kstrtol(buf, 10, &temp); | 143 | switch (attr) { |
133 | if (error) | 144 | case hwmon_temp_max: |
134 | return error; | 145 | reg = LM75_REG_MAX; |
146 | break; | ||
147 | case hwmon_temp_max_hyst: | ||
148 | reg = LM75_REG_HYST; | ||
149 | break; | ||
150 | default: | ||
151 | return -EINVAL; | ||
152 | } | ||
135 | 153 | ||
136 | /* | 154 | /* |
137 | * Resolution of limit registers is assumed to be the same as the | 155 | * Resolution of limit registers is assumed to be the same as the |
138 | * temperature input register resolution unless given explicitly. | 156 | * temperature input register resolution unless given explicitly. |
139 | */ | 157 | */ |
140 | if (attr->index && data->resolution_limits) | 158 | if (data->resolution_limits) |
141 | resolution = data->resolution_limits; | 159 | resolution = data->resolution_limits; |
142 | else | 160 | else |
143 | resolution = data->resolution; | 161 | resolution = data->resolution; |
@@ -145,45 +163,77 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
145 | temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); | 163 | temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); |
146 | temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), | 164 | temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), |
147 | 1000) << (16 - resolution); | 165 | 1000) << (16 - resolution); |
148 | error = regmap_write(data->regmap, attr->index, temp); | ||
149 | if (error < 0) | ||
150 | return error; | ||
151 | 166 | ||
152 | return count; | 167 | return regmap_write(data->regmap, reg, temp); |
153 | } | 168 | } |
154 | 169 | ||
155 | static ssize_t show_update_interval(struct device *dev, | 170 | static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type, |
156 | struct device_attribute *da, char *buf) | 171 | u32 attr, int channel) |
157 | { | 172 | { |
158 | struct lm75_data *data = dev_get_drvdata(dev); | 173 | switch (type) { |
159 | 174 | case hwmon_chip: | |
160 | return sprintf(buf, "%u\n", data->sample_time); | 175 | switch (attr) { |
176 | case hwmon_chip_update_interval: | ||
177 | return S_IRUGO; | ||
178 | } | ||
179 | break; | ||
180 | case hwmon_temp: | ||
181 | switch (attr) { | ||
182 | case hwmon_temp_input: | ||
183 | return S_IRUGO; | ||
184 | case hwmon_temp_max: | ||
185 | case hwmon_temp_max_hyst: | ||
186 | return S_IRUGO | S_IWUSR; | ||
187 | } | ||
188 | break; | ||
189 | default: | ||
190 | break; | ||
191 | } | ||
192 | return 0; | ||
161 | } | 193 | } |
162 | 194 | ||
163 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | 195 | /*-----------------------------------------------------------------------*/ |
164 | show_temp, set_temp, LM75_REG_MAX); | ||
165 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | ||
166 | show_temp, set_temp, LM75_REG_HYST); | ||
167 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, LM75_REG_TEMP); | ||
168 | static DEVICE_ATTR(update_interval, S_IRUGO, show_update_interval, NULL); | ||
169 | 196 | ||
170 | static struct attribute *lm75_attrs[] = { | 197 | /* device probe and removal */ |
171 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
172 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
173 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
174 | &dev_attr_update_interval.attr, | ||
175 | 198 | ||
176 | NULL | 199 | /* chip configuration */ |
200 | |||
201 | static const u32 lm75_chip_config[] = { | ||
202 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL, | ||
203 | 0 | ||
177 | }; | 204 | }; |
178 | ATTRIBUTE_GROUPS(lm75); | ||
179 | 205 | ||
180 | static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = { | 206 | static const struct hwmon_channel_info lm75_chip = { |
181 | .get_temp = lm75_read_temp, | 207 | .type = hwmon_chip, |
208 | .config = lm75_chip_config, | ||
182 | }; | 209 | }; |
183 | 210 | ||
184 | /*-----------------------------------------------------------------------*/ | 211 | static const u32 lm75_temp_config[] = { |
212 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST, | ||
213 | 0 | ||
214 | }; | ||
185 | 215 | ||
186 | /* device probe and removal */ | 216 | static const struct hwmon_channel_info lm75_temp = { |
217 | .type = hwmon_temp, | ||
218 | .config = lm75_temp_config, | ||
219 | }; | ||
220 | |||
221 | static const struct hwmon_channel_info *lm75_info[] = { | ||
222 | &lm75_chip, | ||
223 | &lm75_temp, | ||
224 | NULL | ||
225 | }; | ||
226 | |||
227 | static const struct hwmon_ops lm75_hwmon_ops = { | ||
228 | .is_visible = lm75_is_visible, | ||
229 | .read = lm75_read, | ||
230 | .write = lm75_write, | ||
231 | }; | ||
232 | |||
233 | static const struct hwmon_chip_info lm75_chip_info = { | ||
234 | .ops = &lm75_hwmon_ops, | ||
235 | .info = lm75_info, | ||
236 | }; | ||
187 | 237 | ||
188 | static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) | 238 | static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) |
189 | { | 239 | { |
@@ -337,15 +387,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
337 | 387 | ||
338 | dev_dbg(dev, "Config %02x\n", new); | 388 | dev_dbg(dev, "Config %02x\n", new); |
339 | 389 | ||
340 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 390 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
341 | data, lm75_groups); | 391 | data, &lm75_chip_info, |
392 | NULL); | ||
342 | if (IS_ERR(hwmon_dev)) | 393 | if (IS_ERR(hwmon_dev)) |
343 | return PTR_ERR(hwmon_dev); | 394 | return PTR_ERR(hwmon_dev); |
344 | 395 | ||
345 | devm_thermal_zone_of_sensor_register(hwmon_dev, 0, | ||
346 | hwmon_dev, | ||
347 | &lm75_of_thermal_ops); | ||
348 | |||
349 | dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); | 396 | dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); |
350 | 397 | ||
351 | return 0; | 398 | return 0; |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 496e771b363f..322ed9272811 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -89,7 +89,6 @@ | |||
89 | #include <linux/slab.h> | 89 | #include <linux/slab.h> |
90 | #include <linux/jiffies.h> | 90 | #include <linux/jiffies.h> |
91 | #include <linux/i2c.h> | 91 | #include <linux/i2c.h> |
92 | #include <linux/hwmon-sysfs.h> | ||
93 | #include <linux/hwmon.h> | 92 | #include <linux/hwmon.h> |
94 | #include <linux/err.h> | 93 | #include <linux/err.h> |
95 | #include <linux/mutex.h> | 94 | #include <linux/mutex.h> |
@@ -326,7 +325,7 @@ static const struct lm90_params lm90_params[] = { | |||
326 | .alert_alarms = 0x7c, | 325 | .alert_alarms = 0x7c, |
327 | .max_convrate = 9, | 326 | .max_convrate = 9, |
328 | .reg_local_ext = TMP451_REG_R_LOCAL_TEMPL, | 327 | .reg_local_ext = TMP451_REG_R_LOCAL_TEMPL, |
329 | } | 328 | }, |
330 | }; | 329 | }; |
331 | 330 | ||
332 | /* | 331 | /* |
@@ -365,7 +364,10 @@ enum lm90_temp11_reg_index { | |||
365 | 364 | ||
366 | struct lm90_data { | 365 | struct lm90_data { |
367 | struct i2c_client *client; | 366 | struct i2c_client *client; |
368 | const struct attribute_group *groups[6]; | 367 | u32 channel_config[4]; |
368 | struct hwmon_channel_info temp_info; | ||
369 | const struct hwmon_channel_info *info[3]; | ||
370 | struct hwmon_chip_info chip; | ||
369 | struct mutex update_lock; | 371 | struct mutex update_lock; |
370 | bool valid; /* true if register values are valid */ | 372 | bool valid; /* true if register values are valid */ |
371 | unsigned long last_updated; /* in jiffies */ | 373 | unsigned long last_updated; /* in jiffies */ |
@@ -489,11 +491,11 @@ static inline int lm90_select_remote_channel(struct i2c_client *client, | |||
489 | * client->update_lock must be held when calling this function (unless we are | 491 | * client->update_lock must be held when calling this function (unless we are |
490 | * in detection or initialization steps). | 492 | * in detection or initialization steps). |
491 | */ | 493 | */ |
492 | static void lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, | 494 | static int lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, |
493 | unsigned int interval) | 495 | unsigned int interval) |
494 | { | 496 | { |
495 | int i; | ||
496 | unsigned int update_interval; | 497 | unsigned int update_interval; |
498 | int i, err; | ||
497 | 499 | ||
498 | /* Shift calculations to avoid rounding errors */ | 500 | /* Shift calculations to avoid rounding errors */ |
499 | interval <<= 6; | 501 | interval <<= 6; |
@@ -504,8 +506,9 @@ static void lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, | |||
504 | if (interval >= update_interval * 3 / 4) | 506 | if (interval >= update_interval * 3 / 4) |
505 | break; | 507 | break; |
506 | 508 | ||
507 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, i); | 509 | err = i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, i); |
508 | data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64); | 510 | data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64); |
511 | return err; | ||
509 | } | 512 | } |
510 | 513 | ||
511 | static int lm90_update_limits(struct device *dev) | 514 | static int lm90_update_limits(struct device *dev) |
@@ -604,19 +607,17 @@ static int lm90_update_limits(struct device *dev) | |||
604 | return 0; | 607 | return 0; |
605 | } | 608 | } |
606 | 609 | ||
607 | static struct lm90_data *lm90_update_device(struct device *dev) | 610 | static int lm90_update_device(struct device *dev) |
608 | { | 611 | { |
609 | struct lm90_data *data = dev_get_drvdata(dev); | 612 | struct lm90_data *data = dev_get_drvdata(dev); |
610 | struct i2c_client *client = data->client; | 613 | struct i2c_client *client = data->client; |
611 | unsigned long next_update; | 614 | unsigned long next_update; |
612 | int val = 0; | 615 | int val; |
613 | |||
614 | mutex_lock(&data->update_lock); | ||
615 | 616 | ||
616 | if (!data->valid) { | 617 | if (!data->valid) { |
617 | val = lm90_update_limits(dev); | 618 | val = lm90_update_limits(dev); |
618 | if (val < 0) | 619 | if (val < 0) |
619 | goto error; | 620 | return val; |
620 | } | 621 | } |
621 | 622 | ||
622 | next_update = data->last_updated + | 623 | next_update = data->last_updated + |
@@ -628,53 +629,55 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
628 | 629 | ||
629 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_LOW); | 630 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_LOW); |
630 | if (val < 0) | 631 | if (val < 0) |
631 | goto error; | 632 | return val; |
632 | data->temp8[LOCAL_LOW] = val; | 633 | data->temp8[LOCAL_LOW] = val; |
633 | 634 | ||
634 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH); | 635 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH); |
635 | if (val < 0) | 636 | if (val < 0) |
636 | goto error; | 637 | return val; |
637 | data->temp8[LOCAL_HIGH] = val; | 638 | data->temp8[LOCAL_HIGH] = val; |
638 | 639 | ||
639 | if (data->reg_local_ext) { | 640 | if (data->reg_local_ext) { |
640 | val = lm90_read16(client, LM90_REG_R_LOCAL_TEMP, | 641 | val = lm90_read16(client, LM90_REG_R_LOCAL_TEMP, |
641 | data->reg_local_ext); | 642 | data->reg_local_ext); |
642 | if (val < 0) | 643 | if (val < 0) |
643 | goto error; | 644 | return val; |
644 | data->temp11[LOCAL_TEMP] = val; | 645 | data->temp11[LOCAL_TEMP] = val; |
645 | } else { | 646 | } else { |
646 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP); | 647 | val = lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP); |
647 | if (val < 0) | 648 | if (val < 0) |
648 | goto error; | 649 | return val; |
649 | data->temp11[LOCAL_TEMP] = val << 8; | 650 | data->temp11[LOCAL_TEMP] = val << 8; |
650 | } | 651 | } |
651 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, | 652 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, |
652 | LM90_REG_R_REMOTE_TEMPL); | 653 | LM90_REG_R_REMOTE_TEMPL); |
653 | if (val < 0) | 654 | if (val < 0) |
654 | goto error; | 655 | return val; |
655 | data->temp11[REMOTE_TEMP] = val; | 656 | data->temp11[REMOTE_TEMP] = val; |
656 | 657 | ||
657 | val = lm90_read_reg(client, LM90_REG_R_STATUS); | 658 | val = lm90_read_reg(client, LM90_REG_R_STATUS); |
658 | if (val < 0) | 659 | if (val < 0) |
659 | goto error; | 660 | return val; |
660 | data->alarms = val; /* lower 8 bit of alarms */ | 661 | data->alarms = val; /* lower 8 bit of alarms */ |
661 | 662 | ||
662 | if (data->kind == max6696) { | 663 | if (data->kind == max6696) { |
663 | val = lm90_select_remote_channel(client, data, 1); | 664 | val = lm90_select_remote_channel(client, data, 1); |
664 | if (val < 0) | 665 | if (val < 0) |
665 | goto error; | 666 | return val; |
666 | 667 | ||
667 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, | 668 | val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, |
668 | LM90_REG_R_REMOTE_TEMPL); | 669 | LM90_REG_R_REMOTE_TEMPL); |
669 | if (val < 0) | 670 | if (val < 0) { |
670 | goto error; | 671 | lm90_select_remote_channel(client, data, 0); |
672 | return val; | ||
673 | } | ||
671 | data->temp11[REMOTE2_TEMP] = val; | 674 | data->temp11[REMOTE2_TEMP] = val; |
672 | 675 | ||
673 | lm90_select_remote_channel(client, data, 0); | 676 | lm90_select_remote_channel(client, data, 0); |
674 | 677 | ||
675 | val = lm90_read_reg(client, MAX6696_REG_R_STATUS2); | 678 | val = lm90_read_reg(client, MAX6696_REG_R_STATUS2); |
676 | if (val < 0) | 679 | if (val < 0) |
677 | goto error; | 680 | return val; |
678 | data->alarms |= val << 8; | 681 | data->alarms |= val << 8; |
679 | } | 682 | } |
680 | 683 | ||
@@ -686,7 +689,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
686 | !(data->alarms & data->alert_alarms)) { | 689 | !(data->alarms & data->alert_alarms)) { |
687 | val = lm90_read_reg(client, LM90_REG_R_CONFIG1); | 690 | val = lm90_read_reg(client, LM90_REG_R_CONFIG1); |
688 | if (val < 0) | 691 | if (val < 0) |
689 | goto error; | 692 | return val; |
690 | 693 | ||
691 | if (val & 0x80) { | 694 | if (val & 0x80) { |
692 | dev_dbg(&client->dev, "Re-enabling ALERT#\n"); | 695 | dev_dbg(&client->dev, "Re-enabling ALERT#\n"); |
@@ -700,13 +703,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
700 | data->valid = true; | 703 | data->valid = true; |
701 | } | 704 | } |
702 | 705 | ||
703 | error: | 706 | return 0; |
704 | mutex_unlock(&data->update_lock); | ||
705 | |||
706 | if (val < 0) | ||
707 | return ERR_PTR(val); | ||
708 | |||
709 | return data; | ||
710 | } | 707 | } |
711 | 708 | ||
712 | /* | 709 | /* |
@@ -832,52 +829,19 @@ static u16 temp_to_u16_adt7461(struct lm90_data *data, long val) | |||
832 | return (val + 125) / 250 * 64; | 829 | return (val + 125) / 250 * 64; |
833 | } | 830 | } |
834 | 831 | ||
835 | /* | 832 | /* pec used for ADM1032 only */ |
836 | * Sysfs stuff | 833 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, |
837 | */ | 834 | char *buf) |
838 | |||
839 | static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | ||
840 | char *buf) | ||
841 | { | 835 | { |
842 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 836 | struct i2c_client *client = to_i2c_client(dev); |
843 | struct lm90_data *data = lm90_update_device(dev); | ||
844 | int temp; | ||
845 | |||
846 | if (IS_ERR(data)) | ||
847 | return PTR_ERR(data); | ||
848 | |||
849 | if (data->kind == adt7461 || data->kind == tmp451) | ||
850 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | ||
851 | else if (data->kind == max6646) | ||
852 | temp = temp_from_u8(data->temp8[attr->index]); | ||
853 | else | ||
854 | temp = temp_from_s8(data->temp8[attr->index]); | ||
855 | |||
856 | /* +16 degrees offset for temp2 for the LM99 */ | ||
857 | if (data->kind == lm99 && attr->index == 3) | ||
858 | temp += 16000; | ||
859 | 837 | ||
860 | return sprintf(buf, "%d\n", temp); | 838 | return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); |
861 | } | 839 | } |
862 | 840 | ||
863 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | 841 | static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, |
864 | const char *buf, size_t count) | 842 | const char *buf, size_t count) |
865 | { | 843 | { |
866 | static const u8 reg[TEMP8_REG_NUM] = { | 844 | struct i2c_client *client = to_i2c_client(dev); |
867 | LM90_REG_W_LOCAL_LOW, | ||
868 | LM90_REG_W_LOCAL_HIGH, | ||
869 | LM90_REG_W_LOCAL_CRIT, | ||
870 | LM90_REG_W_REMOTE_CRIT, | ||
871 | MAX6659_REG_W_LOCAL_EMERG, | ||
872 | MAX6659_REG_W_REMOTE_EMERG, | ||
873 | LM90_REG_W_REMOTE_CRIT, | ||
874 | MAX6659_REG_W_REMOTE_EMERG, | ||
875 | }; | ||
876 | |||
877 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
878 | struct lm90_data *data = dev_get_drvdata(dev); | ||
879 | struct i2c_client *client = data->client; | ||
880 | int nr = attr->index; | ||
881 | long val; | 845 | long val; |
882 | int err; | 846 | int err; |
883 | 847 | ||
@@ -885,82 +849,61 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
885 | if (err < 0) | 849 | if (err < 0) |
886 | return err; | 850 | return err; |
887 | 851 | ||
888 | /* +16 degrees offset for temp2 for the LM99 */ | 852 | switch (val) { |
889 | if (data->kind == lm99 && attr->index == 3) | 853 | case 0: |
890 | val -= 16000; | 854 | client->flags &= ~I2C_CLIENT_PEC; |
891 | 855 | break; | |
892 | mutex_lock(&data->update_lock); | 856 | case 1: |
893 | if (data->kind == adt7461 || data->kind == tmp451) | 857 | client->flags |= I2C_CLIENT_PEC; |
894 | data->temp8[nr] = temp_to_u8_adt7461(data, val); | 858 | break; |
895 | else if (data->kind == max6646) | 859 | default: |
896 | data->temp8[nr] = temp_to_u8(val); | 860 | return -EINVAL; |
897 | else | 861 | } |
898 | data->temp8[nr] = temp_to_s8(val); | ||
899 | |||
900 | lm90_select_remote_channel(client, data, nr >= 6); | ||
901 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); | ||
902 | lm90_select_remote_channel(client, data, 0); | ||
903 | 862 | ||
904 | mutex_unlock(&data->update_lock); | ||
905 | return count; | 863 | return count; |
906 | } | 864 | } |
907 | 865 | ||
908 | static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | 866 | static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); |
909 | char *buf) | 867 | |
868 | static int lm90_get_temp11(struct lm90_data *data, int index) | ||
910 | { | 869 | { |
911 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | 870 | s16 temp11 = data->temp11[index]; |
912 | struct lm90_data *data = lm90_update_device(dev); | ||
913 | int temp; | 871 | int temp; |
914 | 872 | ||
915 | if (IS_ERR(data)) | ||
916 | return PTR_ERR(data); | ||
917 | |||
918 | if (data->kind == adt7461 || data->kind == tmp451) | 873 | if (data->kind == adt7461 || data->kind == tmp451) |
919 | temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); | 874 | temp = temp_from_u16_adt7461(data, temp11); |
920 | else if (data->kind == max6646) | 875 | else if (data->kind == max6646) |
921 | temp = temp_from_u16(data->temp11[attr->index]); | 876 | temp = temp_from_u16(temp11); |
922 | else | 877 | else |
923 | temp = temp_from_s16(data->temp11[attr->index]); | 878 | temp = temp_from_s16(temp11); |
924 | 879 | ||
925 | /* +16 degrees offset for temp2 for the LM99 */ | 880 | /* +16 degrees offset for temp2 for the LM99 */ |
926 | if (data->kind == lm99 && attr->index <= 2) | 881 | if (data->kind == lm99 && index <= 2) |
927 | temp += 16000; | 882 | temp += 16000; |
928 | 883 | ||
929 | return sprintf(buf, "%d\n", temp); | 884 | return temp; |
930 | } | 885 | } |
931 | 886 | ||
932 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 887 | static int lm90_set_temp11(struct lm90_data *data, int index, long val) |
933 | const char *buf, size_t count) | ||
934 | { | 888 | { |
935 | struct { | 889 | static struct reg { |
936 | u8 high; | 890 | u8 high; |
937 | u8 low; | 891 | u8 low; |
938 | int channel; | 892 | } reg[] = { |
939 | } reg[5] = { | 893 | [REMOTE_LOW] = { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL }, |
940 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 0 }, | 894 | [REMOTE_HIGH] = { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL }, |
941 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 0 }, | 895 | [REMOTE_OFFSET] = { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL }, |
942 | { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL, 0 }, | 896 | [REMOTE2_LOW] = { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL }, |
943 | { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 1 }, | 897 | [REMOTE2_HIGH] = { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL } |
944 | { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 1 } | ||
945 | }; | 898 | }; |
946 | |||
947 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
948 | struct lm90_data *data = dev_get_drvdata(dev); | ||
949 | struct i2c_client *client = data->client; | 899 | struct i2c_client *client = data->client; |
950 | int nr = attr->nr; | 900 | struct reg *regp = ®[index]; |
951 | int index = attr->index; | ||
952 | long val; | ||
953 | int err; | 901 | int err; |
954 | 902 | ||
955 | err = kstrtol(buf, 10, &val); | ||
956 | if (err < 0) | ||
957 | return err; | ||
958 | |||
959 | /* +16 degrees offset for temp2 for the LM99 */ | 903 | /* +16 degrees offset for temp2 for the LM99 */ |
960 | if (data->kind == lm99 && index <= 2) | 904 | if (data->kind == lm99 && index <= 2) |
961 | val -= 16000; | 905 | val -= 16000; |
962 | 906 | ||
963 | mutex_lock(&data->update_lock); | ||
964 | if (data->kind == adt7461 || data->kind == tmp451) | 907 | if (data->kind == adt7461 || data->kind == tmp451) |
965 | data->temp11[index] = temp_to_u16_adt7461(data, val); | 908 | data->temp11[index] = temp_to_u16_adt7461(data, val); |
966 | else if (data->kind == max6646) | 909 | else if (data->kind == max6646) |
@@ -970,317 +913,383 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
970 | else | 913 | else |
971 | data->temp11[index] = temp_to_s8(val) << 8; | 914 | data->temp11[index] = temp_to_s8(val) << 8; |
972 | 915 | ||
973 | lm90_select_remote_channel(client, data, reg[nr].channel); | 916 | lm90_select_remote_channel(client, data, index >= 3); |
974 | i2c_smbus_write_byte_data(client, reg[nr].high, | 917 | err = i2c_smbus_write_byte_data(client, regp->high, |
975 | data->temp11[index] >> 8); | 918 | data->temp11[index] >> 8); |
919 | if (err < 0) | ||
920 | return err; | ||
976 | if (data->flags & LM90_HAVE_REM_LIMIT_EXT) | 921 | if (data->flags & LM90_HAVE_REM_LIMIT_EXT) |
977 | i2c_smbus_write_byte_data(client, reg[nr].low, | 922 | err = i2c_smbus_write_byte_data(client, regp->low, |
978 | data->temp11[index] & 0xff); | 923 | data->temp11[index] & 0xff); |
979 | lm90_select_remote_channel(client, data, 0); | ||
980 | 924 | ||
981 | mutex_unlock(&data->update_lock); | 925 | lm90_select_remote_channel(client, data, 0); |
982 | return count; | 926 | return err; |
983 | } | 927 | } |
984 | 928 | ||
985 | static ssize_t show_temphyst(struct device *dev, | 929 | static int lm90_get_temp8(struct lm90_data *data, int index) |
986 | struct device_attribute *devattr, | ||
987 | char *buf) | ||
988 | { | 930 | { |
989 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 931 | s8 temp8 = data->temp8[index]; |
990 | struct lm90_data *data = lm90_update_device(dev); | ||
991 | int temp; | 932 | int temp; |
992 | 933 | ||
993 | if (IS_ERR(data)) | ||
994 | return PTR_ERR(data); | ||
995 | |||
996 | if (data->kind == adt7461 || data->kind == tmp451) | 934 | if (data->kind == adt7461 || data->kind == tmp451) |
997 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | 935 | temp = temp_from_u8_adt7461(data, temp8); |
998 | else if (data->kind == max6646) | 936 | else if (data->kind == max6646) |
999 | temp = temp_from_u8(data->temp8[attr->index]); | 937 | temp = temp_from_u8(temp8); |
1000 | else | 938 | else |
1001 | temp = temp_from_s8(data->temp8[attr->index]); | 939 | temp = temp_from_s8(temp8); |
1002 | 940 | ||
1003 | /* +16 degrees offset for temp2 for the LM99 */ | 941 | /* +16 degrees offset for temp2 for the LM99 */ |
1004 | if (data->kind == lm99 && attr->index == 3) | 942 | if (data->kind == lm99 && index == 3) |
1005 | temp += 16000; | 943 | temp += 16000; |
1006 | 944 | ||
1007 | return sprintf(buf, "%d\n", temp - temp_from_s8(data->temp_hyst)); | 945 | return temp; |
1008 | } | 946 | } |
1009 | 947 | ||
1010 | static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, | 948 | static int lm90_set_temp8(struct lm90_data *data, int index, long val) |
1011 | const char *buf, size_t count) | ||
1012 | { | 949 | { |
1013 | struct lm90_data *data = dev_get_drvdata(dev); | 950 | static const u8 reg[TEMP8_REG_NUM] = { |
951 | LM90_REG_W_LOCAL_LOW, | ||
952 | LM90_REG_W_LOCAL_HIGH, | ||
953 | LM90_REG_W_LOCAL_CRIT, | ||
954 | LM90_REG_W_REMOTE_CRIT, | ||
955 | MAX6659_REG_W_LOCAL_EMERG, | ||
956 | MAX6659_REG_W_REMOTE_EMERG, | ||
957 | LM90_REG_W_REMOTE_CRIT, | ||
958 | MAX6659_REG_W_REMOTE_EMERG, | ||
959 | }; | ||
1014 | struct i2c_client *client = data->client; | 960 | struct i2c_client *client = data->client; |
1015 | long val; | ||
1016 | int err; | 961 | int err; |
1017 | int temp; | ||
1018 | 962 | ||
1019 | err = kstrtol(buf, 10, &val); | 963 | /* +16 degrees offset for temp2 for the LM99 */ |
1020 | if (err < 0) | 964 | if (data->kind == lm99 && index == 3) |
1021 | return err; | 965 | val -= 16000; |
1022 | 966 | ||
1023 | mutex_lock(&data->update_lock); | ||
1024 | if (data->kind == adt7461 || data->kind == tmp451) | 967 | if (data->kind == adt7461 || data->kind == tmp451) |
1025 | temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]); | 968 | data->temp8[index] = temp_to_u8_adt7461(data, val); |
1026 | else if (data->kind == max6646) | 969 | else if (data->kind == max6646) |
1027 | temp = temp_from_u8(data->temp8[LOCAL_CRIT]); | 970 | data->temp8[index] = temp_to_u8(val); |
1028 | else | 971 | else |
1029 | temp = temp_from_s8(data->temp8[LOCAL_CRIT]); | 972 | data->temp8[index] = temp_to_s8(val); |
1030 | 973 | ||
1031 | data->temp_hyst = hyst_to_reg(temp - val); | 974 | lm90_select_remote_channel(client, data, index >= 6); |
1032 | i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, | 975 | err = i2c_smbus_write_byte_data(client, reg[index], data->temp8[index]); |
1033 | data->temp_hyst); | 976 | lm90_select_remote_channel(client, data, 0); |
1034 | mutex_unlock(&data->update_lock); | ||
1035 | return count; | ||
1036 | } | ||
1037 | |||
1038 | static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, | ||
1039 | char *buf) | ||
1040 | { | ||
1041 | struct lm90_data *data = lm90_update_device(dev); | ||
1042 | |||
1043 | if (IS_ERR(data)) | ||
1044 | return PTR_ERR(data); | ||
1045 | 977 | ||
1046 | return sprintf(buf, "%d\n", data->alarms); | 978 | return err; |
1047 | } | 979 | } |
1048 | 980 | ||
1049 | static ssize_t show_alarm(struct device *dev, struct device_attribute | 981 | static int lm90_get_temphyst(struct lm90_data *data, int index) |
1050 | *devattr, char *buf) | ||
1051 | { | 982 | { |
1052 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 983 | int temp; |
1053 | struct lm90_data *data = lm90_update_device(dev); | ||
1054 | int bitnr = attr->index; | ||
1055 | |||
1056 | if (IS_ERR(data)) | ||
1057 | return PTR_ERR(data); | ||
1058 | 984 | ||
1059 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | 985 | if (data->kind == adt7461 || data->kind == tmp451) |
1060 | } | 986 | temp = temp_from_u8_adt7461(data, data->temp8[index]); |
987 | else if (data->kind == max6646) | ||
988 | temp = temp_from_u8(data->temp8[index]); | ||
989 | else | ||
990 | temp = temp_from_s8(data->temp8[index]); | ||
1061 | 991 | ||
1062 | static ssize_t show_update_interval(struct device *dev, | 992 | /* +16 degrees offset for temp2 for the LM99 */ |
1063 | struct device_attribute *attr, char *buf) | 993 | if (data->kind == lm99 && index == 3) |
1064 | { | 994 | temp += 16000; |
1065 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1066 | 995 | ||
1067 | return sprintf(buf, "%u\n", data->update_interval); | 996 | return temp - temp_from_s8(data->temp_hyst); |
1068 | } | 997 | } |
1069 | 998 | ||
1070 | static ssize_t set_update_interval(struct device *dev, | 999 | static int lm90_set_temphyst(struct lm90_data *data, long val) |
1071 | struct device_attribute *attr, | ||
1072 | const char *buf, size_t count) | ||
1073 | { | 1000 | { |
1074 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1075 | struct i2c_client *client = data->client; | 1001 | struct i2c_client *client = data->client; |
1076 | unsigned long val; | 1002 | int temp; |
1077 | int err; | 1003 | int err; |
1078 | 1004 | ||
1079 | err = kstrtoul(buf, 10, &val); | 1005 | if (data->kind == adt7461 || data->kind == tmp451) |
1080 | if (err) | 1006 | temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]); |
1081 | return err; | 1007 | else if (data->kind == max6646) |
1082 | 1008 | temp = temp_from_u8(data->temp8[LOCAL_CRIT]); | |
1083 | mutex_lock(&data->update_lock); | 1009 | else |
1084 | lm90_set_convrate(client, data, clamp_val(val, 0, 100000)); | 1010 | temp = temp_from_s8(data->temp8[LOCAL_CRIT]); |
1085 | mutex_unlock(&data->update_lock); | ||
1086 | 1011 | ||
1087 | return count; | 1012 | data->temp_hyst = hyst_to_reg(temp - val); |
1013 | err = i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, | ||
1014 | data->temp_hyst); | ||
1015 | return err; | ||
1088 | } | 1016 | } |
1089 | 1017 | ||
1090 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp11, NULL, | 1018 | static const u8 lm90_temp_index[3] = { |
1091 | 0, LOCAL_TEMP); | 1019 | LOCAL_TEMP, REMOTE_TEMP, REMOTE2_TEMP |
1092 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp11, NULL, | ||
1093 | 0, REMOTE_TEMP); | ||
1094 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, | ||
1095 | set_temp8, LOCAL_LOW); | ||
1096 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp11, | ||
1097 | set_temp11, 0, REMOTE_LOW); | ||
1098 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, | ||
1099 | set_temp8, LOCAL_HIGH); | ||
1100 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp11, | ||
1101 | set_temp11, 1, REMOTE_HIGH); | ||
1102 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
1103 | set_temp8, LOCAL_CRIT); | ||
1104 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
1105 | set_temp8, REMOTE_CRIT); | ||
1106 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, | ||
1107 | set_temphyst, LOCAL_CRIT); | ||
1108 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, | ||
1109 | REMOTE_CRIT); | ||
1110 | static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, | ||
1111 | set_temp11, 2, REMOTE_OFFSET); | ||
1112 | |||
1113 | /* Individual alarm files */ | ||
1114 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
1115 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
1116 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); | ||
1117 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
1118 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
1119 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); | ||
1120 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
1121 | /* Raw alarm file for compatibility */ | ||
1122 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
1123 | |||
1124 | static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, | ||
1125 | set_update_interval); | ||
1126 | |||
1127 | static struct attribute *lm90_attributes[] = { | ||
1128 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1129 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1130 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
1131 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
1132 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
1133 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
1134 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
1135 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
1136 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
1137 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
1138 | |||
1139 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
1140 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
1141 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
1142 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
1143 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
1144 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
1145 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
1146 | &dev_attr_alarms.attr, | ||
1147 | &dev_attr_update_interval.attr, | ||
1148 | NULL | ||
1149 | }; | 1020 | }; |
1150 | 1021 | ||
1151 | static const struct attribute_group lm90_group = { | 1022 | static const u8 lm90_temp_min_index[3] = { |
1152 | .attrs = lm90_attributes, | 1023 | LOCAL_LOW, REMOTE_LOW, REMOTE2_LOW |
1153 | }; | 1024 | }; |
1154 | 1025 | ||
1155 | static struct attribute *lm90_temp2_offset_attributes[] = { | 1026 | static const u8 lm90_temp_max_index[3] = { |
1156 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 1027 | LOCAL_HIGH, REMOTE_HIGH, REMOTE2_HIGH |
1157 | NULL | ||
1158 | }; | 1028 | }; |
1159 | 1029 | ||
1160 | static const struct attribute_group lm90_temp2_offset_group = { | 1030 | static const u8 lm90_temp_crit_index[3] = { |
1161 | .attrs = lm90_temp2_offset_attributes, | 1031 | LOCAL_CRIT, REMOTE_CRIT, REMOTE2_CRIT |
1162 | }; | 1032 | }; |
1163 | 1033 | ||
1164 | /* | 1034 | static const u8 lm90_temp_emerg_index[3] = { |
1165 | * Additional attributes for devices with emergency sensors | 1035 | LOCAL_EMERG, REMOTE_EMERG, REMOTE2_EMERG |
1166 | */ | ||
1167 | static SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
1168 | set_temp8, LOCAL_EMERG); | ||
1169 | static SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
1170 | set_temp8, REMOTE_EMERG); | ||
1171 | static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO, show_temphyst, | ||
1172 | NULL, LOCAL_EMERG); | ||
1173 | static SENSOR_DEVICE_ATTR(temp2_emergency_hyst, S_IRUGO, show_temphyst, | ||
1174 | NULL, REMOTE_EMERG); | ||
1175 | |||
1176 | static struct attribute *lm90_emergency_attributes[] = { | ||
1177 | &sensor_dev_attr_temp1_emergency.dev_attr.attr, | ||
1178 | &sensor_dev_attr_temp2_emergency.dev_attr.attr, | ||
1179 | &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr, | ||
1180 | &sensor_dev_attr_temp2_emergency_hyst.dev_attr.attr, | ||
1181 | NULL | ||
1182 | }; | 1036 | }; |
1183 | 1037 | ||
1184 | static const struct attribute_group lm90_emergency_group = { | 1038 | static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 }; |
1185 | .attrs = lm90_emergency_attributes, | 1039 | static const u8 lm90_max_alarm_bits[3] = { 0, 4, 12 }; |
1186 | }; | 1040 | static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 }; |
1041 | static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 }; | ||
1042 | static const u8 lm90_fault_bits[3] = { 0, 2, 10 }; | ||
1187 | 1043 | ||
1188 | static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_alarm, NULL, 15); | 1044 | static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val) |
1189 | static SENSOR_DEVICE_ATTR(temp2_emergency_alarm, S_IRUGO, show_alarm, NULL, 13); | 1045 | { |
1046 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1047 | int err; | ||
1190 | 1048 | ||
1191 | static struct attribute *lm90_emergency_alarm_attributes[] = { | 1049 | mutex_lock(&data->update_lock); |
1192 | &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, | 1050 | err = lm90_update_device(dev); |
1193 | &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr, | 1051 | mutex_unlock(&data->update_lock); |
1194 | NULL | 1052 | if (err) |
1195 | }; | 1053 | return err; |
1196 | 1054 | ||
1197 | static const struct attribute_group lm90_emergency_alarm_group = { | 1055 | switch (attr) { |
1198 | .attrs = lm90_emergency_alarm_attributes, | 1056 | case hwmon_temp_input: |
1199 | }; | 1057 | *val = lm90_get_temp11(data, lm90_temp_index[channel]); |
1058 | break; | ||
1059 | case hwmon_temp_min_alarm: | ||
1060 | *val = (data->alarms >> lm90_min_alarm_bits[channel]) & 1; | ||
1061 | break; | ||
1062 | case hwmon_temp_max_alarm: | ||
1063 | *val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1; | ||
1064 | break; | ||
1065 | case hwmon_temp_crit_alarm: | ||
1066 | *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1; | ||
1067 | break; | ||
1068 | case hwmon_temp_emergency_alarm: | ||
1069 | *val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1; | ||
1070 | break; | ||
1071 | case hwmon_temp_fault: | ||
1072 | *val = (data->alarms >> lm90_fault_bits[channel]) & 1; | ||
1073 | break; | ||
1074 | case hwmon_temp_min: | ||
1075 | if (channel == 0) | ||
1076 | *val = lm90_get_temp8(data, | ||
1077 | lm90_temp_min_index[channel]); | ||
1078 | else | ||
1079 | *val = lm90_get_temp11(data, | ||
1080 | lm90_temp_min_index[channel]); | ||
1081 | break; | ||
1082 | case hwmon_temp_max: | ||
1083 | if (channel == 0) | ||
1084 | *val = lm90_get_temp8(data, | ||
1085 | lm90_temp_max_index[channel]); | ||
1086 | else | ||
1087 | *val = lm90_get_temp11(data, | ||
1088 | lm90_temp_max_index[channel]); | ||
1089 | break; | ||
1090 | case hwmon_temp_crit: | ||
1091 | *val = lm90_get_temp8(data, lm90_temp_crit_index[channel]); | ||
1092 | break; | ||
1093 | case hwmon_temp_crit_hyst: | ||
1094 | *val = lm90_get_temphyst(data, lm90_temp_crit_index[channel]); | ||
1095 | break; | ||
1096 | case hwmon_temp_emergency: | ||
1097 | *val = lm90_get_temp8(data, lm90_temp_emerg_index[channel]); | ||
1098 | break; | ||
1099 | case hwmon_temp_emergency_hyst: | ||
1100 | *val = lm90_get_temphyst(data, lm90_temp_emerg_index[channel]); | ||
1101 | break; | ||
1102 | case hwmon_temp_offset: | ||
1103 | *val = lm90_get_temp11(data, REMOTE_OFFSET); | ||
1104 | break; | ||
1105 | default: | ||
1106 | return -EOPNOTSUPP; | ||
1107 | } | ||
1108 | return 0; | ||
1109 | } | ||
1200 | 1110 | ||
1201 | /* | 1111 | static int lm90_temp_write(struct device *dev, u32 attr, int channel, long val) |
1202 | * Additional attributes for devices with 3 temperature sensors | 1112 | { |
1203 | */ | 1113 | struct lm90_data *data = dev_get_drvdata(dev); |
1204 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp11, NULL, | 1114 | int err; |
1205 | 0, REMOTE2_TEMP); | ||
1206 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp11, | ||
1207 | set_temp11, 3, REMOTE2_LOW); | ||
1208 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp11, | ||
1209 | set_temp11, 4, REMOTE2_HIGH); | ||
1210 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp8, | ||
1211 | set_temp8, REMOTE2_CRIT); | ||
1212 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temphyst, NULL, | ||
1213 | REMOTE2_CRIT); | ||
1214 | static SENSOR_DEVICE_ATTR(temp3_emergency, S_IWUSR | S_IRUGO, show_temp8, | ||
1215 | set_temp8, REMOTE2_EMERG); | ||
1216 | static SENSOR_DEVICE_ATTR(temp3_emergency_hyst, S_IRUGO, show_temphyst, | ||
1217 | NULL, REMOTE2_EMERG); | ||
1218 | |||
1219 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 9); | ||
1220 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 10); | ||
1221 | static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 11); | ||
1222 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 12); | ||
1223 | static SENSOR_DEVICE_ATTR(temp3_emergency_alarm, S_IRUGO, show_alarm, NULL, 14); | ||
1224 | |||
1225 | static struct attribute *lm90_temp3_attributes[] = { | ||
1226 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1227 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
1228 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
1229 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
1230 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | ||
1231 | &sensor_dev_attr_temp3_emergency.dev_attr.attr, | ||
1232 | &sensor_dev_attr_temp3_emergency_hyst.dev_attr.attr, | ||
1233 | |||
1234 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
1235 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | ||
1236 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
1237 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
1238 | &sensor_dev_attr_temp3_emergency_alarm.dev_attr.attr, | ||
1239 | NULL | ||
1240 | }; | ||
1241 | 1115 | ||
1242 | static const struct attribute_group lm90_temp3_group = { | 1116 | mutex_lock(&data->update_lock); |
1243 | .attrs = lm90_temp3_attributes, | ||
1244 | }; | ||
1245 | 1117 | ||
1246 | /* pec used for ADM1032 only */ | 1118 | err = lm90_update_device(dev); |
1247 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, | 1119 | if (err) |
1248 | char *buf) | 1120 | goto error; |
1121 | |||
1122 | switch (attr) { | ||
1123 | case hwmon_temp_min: | ||
1124 | if (channel == 0) | ||
1125 | err = lm90_set_temp8(data, | ||
1126 | lm90_temp_min_index[channel], | ||
1127 | val); | ||
1128 | else | ||
1129 | err = lm90_set_temp11(data, | ||
1130 | lm90_temp_min_index[channel], | ||
1131 | val); | ||
1132 | break; | ||
1133 | case hwmon_temp_max: | ||
1134 | if (channel == 0) | ||
1135 | err = lm90_set_temp8(data, | ||
1136 | lm90_temp_max_index[channel], | ||
1137 | val); | ||
1138 | else | ||
1139 | err = lm90_set_temp11(data, | ||
1140 | lm90_temp_max_index[channel], | ||
1141 | val); | ||
1142 | break; | ||
1143 | case hwmon_temp_crit: | ||
1144 | err = lm90_set_temp8(data, lm90_temp_crit_index[channel], val); | ||
1145 | break; | ||
1146 | case hwmon_temp_crit_hyst: | ||
1147 | err = lm90_set_temphyst(data, val); | ||
1148 | break; | ||
1149 | case hwmon_temp_emergency: | ||
1150 | err = lm90_set_temp8(data, lm90_temp_emerg_index[channel], val); | ||
1151 | break; | ||
1152 | case hwmon_temp_offset: | ||
1153 | err = lm90_set_temp11(data, REMOTE_OFFSET, val); | ||
1154 | break; | ||
1155 | default: | ||
1156 | err = -EOPNOTSUPP; | ||
1157 | break; | ||
1158 | } | ||
1159 | error: | ||
1160 | mutex_unlock(&data->update_lock); | ||
1161 | |||
1162 | return err; | ||
1163 | } | ||
1164 | |||
1165 | static umode_t lm90_temp_is_visible(const void *data, u32 attr, int channel) | ||
1249 | { | 1166 | { |
1250 | struct i2c_client *client = to_i2c_client(dev); | 1167 | switch (attr) { |
1251 | return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); | 1168 | case hwmon_temp_input: |
1169 | case hwmon_temp_min_alarm: | ||
1170 | case hwmon_temp_max_alarm: | ||
1171 | case hwmon_temp_crit_alarm: | ||
1172 | case hwmon_temp_emergency_alarm: | ||
1173 | case hwmon_temp_emergency_hyst: | ||
1174 | case hwmon_temp_fault: | ||
1175 | return S_IRUGO; | ||
1176 | case hwmon_temp_min: | ||
1177 | case hwmon_temp_max: | ||
1178 | case hwmon_temp_crit: | ||
1179 | case hwmon_temp_emergency: | ||
1180 | case hwmon_temp_offset: | ||
1181 | return S_IRUGO | S_IWUSR; | ||
1182 | case hwmon_temp_crit_hyst: | ||
1183 | if (channel == 0) | ||
1184 | return S_IRUGO | S_IWUSR; | ||
1185 | return S_IRUGO; | ||
1186 | default: | ||
1187 | return 0; | ||
1188 | } | ||
1252 | } | 1189 | } |
1253 | 1190 | ||
1254 | static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, | 1191 | static int lm90_chip_read(struct device *dev, u32 attr, int channel, long *val) |
1255 | const char *buf, size_t count) | ||
1256 | { | 1192 | { |
1257 | struct i2c_client *client = to_i2c_client(dev); | 1193 | struct lm90_data *data = dev_get_drvdata(dev); |
1258 | long val; | ||
1259 | int err; | 1194 | int err; |
1260 | 1195 | ||
1261 | err = kstrtol(buf, 10, &val); | 1196 | mutex_lock(&data->update_lock); |
1262 | if (err < 0) | 1197 | err = lm90_update_device(dev); |
1198 | mutex_unlock(&data->update_lock); | ||
1199 | if (err) | ||
1263 | return err; | 1200 | return err; |
1264 | 1201 | ||
1265 | switch (val) { | 1202 | switch (attr) { |
1266 | case 0: | 1203 | case hwmon_chip_update_interval: |
1267 | client->flags &= ~I2C_CLIENT_PEC; | 1204 | *val = data->update_interval; |
1268 | break; | 1205 | break; |
1269 | case 1: | 1206 | case hwmon_chip_alarms: |
1270 | client->flags |= I2C_CLIENT_PEC; | 1207 | *val = data->alarms; |
1271 | break; | 1208 | break; |
1272 | default: | 1209 | default: |
1273 | return -EINVAL; | 1210 | return -EOPNOTSUPP; |
1274 | } | 1211 | } |
1275 | 1212 | ||
1276 | return count; | 1213 | return 0; |
1277 | } | 1214 | } |
1278 | 1215 | ||
1279 | static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); | 1216 | static int lm90_chip_write(struct device *dev, u32 attr, int channel, long val) |
1217 | { | ||
1218 | struct lm90_data *data = dev_get_drvdata(dev); | ||
1219 | struct i2c_client *client = data->client; | ||
1220 | int err; | ||
1280 | 1221 | ||
1281 | /* | 1222 | mutex_lock(&data->update_lock); |
1282 | * Real code | 1223 | |
1283 | */ | 1224 | err = lm90_update_device(dev); |
1225 | if (err) | ||
1226 | goto error; | ||
1227 | |||
1228 | switch (attr) { | ||
1229 | case hwmon_chip_update_interval: | ||
1230 | err = lm90_set_convrate(client, data, | ||
1231 | clamp_val(val, 0, 100000)); | ||
1232 | break; | ||
1233 | default: | ||
1234 | err = -EOPNOTSUPP; | ||
1235 | break; | ||
1236 | } | ||
1237 | error: | ||
1238 | mutex_unlock(&data->update_lock); | ||
1239 | |||
1240 | return err; | ||
1241 | } | ||
1242 | |||
1243 | static umode_t lm90_chip_is_visible(const void *data, u32 attr, int channel) | ||
1244 | { | ||
1245 | switch (attr) { | ||
1246 | case hwmon_chip_update_interval: | ||
1247 | return S_IRUGO | S_IWUSR; | ||
1248 | case hwmon_chip_alarms: | ||
1249 | return S_IRUGO; | ||
1250 | default: | ||
1251 | return 0; | ||
1252 | } | ||
1253 | } | ||
1254 | |||
1255 | static int lm90_read(struct device *dev, enum hwmon_sensor_types type, | ||
1256 | u32 attr, int channel, long *val) | ||
1257 | { | ||
1258 | switch (type) { | ||
1259 | case hwmon_chip: | ||
1260 | return lm90_chip_read(dev, attr, channel, val); | ||
1261 | case hwmon_temp: | ||
1262 | return lm90_temp_read(dev, attr, channel, val); | ||
1263 | default: | ||
1264 | return -EOPNOTSUPP; | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1268 | static int lm90_write(struct device *dev, enum hwmon_sensor_types type, | ||
1269 | u32 attr, int channel, long val) | ||
1270 | { | ||
1271 | switch (type) { | ||
1272 | case hwmon_chip: | ||
1273 | return lm90_chip_write(dev, attr, channel, val); | ||
1274 | case hwmon_temp: | ||
1275 | return lm90_temp_write(dev, attr, channel, val); | ||
1276 | default: | ||
1277 | return -EOPNOTSUPP; | ||
1278 | } | ||
1279 | } | ||
1280 | |||
1281 | static umode_t lm90_is_visible(const void *data, enum hwmon_sensor_types type, | ||
1282 | u32 attr, int channel) | ||
1283 | { | ||
1284 | switch (type) { | ||
1285 | case hwmon_chip: | ||
1286 | return lm90_chip_is_visible(data, attr, channel); | ||
1287 | case hwmon_temp: | ||
1288 | return lm90_temp_is_visible(data, attr, channel); | ||
1289 | default: | ||
1290 | return 0; | ||
1291 | } | ||
1292 | } | ||
1284 | 1293 | ||
1285 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1294 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1286 | static int lm90_detect(struct i2c_client *client, | 1295 | static int lm90_detect(struct i2c_client *client, |
@@ -1617,15 +1626,32 @@ static void lm90_regulator_disable(void *regulator) | |||
1617 | regulator_disable(regulator); | 1626 | regulator_disable(regulator); |
1618 | } | 1627 | } |
1619 | 1628 | ||
1629 | static const u32 lm90_chip_config[] = { | ||
1630 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL | HWMON_C_ALARMS, | ||
1631 | 0 | ||
1632 | }; | ||
1633 | |||
1634 | static const struct hwmon_channel_info lm90_chip_info = { | ||
1635 | .type = hwmon_chip, | ||
1636 | .config = lm90_chip_config, | ||
1637 | }; | ||
1638 | |||
1639 | |||
1640 | static const struct hwmon_ops lm90_ops = { | ||
1641 | .is_visible = lm90_is_visible, | ||
1642 | .read = lm90_read, | ||
1643 | .write = lm90_write, | ||
1644 | }; | ||
1645 | |||
1620 | static int lm90_probe(struct i2c_client *client, | 1646 | static int lm90_probe(struct i2c_client *client, |
1621 | const struct i2c_device_id *id) | 1647 | const struct i2c_device_id *id) |
1622 | { | 1648 | { |
1623 | struct device *dev = &client->dev; | 1649 | struct device *dev = &client->dev; |
1624 | struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); | 1650 | struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); |
1625 | struct lm90_data *data; | 1651 | struct hwmon_channel_info *info; |
1626 | struct regulator *regulator; | 1652 | struct regulator *regulator; |
1627 | struct device *hwmon_dev; | 1653 | struct device *hwmon_dev; |
1628 | int groups = 0; | 1654 | struct lm90_data *data; |
1629 | int err; | 1655 | int err; |
1630 | 1656 | ||
1631 | regulator = devm_regulator_get(dev, "vcc"); | 1657 | regulator = devm_regulator_get(dev, "vcc"); |
@@ -1665,6 +1691,49 @@ static int lm90_probe(struct i2c_client *client, | |||
1665 | 1691 | ||
1666 | /* Set chip capabilities */ | 1692 | /* Set chip capabilities */ |
1667 | data->flags = lm90_params[data->kind].flags; | 1693 | data->flags = lm90_params[data->kind].flags; |
1694 | |||
1695 | data->chip.ops = &lm90_ops; | ||
1696 | data->chip.info = data->info; | ||
1697 | |||
1698 | data->info[0] = &lm90_chip_info; | ||
1699 | data->info[1] = &data->temp_info; | ||
1700 | |||
1701 | info = &data->temp_info; | ||
1702 | info->type = hwmon_temp; | ||
1703 | info->config = data->channel_config; | ||
1704 | |||
1705 | data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | | ||
1706 | HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | | ||
1707 | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM; | ||
1708 | data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | | ||
1709 | HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | | ||
1710 | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT; | ||
1711 | |||
1712 | if (data->flags & LM90_HAVE_OFFSET) | ||
1713 | data->channel_config[1] |= HWMON_T_OFFSET; | ||
1714 | |||
1715 | if (data->flags & LM90_HAVE_EMERGENCY) { | ||
1716 | data->channel_config[0] |= HWMON_T_EMERGENCY | | ||
1717 | HWMON_T_EMERGENCY_HYST; | ||
1718 | data->channel_config[1] |= HWMON_T_EMERGENCY | | ||
1719 | HWMON_T_EMERGENCY_HYST; | ||
1720 | } | ||
1721 | |||
1722 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { | ||
1723 | data->channel_config[0] |= HWMON_T_EMERGENCY_ALARM; | ||
1724 | data->channel_config[1] |= HWMON_T_EMERGENCY_ALARM; | ||
1725 | } | ||
1726 | |||
1727 | if (data->flags & LM90_HAVE_TEMP3) { | ||
1728 | data->channel_config[2] = HWMON_T_INPUT | | ||
1729 | HWMON_T_MIN | HWMON_T_MAX | | ||
1730 | HWMON_T_CRIT | HWMON_T_CRIT_HYST | | ||
1731 | HWMON_T_EMERGENCY | HWMON_T_EMERGENCY_HYST | | ||
1732 | HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | | ||
1733 | HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY_ALARM | | ||
1734 | HWMON_T_FAULT; | ||
1735 | } | ||
1736 | |||
1668 | data->reg_local_ext = lm90_params[data->kind].reg_local_ext; | 1737 | data->reg_local_ext = lm90_params[data->kind].reg_local_ext; |
1669 | 1738 | ||
1670 | /* Set maximum conversion rate */ | 1739 | /* Set maximum conversion rate */ |
@@ -1677,21 +1746,10 @@ static int lm90_probe(struct i2c_client *client, | |||
1677 | return err; | 1746 | return err; |
1678 | } | 1747 | } |
1679 | 1748 | ||
1680 | /* Register sysfs hooks */ | 1749 | /* |
1681 | data->groups[groups++] = &lm90_group; | 1750 | * The 'pec' attribute is attached to the i2c device and thus created |
1682 | 1751 | * separately. | |
1683 | if (data->flags & LM90_HAVE_OFFSET) | 1752 | */ |
1684 | data->groups[groups++] = &lm90_temp2_offset_group; | ||
1685 | |||
1686 | if (data->flags & LM90_HAVE_EMERGENCY) | ||
1687 | data->groups[groups++] = &lm90_emergency_group; | ||
1688 | |||
1689 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) | ||
1690 | data->groups[groups++] = &lm90_emergency_alarm_group; | ||
1691 | |||
1692 | if (data->flags & LM90_HAVE_TEMP3) | ||
1693 | data->groups[groups++] = &lm90_temp3_group; | ||
1694 | |||
1695 | if (client->flags & I2C_CLIENT_PEC) { | 1753 | if (client->flags & I2C_CLIENT_PEC) { |
1696 | err = device_create_file(dev, &dev_attr_pec); | 1754 | err = device_create_file(dev, &dev_attr_pec); |
1697 | if (err) | 1755 | if (err) |
@@ -1701,8 +1759,9 @@ static int lm90_probe(struct i2c_client *client, | |||
1701 | return err; | 1759 | return err; |
1702 | } | 1760 | } |
1703 | 1761 | ||
1704 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 1762 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
1705 | data, data->groups); | 1763 | data, &data->chip, |
1764 | NULL); | ||
1706 | if (IS_ERR(hwmon_dev)) | 1765 | if (IS_ERR(hwmon_dev)) |
1707 | return PTR_ERR(hwmon_dev); | 1766 | return PTR_ERR(hwmon_dev); |
1708 | 1767 | ||
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index cdf19adaec79..8c573e6e9726 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c | |||
@@ -15,22 +15,17 @@ | |||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | 18 | */ |
23 | 19 | ||
24 | #include <linux/module.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/err.h> | ||
22 | #include <linux/i2c.h> | ||
25 | #include <linux/init.h> | 23 | #include <linux/init.h> |
26 | #include <linux/slab.h> | ||
27 | #include <linux/jiffies.h> | 24 | #include <linux/jiffies.h> |
28 | #include <linux/i2c.h> | ||
29 | #include <linux/hwmon.h> | 25 | #include <linux/hwmon.h> |
30 | #include <linux/hwmon-sysfs.h> | 26 | #include <linux/module.h> |
31 | #include <linux/err.h> | ||
32 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
33 | #include <linux/sysfs.h> | 28 | #include <linux/slab.h> |
34 | 29 | ||
35 | #define DEVNAME "lm95241" | 30 | #define DEVNAME "lm95241" |
36 | 31 | ||
@@ -54,26 +49,25 @@ static const unsigned short normal_i2c[] = { | |||
54 | #define LM95241_REG_RW_REMOTE_MODEL 0x30 | 49 | #define LM95241_REG_RW_REMOTE_MODEL 0x30 |
55 | 50 | ||
56 | /* LM95241 specific bitfields */ | 51 | /* LM95241 specific bitfields */ |
57 | #define CFG_STOP 0x40 | 52 | #define CFG_STOP BIT(6) |
58 | #define CFG_CR0076 0x00 | 53 | #define CFG_CR0076 0x00 |
59 | #define CFG_CR0182 0x10 | 54 | #define CFG_CR0182 BIT(4) |
60 | #define CFG_CR1000 0x20 | 55 | #define CFG_CR1000 BIT(5) |
61 | #define CFG_CR2700 0x30 | 56 | #define CFG_CR2700 (BIT(4) | BIT(5)) |
62 | #define R1MS_SHIFT 0 | 57 | #define CFG_CRMASK (BIT(4) | BIT(5)) |
63 | #define R2MS_SHIFT 2 | 58 | #define R1MS_MASK BIT(0) |
64 | #define R1MS_MASK (0x01 << (R1MS_SHIFT)) | 59 | #define R2MS_MASK BIT(2) |
65 | #define R2MS_MASK (0x01 << (R2MS_SHIFT)) | 60 | #define R1DF_MASK BIT(1) |
66 | #define R1DF_SHIFT 1 | 61 | #define R2DF_MASK BIT(2) |
67 | #define R2DF_SHIFT 2 | 62 | #define R1FE_MASK BIT(0) |
68 | #define R1DF_MASK (0x01 << (R1DF_SHIFT)) | 63 | #define R2FE_MASK BIT(2) |
69 | #define R2DF_MASK (0x01 << (R2DF_SHIFT)) | 64 | #define R1DM BIT(0) |
70 | #define R1FE_MASK 0x01 | 65 | #define R2DM BIT(1) |
71 | #define R2FE_MASK 0x05 | 66 | #define TT1_SHIFT 0 |
72 | #define TT1_SHIFT 0 | 67 | #define TT2_SHIFT 4 |
73 | #define TT2_SHIFT 4 | 68 | #define TT_OFF 0 |
74 | #define TT_OFF 0 | 69 | #define TT_ON 1 |
75 | #define TT_ON 1 | 70 | #define TT_MASK 7 |
76 | #define TT_MASK 7 | ||
77 | #define NATSEMI_MAN_ID 0x01 | 71 | #define NATSEMI_MAN_ID 0x01 |
78 | #define LM95231_CHIP_ID 0xA1 | 72 | #define LM95231_CHIP_ID 0xA1 |
79 | #define LM95241_CHIP_ID 0xA4 | 73 | #define LM95241_CHIP_ID 0xA4 |
@@ -91,11 +85,12 @@ static const u8 lm95241_reg_address[] = { | |||
91 | struct lm95241_data { | 85 | struct lm95241_data { |
92 | struct i2c_client *client; | 86 | struct i2c_client *client; |
93 | struct mutex update_lock; | 87 | struct mutex update_lock; |
94 | unsigned long last_updated, interval; /* in jiffies */ | 88 | unsigned long last_updated; /* in jiffies */ |
89 | unsigned long interval; /* in milli-seconds */ | ||
95 | char valid; /* zero until following fields are valid */ | 90 | char valid; /* zero until following fields are valid */ |
96 | /* registers values */ | 91 | /* registers values */ |
97 | u8 temp[ARRAY_SIZE(lm95241_reg_address)]; | 92 | u8 temp[ARRAY_SIZE(lm95241_reg_address)]; |
98 | u8 config, model, trutherm; | 93 | u8 status, config, model, trutherm; |
99 | }; | 94 | }; |
100 | 95 | ||
101 | /* Conversions */ | 96 | /* Conversions */ |
@@ -118,7 +113,8 @@ static struct lm95241_data *lm95241_update_device(struct device *dev) | |||
118 | 113 | ||
119 | mutex_lock(&data->update_lock); | 114 | mutex_lock(&data->update_lock); |
120 | 115 | ||
121 | if (time_after(jiffies, data->last_updated + data->interval) || | 116 | if (time_after(jiffies, data->last_updated |
117 | + msecs_to_jiffies(data->interval)) || | ||
122 | !data->valid) { | 118 | !data->valid) { |
123 | int i; | 119 | int i; |
124 | 120 | ||
@@ -127,6 +123,9 @@ static struct lm95241_data *lm95241_update_device(struct device *dev) | |||
127 | data->temp[i] | 123 | data->temp[i] |
128 | = i2c_smbus_read_byte_data(client, | 124 | = i2c_smbus_read_byte_data(client, |
129 | lm95241_reg_address[i]); | 125 | lm95241_reg_address[i]); |
126 | |||
127 | data->status = i2c_smbus_read_byte_data(client, | ||
128 | LM95241_REG_R_STATUS); | ||
130 | data->last_updated = jiffies; | 129 | data->last_updated = jiffies; |
131 | data->valid = 1; | 130 | data->valid = 1; |
132 | } | 131 | } |
@@ -136,197 +135,241 @@ static struct lm95241_data *lm95241_update_device(struct device *dev) | |||
136 | return data; | 135 | return data; |
137 | } | 136 | } |
138 | 137 | ||
139 | /* Sysfs stuff */ | 138 | static int lm95241_read_chip(struct device *dev, u32 attr, int channel, |
140 | static ssize_t show_input(struct device *dev, struct device_attribute *attr, | 139 | long *val) |
141 | char *buf) | ||
142 | { | ||
143 | struct lm95241_data *data = lm95241_update_device(dev); | ||
144 | int index = to_sensor_dev_attr(attr)->index; | ||
145 | |||
146 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", | ||
147 | index == 0 || (data->config & (1 << (index / 2))) ? | ||
148 | temp_from_reg_signed(data->temp[index], data->temp[index + 1]) : | ||
149 | temp_from_reg_unsigned(data->temp[index], | ||
150 | data->temp[index + 1])); | ||
151 | } | ||
152 | |||
153 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, | ||
154 | char *buf) | ||
155 | { | 140 | { |
156 | struct lm95241_data *data = dev_get_drvdata(dev); | 141 | struct lm95241_data *data = dev_get_drvdata(dev); |
157 | 142 | ||
158 | return snprintf(buf, PAGE_SIZE - 1, | 143 | switch (attr) { |
159 | data->model & to_sensor_dev_attr(attr)->index ? "1\n" : "2\n"); | 144 | case hwmon_chip_update_interval: |
145 | *val = data->interval; | ||
146 | return 0; | ||
147 | default: | ||
148 | return -EOPNOTSUPP; | ||
149 | } | ||
160 | } | 150 | } |
161 | 151 | ||
162 | static ssize_t set_type(struct device *dev, struct device_attribute *attr, | 152 | static int lm95241_read_temp(struct device *dev, u32 attr, int channel, |
163 | const char *buf, size_t count) | 153 | long *val) |
164 | { | 154 | { |
165 | struct lm95241_data *data = dev_get_drvdata(dev); | 155 | struct lm95241_data *data = lm95241_update_device(dev); |
166 | struct i2c_client *client = data->client; | ||
167 | unsigned long val; | ||
168 | int shift; | ||
169 | u8 mask = to_sensor_dev_attr(attr)->index; | ||
170 | |||
171 | if (kstrtoul(buf, 10, &val) < 0) | ||
172 | return -EINVAL; | ||
173 | if (val != 1 && val != 2) | ||
174 | return -EINVAL; | ||
175 | |||
176 | shift = mask == R1MS_MASK ? TT1_SHIFT : TT2_SHIFT; | ||
177 | |||
178 | mutex_lock(&data->update_lock); | ||
179 | 156 | ||
180 | data->trutherm &= ~(TT_MASK << shift); | 157 | switch (attr) { |
181 | if (val == 1) { | 158 | case hwmon_temp_input: |
182 | data->model |= mask; | 159 | if (!channel || (data->config & BIT(channel - 1))) |
183 | data->trutherm |= (TT_ON << shift); | 160 | *val = temp_from_reg_signed(data->temp[channel * 2], |
184 | } else { | 161 | data->temp[channel * 2 + 1]); |
185 | data->model &= ~mask; | 162 | else |
186 | data->trutherm |= (TT_OFF << shift); | 163 | *val = temp_from_reg_unsigned(data->temp[channel * 2], |
164 | data->temp[channel * 2 + 1]); | ||
165 | return 0; | ||
166 | case hwmon_temp_min: | ||
167 | if (channel == 1) | ||
168 | *val = (data->config & R1DF_MASK) ? -128000 : 0; | ||
169 | else | ||
170 | *val = (data->config & R2DF_MASK) ? -128000 : 0; | ||
171 | return 0; | ||
172 | case hwmon_temp_max: | ||
173 | if (channel == 1) | ||
174 | *val = (data->config & R1DF_MASK) ? 127875 : 255875; | ||
175 | else | ||
176 | *val = (data->config & R2DF_MASK) ? 127875 : 255875; | ||
177 | return 0; | ||
178 | case hwmon_temp_type: | ||
179 | if (channel == 1) | ||
180 | *val = (data->model & R1MS_MASK) ? 1 : 2; | ||
181 | else | ||
182 | *val = (data->model & R2MS_MASK) ? 1 : 2; | ||
183 | return 0; | ||
184 | case hwmon_temp_fault: | ||
185 | if (channel == 1) | ||
186 | *val = !!(data->status & R1DM); | ||
187 | else | ||
188 | *val = !!(data->status & R2DM); | ||
189 | return 0; | ||
190 | default: | ||
191 | return -EOPNOTSUPP; | ||
187 | } | 192 | } |
188 | data->valid = 0; | ||
189 | |||
190 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, | ||
191 | data->model); | ||
192 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, | ||
193 | data->trutherm); | ||
194 | |||
195 | mutex_unlock(&data->update_lock); | ||
196 | |||
197 | return count; | ||
198 | } | 193 | } |
199 | 194 | ||
200 | static ssize_t show_min(struct device *dev, struct device_attribute *attr, | 195 | static int lm95241_read(struct device *dev, enum hwmon_sensor_types type, |
201 | char *buf) | 196 | u32 attr, int channel, long *val) |
202 | { | 197 | { |
203 | struct lm95241_data *data = dev_get_drvdata(dev); | 198 | switch (type) { |
204 | 199 | case hwmon_chip: | |
205 | return snprintf(buf, PAGE_SIZE - 1, | 200 | return lm95241_read_chip(dev, attr, channel, val); |
206 | data->config & to_sensor_dev_attr(attr)->index ? | 201 | case hwmon_temp: |
207 | "-127000\n" : "0\n"); | 202 | return lm95241_read_temp(dev, attr, channel, val); |
203 | default: | ||
204 | return -EOPNOTSUPP; | ||
205 | } | ||
208 | } | 206 | } |
209 | 207 | ||
210 | static ssize_t set_min(struct device *dev, struct device_attribute *attr, | 208 | static int lm95241_write_chip(struct device *dev, u32 attr, int channel, |
211 | const char *buf, size_t count) | 209 | long val) |
212 | { | 210 | { |
213 | struct lm95241_data *data = dev_get_drvdata(dev); | 211 | struct lm95241_data *data = dev_get_drvdata(dev); |
214 | long val; | 212 | int convrate; |
215 | 213 | u8 config; | |
216 | if (kstrtol(buf, 10, &val) < 0) | 214 | int ret; |
217 | return -EINVAL; | ||
218 | if (val < -128000) | ||
219 | return -EINVAL; | ||
220 | 215 | ||
221 | mutex_lock(&data->update_lock); | 216 | mutex_lock(&data->update_lock); |
222 | 217 | ||
223 | if (val < 0) | 218 | switch (attr) { |
224 | data->config |= to_sensor_dev_attr(attr)->index; | 219 | case hwmon_chip_update_interval: |
225 | else | 220 | config = data->config & ~CFG_CRMASK; |
226 | data->config &= ~to_sensor_dev_attr(attr)->index; | 221 | if (val < 130) { |
227 | data->valid = 0; | 222 | convrate = 76; |
228 | 223 | config |= CFG_CR0076; | |
229 | i2c_smbus_write_byte_data(data->client, LM95241_REG_RW_CONFIG, | 224 | } else if (val < 590) { |
230 | data->config); | 225 | convrate = 182; |
231 | 226 | config |= CFG_CR0182; | |
227 | } else if (val < 1850) { | ||
228 | convrate = 1000; | ||
229 | config |= CFG_CR1000; | ||
230 | } else { | ||
231 | convrate = 2700; | ||
232 | config |= CFG_CR2700; | ||
233 | } | ||
234 | data->interval = convrate; | ||
235 | data->config = config; | ||
236 | ret = i2c_smbus_write_byte_data(data->client, | ||
237 | LM95241_REG_RW_CONFIG, config); | ||
238 | break; | ||
239 | default: | ||
240 | ret = -EOPNOTSUPP; | ||
241 | break; | ||
242 | } | ||
232 | mutex_unlock(&data->update_lock); | 243 | mutex_unlock(&data->update_lock); |
233 | 244 | return ret; | |
234 | return count; | ||
235 | } | 245 | } |
236 | 246 | ||
237 | static ssize_t show_max(struct device *dev, struct device_attribute *attr, | 247 | static int lm95241_write_temp(struct device *dev, u32 attr, int channel, |
238 | char *buf) | 248 | long val) |
239 | { | 249 | { |
240 | struct lm95241_data *data = dev_get_drvdata(dev); | 250 | struct lm95241_data *data = dev_get_drvdata(dev); |
241 | 251 | struct i2c_client *client = data->client; | |
242 | return snprintf(buf, PAGE_SIZE - 1, | 252 | int ret; |
243 | data->config & to_sensor_dev_attr(attr)->index ? | ||
244 | "127000\n" : "255000\n"); | ||
245 | } | ||
246 | |||
247 | static ssize_t set_max(struct device *dev, struct device_attribute *attr, | ||
248 | const char *buf, size_t count) | ||
249 | { | ||
250 | struct lm95241_data *data = dev_get_drvdata(dev); | ||
251 | long val; | ||
252 | |||
253 | if (kstrtol(buf, 10, &val) < 0) | ||
254 | return -EINVAL; | ||
255 | if (val >= 256000) | ||
256 | return -EINVAL; | ||
257 | 253 | ||
258 | mutex_lock(&data->update_lock); | 254 | mutex_lock(&data->update_lock); |
259 | 255 | ||
260 | if (val <= 127000) | 256 | switch (attr) { |
261 | data->config |= to_sensor_dev_attr(attr)->index; | 257 | case hwmon_temp_min: |
262 | else | 258 | if (channel == 1) { |
263 | data->config &= ~to_sensor_dev_attr(attr)->index; | 259 | if (val < 0) |
264 | data->valid = 0; | 260 | data->config |= R1DF_MASK; |
265 | 261 | else | |
266 | i2c_smbus_write_byte_data(data->client, LM95241_REG_RW_CONFIG, | 262 | data->config &= ~R1DF_MASK; |
267 | data->config); | 263 | } else { |
264 | if (val < 0) | ||
265 | data->config |= R2DF_MASK; | ||
266 | else | ||
267 | data->config &= ~R2DF_MASK; | ||
268 | } | ||
269 | data->valid = 0; | ||
270 | ret = i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, | ||
271 | data->config); | ||
272 | break; | ||
273 | case hwmon_temp_max: | ||
274 | if (channel == 1) { | ||
275 | if (val <= 127875) | ||
276 | data->config |= R1DF_MASK; | ||
277 | else | ||
278 | data->config &= ~R1DF_MASK; | ||
279 | } else { | ||
280 | if (val <= 127875) | ||
281 | data->config |= R2DF_MASK; | ||
282 | else | ||
283 | data->config &= ~R2DF_MASK; | ||
284 | } | ||
285 | data->valid = 0; | ||
286 | ret = i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, | ||
287 | data->config); | ||
288 | break; | ||
289 | case hwmon_temp_type: | ||
290 | if (val != 1 && val != 2) { | ||
291 | ret = -EINVAL; | ||
292 | break; | ||
293 | } | ||
294 | if (channel == 1) { | ||
295 | data->trutherm &= ~(TT_MASK << TT1_SHIFT); | ||
296 | if (val == 1) { | ||
297 | data->model |= R1MS_MASK; | ||
298 | data->trutherm |= (TT_ON << TT1_SHIFT); | ||
299 | } else { | ||
300 | data->model &= ~R1MS_MASK; | ||
301 | data->trutherm |= (TT_OFF << TT1_SHIFT); | ||
302 | } | ||
303 | } else { | ||
304 | data->trutherm &= ~(TT_MASK << TT2_SHIFT); | ||
305 | if (val == 1) { | ||
306 | data->model |= R2MS_MASK; | ||
307 | data->trutherm |= (TT_ON << TT2_SHIFT); | ||
308 | } else { | ||
309 | data->model &= ~R2MS_MASK; | ||
310 | data->trutherm |= (TT_OFF << TT2_SHIFT); | ||
311 | } | ||
312 | } | ||
313 | ret = i2c_smbus_write_byte_data(client, | ||
314 | LM95241_REG_RW_REMOTE_MODEL, | ||
315 | data->model); | ||
316 | if (ret < 0) | ||
317 | break; | ||
318 | ret = i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, | ||
319 | data->trutherm); | ||
320 | break; | ||
321 | default: | ||
322 | ret = -EOPNOTSUPP; | ||
323 | break; | ||
324 | } | ||
268 | 325 | ||
269 | mutex_unlock(&data->update_lock); | 326 | mutex_unlock(&data->update_lock); |
270 | 327 | ||
271 | return count; | 328 | return ret; |
272 | } | 329 | } |
273 | 330 | ||
274 | static ssize_t show_interval(struct device *dev, struct device_attribute *attr, | 331 | static int lm95241_write(struct device *dev, enum hwmon_sensor_types type, |
275 | char *buf) | 332 | u32 attr, int channel, long val) |
276 | { | 333 | { |
277 | struct lm95241_data *data = lm95241_update_device(dev); | 334 | switch (type) { |
278 | 335 | case hwmon_chip: | |
279 | return snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval | 336 | return lm95241_write_chip(dev, attr, channel, val); |
280 | / HZ); | 337 | case hwmon_temp: |
338 | return lm95241_write_temp(dev, attr, channel, val); | ||
339 | default: | ||
340 | return -EOPNOTSUPP; | ||
341 | } | ||
281 | } | 342 | } |
282 | 343 | ||
283 | static ssize_t set_interval(struct device *dev, struct device_attribute *attr, | 344 | static umode_t lm95241_is_visible(const void *data, |
284 | const char *buf, size_t count) | 345 | enum hwmon_sensor_types type, |
346 | u32 attr, int channel) | ||
285 | { | 347 | { |
286 | struct lm95241_data *data = dev_get_drvdata(dev); | 348 | switch (type) { |
287 | unsigned long val; | 349 | case hwmon_chip: |
288 | 350 | switch (attr) { | |
289 | if (kstrtoul(buf, 10, &val) < 0) | 351 | case hwmon_chip_update_interval: |
290 | return -EINVAL; | 352 | return S_IRUGO | S_IWUSR; |
291 | 353 | } | |
292 | data->interval = val * HZ / 1000; | 354 | break; |
293 | 355 | case hwmon_temp: | |
294 | return count; | 356 | switch (attr) { |
357 | case hwmon_temp_input: | ||
358 | return S_IRUGO; | ||
359 | case hwmon_temp_fault: | ||
360 | return S_IRUGO; | ||
361 | case hwmon_temp_min: | ||
362 | case hwmon_temp_max: | ||
363 | case hwmon_temp_type: | ||
364 | return S_IRUGO | S_IWUSR; | ||
365 | } | ||
366 | break; | ||
367 | default: | ||
368 | break; | ||
369 | } | ||
370 | return 0; | ||
295 | } | 371 | } |
296 | 372 | ||
297 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0); | ||
298 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2); | ||
299 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 4); | ||
300 | static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type, | ||
301 | R1MS_MASK); | ||
302 | static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type, | ||
303 | R2MS_MASK); | ||
304 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min, | ||
305 | R1DF_MASK); | ||
306 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min, | ||
307 | R2DF_MASK); | ||
308 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max, | ||
309 | R1DF_MASK); | ||
310 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max, | ||
311 | R2DF_MASK); | ||
312 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, | ||
313 | set_interval); | ||
314 | |||
315 | static struct attribute *lm95241_attrs[] = { | ||
316 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
317 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
318 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
319 | &sensor_dev_attr_temp2_type.dev_attr.attr, | ||
320 | &sensor_dev_attr_temp3_type.dev_attr.attr, | ||
321 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
322 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
323 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
324 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
325 | &dev_attr_update_interval.attr, | ||
326 | NULL | ||
327 | }; | ||
328 | ATTRIBUTE_GROUPS(lm95241); | ||
329 | |||
330 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 373 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
331 | static int lm95241_detect(struct i2c_client *new_client, | 374 | static int lm95241_detect(struct i2c_client *new_client, |
332 | struct i2c_board_info *info) | 375 | struct i2c_board_info *info) |
@@ -362,8 +405,8 @@ static int lm95241_detect(struct i2c_client *new_client, | |||
362 | static void lm95241_init_client(struct i2c_client *client, | 405 | static void lm95241_init_client(struct i2c_client *client, |
363 | struct lm95241_data *data) | 406 | struct lm95241_data *data) |
364 | { | 407 | { |
365 | data->interval = HZ; /* 1 sec default */ | 408 | data->interval = 1000; |
366 | data->config = CFG_CR0076; | 409 | data->config = CFG_CR1000; |
367 | data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); | 410 | data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); |
368 | 411 | ||
369 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); | 412 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); |
@@ -375,6 +418,47 @@ static void lm95241_init_client(struct i2c_client *client, | |||
375 | data->model); | 418 | data->model); |
376 | } | 419 | } |
377 | 420 | ||
421 | static const u32 lm95241_chip_config[] = { | ||
422 | HWMON_C_UPDATE_INTERVAL, | ||
423 | 0 | ||
424 | }; | ||
425 | |||
426 | static const struct hwmon_channel_info lm95241_chip = { | ||
427 | .type = hwmon_chip, | ||
428 | .config = lm95241_chip_config, | ||
429 | }; | ||
430 | |||
431 | static const u32 lm95241_temp_config[] = { | ||
432 | HWMON_T_INPUT, | ||
433 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN | HWMON_T_TYPE | | ||
434 | HWMON_T_FAULT, | ||
435 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN | HWMON_T_TYPE | | ||
436 | HWMON_T_FAULT, | ||
437 | 0 | ||
438 | }; | ||
439 | |||
440 | static const struct hwmon_channel_info lm95241_temp = { | ||
441 | .type = hwmon_temp, | ||
442 | .config = lm95241_temp_config, | ||
443 | }; | ||
444 | |||
445 | static const struct hwmon_channel_info *lm95241_info[] = { | ||
446 | &lm95241_chip, | ||
447 | &lm95241_temp, | ||
448 | NULL | ||
449 | }; | ||
450 | |||
451 | static const struct hwmon_ops lm95241_hwmon_ops = { | ||
452 | .is_visible = lm95241_is_visible, | ||
453 | .read = lm95241_read, | ||
454 | .write = lm95241_write, | ||
455 | }; | ||
456 | |||
457 | static const struct hwmon_chip_info lm95241_chip_info = { | ||
458 | .ops = &lm95241_hwmon_ops, | ||
459 | .info = lm95241_info, | ||
460 | }; | ||
461 | |||
378 | static int lm95241_probe(struct i2c_client *client, | 462 | static int lm95241_probe(struct i2c_client *client, |
379 | const struct i2c_device_id *id) | 463 | const struct i2c_device_id *id) |
380 | { | 464 | { |
@@ -392,9 +476,10 @@ static int lm95241_probe(struct i2c_client *client, | |||
392 | /* Initialize the LM95241 chip */ | 476 | /* Initialize the LM95241 chip */ |
393 | lm95241_init_client(client, data); | 477 | lm95241_init_client(client, data); |
394 | 478 | ||
395 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 479 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
396 | data, | 480 | data, |
397 | lm95241_groups); | 481 | &lm95241_chip_info, |
482 | NULL); | ||
398 | return PTR_ERR_OR_ZERO(hwmon_dev); | 483 | return PTR_ERR_OR_ZERO(hwmon_dev); |
399 | } | 484 | } |
400 | 485 | ||
@@ -420,5 +505,5 @@ static struct i2c_driver lm95241_driver = { | |||
420 | module_i2c_driver(lm95241_driver); | 505 | module_i2c_driver(lm95241_driver); |
421 | 506 | ||
422 | MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>"); | 507 | MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>"); |
423 | MODULE_DESCRIPTION("LM95241 sensor driver"); | 508 | MODULE_DESCRIPTION("LM95231/LM95241 sensor driver"); |
424 | MODULE_LICENSE("GPL"); | 509 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/lm95245.c b/drivers/hwmon/lm95245.c index e7aef4561c83..a3bfd88752ca 100644 --- a/drivers/hwmon/lm95245.c +++ b/drivers/hwmon/lm95245.c | |||
@@ -15,22 +15,16 @@ | |||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | 18 | */ |
23 | 19 | ||
24 | #include <linux/module.h> | 20 | #include <linux/err.h> |
25 | #include <linux/init.h> | 21 | #include <linux/init.h> |
26 | #include <linux/slab.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/hwmon.h> | 22 | #include <linux/hwmon.h> |
30 | #include <linux/hwmon-sysfs.h> | 23 | #include <linux/i2c.h> |
31 | #include <linux/err.h> | 24 | #include <linux/module.h> |
32 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
33 | #include <linux/sysfs.h> | 26 | #include <linux/regmap.h> |
27 | #include <linux/slab.h> | ||
34 | 28 | ||
35 | static const unsigned short normal_i2c[] = { | 29 | static const unsigned short normal_i2c[] = { |
36 | 0x18, 0x19, 0x29, 0x4c, 0x4d, I2C_CLIENT_END }; | 30 | 0x18, 0x19, 0x29, 0x4c, 0x4d, I2C_CLIENT_END }; |
@@ -89,6 +83,7 @@ static const unsigned short normal_i2c[] = { | |||
89 | #define RATE_CR1000 0x02 | 83 | #define RATE_CR1000 0x02 |
90 | #define RATE_CR2500 0x03 | 84 | #define RATE_CR2500 0x03 |
91 | 85 | ||
86 | #define STATUS1_ROS 0x10 | ||
92 | #define STATUS1_DIODE_FAULT 0x04 | 87 | #define STATUS1_DIODE_FAULT 0x04 |
93 | #define STATUS1_RTCRIT 0x02 | 88 | #define STATUS1_RTCRIT 0x02 |
94 | #define STATUS1_LOC 0x01 | 89 | #define STATUS1_LOC 0x01 |
@@ -112,14 +107,9 @@ static const u8 lm95245_reg_address[] = { | |||
112 | 107 | ||
113 | /* Client data (each client gets its own) */ | 108 | /* Client data (each client gets its own) */ |
114 | struct lm95245_data { | 109 | struct lm95245_data { |
115 | struct i2c_client *client; | 110 | struct regmap *regmap; |
116 | struct mutex update_lock; | 111 | struct mutex update_lock; |
117 | unsigned long last_updated; /* in jiffies */ | 112 | int interval; /* in msecs */ |
118 | unsigned long interval; /* in msecs */ | ||
119 | bool valid; /* zero until following fields are valid */ | ||
120 | /* registers values */ | ||
121 | u8 regs[ARRAY_SIZE(lm95245_reg_address)]; | ||
122 | u8 config1, config2; | ||
123 | }; | 113 | }; |
124 | 114 | ||
125 | /* Conversions */ | 115 | /* Conversions */ |
@@ -135,60 +125,36 @@ static int temp_from_reg_signed(u8 val_h, u8 val_l) | |||
135 | return temp_from_reg_unsigned(val_h, val_l); | 125 | return temp_from_reg_unsigned(val_h, val_l); |
136 | } | 126 | } |
137 | 127 | ||
138 | static struct lm95245_data *lm95245_update_device(struct device *dev) | 128 | static int lm95245_read_conversion_rate(struct lm95245_data *data) |
139 | { | 129 | { |
140 | struct lm95245_data *data = dev_get_drvdata(dev); | 130 | unsigned int rate; |
141 | struct i2c_client *client = data->client; | 131 | int ret; |
142 | 132 | ||
143 | mutex_lock(&data->update_lock); | 133 | ret = regmap_read(data->regmap, LM95245_REG_RW_CONVERS_RATE, &rate); |
144 | 134 | if (ret < 0) | |
145 | if (time_after(jiffies, data->last_updated | 135 | return ret; |
146 | + msecs_to_jiffies(data->interval)) || !data->valid) { | ||
147 | int i; | ||
148 | |||
149 | for (i = 0; i < ARRAY_SIZE(lm95245_reg_address); i++) | ||
150 | data->regs[i] | ||
151 | = i2c_smbus_read_byte_data(client, | ||
152 | lm95245_reg_address[i]); | ||
153 | data->last_updated = jiffies; | ||
154 | data->valid = 1; | ||
155 | } | ||
156 | |||
157 | mutex_unlock(&data->update_lock); | ||
158 | |||
159 | return data; | ||
160 | } | ||
161 | |||
162 | static unsigned long lm95245_read_conversion_rate(struct i2c_client *client) | ||
163 | { | ||
164 | int rate; | ||
165 | unsigned long interval; | ||
166 | |||
167 | rate = i2c_smbus_read_byte_data(client, LM95245_REG_RW_CONVERS_RATE); | ||
168 | 136 | ||
169 | switch (rate) { | 137 | switch (rate) { |
170 | case RATE_CR0063: | 138 | case RATE_CR0063: |
171 | interval = 63; | 139 | data->interval = 63; |
172 | break; | 140 | break; |
173 | case RATE_CR0364: | 141 | case RATE_CR0364: |
174 | interval = 364; | 142 | data->interval = 364; |
175 | break; | 143 | break; |
176 | case RATE_CR1000: | 144 | case RATE_CR1000: |
177 | interval = 1000; | 145 | data->interval = 1000; |
178 | break; | 146 | break; |
179 | case RATE_CR2500: | 147 | case RATE_CR2500: |
180 | default: | 148 | default: |
181 | interval = 2500; | 149 | data->interval = 2500; |
182 | break; | 150 | break; |
183 | } | 151 | } |
184 | 152 | return 0; | |
185 | return interval; | ||
186 | } | 153 | } |
187 | 154 | ||
188 | static unsigned long lm95245_set_conversion_rate(struct i2c_client *client, | 155 | static int lm95245_set_conversion_rate(struct lm95245_data *data, long interval) |
189 | unsigned long interval) | ||
190 | { | 156 | { |
191 | int rate; | 157 | int ret, rate; |
192 | 158 | ||
193 | if (interval <= 63) { | 159 | if (interval <= 63) { |
194 | interval = 63; | 160 | interval = 63; |
@@ -204,221 +170,289 @@ static unsigned long lm95245_set_conversion_rate(struct i2c_client *client, | |||
204 | rate = RATE_CR2500; | 170 | rate = RATE_CR2500; |
205 | } | 171 | } |
206 | 172 | ||
207 | i2c_smbus_write_byte_data(client, LM95245_REG_RW_CONVERS_RATE, rate); | 173 | ret = regmap_write(data->regmap, LM95245_REG_RW_CONVERS_RATE, rate); |
174 | if (ret < 0) | ||
175 | return ret; | ||
208 | 176 | ||
209 | return interval; | 177 | data->interval = interval; |
210 | } | 178 | return 0; |
211 | |||
212 | /* Sysfs stuff */ | ||
213 | static ssize_t show_input(struct device *dev, struct device_attribute *attr, | ||
214 | char *buf) | ||
215 | { | ||
216 | struct lm95245_data *data = lm95245_update_device(dev); | ||
217 | int temp; | ||
218 | int index = to_sensor_dev_attr(attr)->index; | ||
219 | |||
220 | /* | ||
221 | * Index 0 (Local temp) is always signed | ||
222 | * Index 2 (Remote temp) has both signed and unsigned data | ||
223 | * use signed calculation for remote if signed bit is set | ||
224 | */ | ||
225 | if (index == 0 || data->regs[index] & 0x80) | ||
226 | temp = temp_from_reg_signed(data->regs[index], | ||
227 | data->regs[index + 1]); | ||
228 | else | ||
229 | temp = temp_from_reg_unsigned(data->regs[index + 2], | ||
230 | data->regs[index + 3]); | ||
231 | |||
232 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", temp); | ||
233 | } | ||
234 | |||
235 | static ssize_t show_limit(struct device *dev, struct device_attribute *attr, | ||
236 | char *buf) | ||
237 | { | ||
238 | struct lm95245_data *data = lm95245_update_device(dev); | ||
239 | int index = to_sensor_dev_attr(attr)->index; | ||
240 | |||
241 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", | ||
242 | data->regs[index] * 1000); | ||
243 | } | 179 | } |
244 | 180 | ||
245 | static ssize_t set_limit(struct device *dev, struct device_attribute *attr, | 181 | static int lm95245_read_temp(struct device *dev, u32 attr, int channel, |
246 | const char *buf, size_t count) | 182 | long *val) |
247 | { | 183 | { |
248 | struct lm95245_data *data = dev_get_drvdata(dev); | 184 | struct lm95245_data *data = dev_get_drvdata(dev); |
249 | int index = to_sensor_dev_attr(attr)->index; | 185 | struct regmap *regmap = data->regmap; |
250 | struct i2c_client *client = data->client; | 186 | int ret, regl, regh, regvall, regvalh; |
251 | unsigned long val; | 187 | |
252 | 188 | switch (attr) { | |
253 | if (kstrtoul(buf, 10, &val) < 0) | 189 | case hwmon_temp_input: |
254 | return -EINVAL; | 190 | regl = channel ? LM95245_REG_R_REMOTE_TEMPL_S : |
255 | 191 | LM95245_REG_R_LOCAL_TEMPL_S; | |
256 | val /= 1000; | 192 | regh = channel ? LM95245_REG_R_REMOTE_TEMPH_S : |
257 | 193 | LM95245_REG_R_LOCAL_TEMPH_S; | |
258 | val = clamp_val(val, 0, (index == 6 ? 127 : 255)); | 194 | ret = regmap_read(regmap, regl, ®vall); |
259 | 195 | if (ret < 0) | |
260 | mutex_lock(&data->update_lock); | 196 | return ret; |
261 | 197 | ret = regmap_read(regmap, regh, ®valh); | |
262 | data->valid = 0; | 198 | if (ret < 0) |
263 | 199 | return ret; | |
264 | i2c_smbus_write_byte_data(client, lm95245_reg_address[index], val); | 200 | /* |
265 | 201 | * Local temp is always signed. | |
266 | mutex_unlock(&data->update_lock); | 202 | * Remote temp has both signed and unsigned data. |
267 | 203 | * Use signed calculation for remote if signed bit is set | |
268 | return count; | 204 | * or if reported temperature is below signed limit. |
205 | */ | ||
206 | if (!channel || (regvalh & 0x80) || regvalh < 0x7f) { | ||
207 | *val = temp_from_reg_signed(regvalh, regvall); | ||
208 | return 0; | ||
209 | } | ||
210 | ret = regmap_read(regmap, LM95245_REG_R_REMOTE_TEMPL_U, | ||
211 | ®vall); | ||
212 | if (ret < 0) | ||
213 | return ret; | ||
214 | ret = regmap_read(regmap, LM95245_REG_R_REMOTE_TEMPH_U, | ||
215 | ®valh); | ||
216 | if (ret < 0) | ||
217 | return ret; | ||
218 | *val = temp_from_reg_unsigned(regvalh, regvall); | ||
219 | return 0; | ||
220 | case hwmon_temp_max: | ||
221 | ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT, | ||
222 | ®valh); | ||
223 | if (ret < 0) | ||
224 | return ret; | ||
225 | *val = regvalh * 1000; | ||
226 | return 0; | ||
227 | case hwmon_temp_crit: | ||
228 | regh = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT : | ||
229 | LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT; | ||
230 | ret = regmap_read(regmap, regh, ®valh); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | *val = regvalh * 1000; | ||
234 | return 0; | ||
235 | case hwmon_temp_max_hyst: | ||
236 | ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT, | ||
237 | ®valh); | ||
238 | if (ret < 0) | ||
239 | return ret; | ||
240 | ret = regmap_read(regmap, LM95245_REG_RW_COMMON_HYSTERESIS, | ||
241 | ®vall); | ||
242 | if (ret < 0) | ||
243 | return ret; | ||
244 | *val = (regvalh - regvall) * 1000; | ||
245 | return 0; | ||
246 | case hwmon_temp_crit_hyst: | ||
247 | regh = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT : | ||
248 | LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT; | ||
249 | ret = regmap_read(regmap, regh, ®valh); | ||
250 | if (ret < 0) | ||
251 | return ret; | ||
252 | ret = regmap_read(regmap, LM95245_REG_RW_COMMON_HYSTERESIS, | ||
253 | ®vall); | ||
254 | if (ret < 0) | ||
255 | return ret; | ||
256 | *val = (regvalh - regvall) * 1000; | ||
257 | return 0; | ||
258 | case hwmon_temp_type: | ||
259 | ret = regmap_read(regmap, LM95245_REG_RW_CONFIG2, ®valh); | ||
260 | if (ret < 0) | ||
261 | return ret; | ||
262 | *val = (regvalh & CFG2_REMOTE_TT) ? 1 : 2; | ||
263 | return 0; | ||
264 | case hwmon_temp_offset: | ||
265 | ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OFFL, | ||
266 | ®vall); | ||
267 | if (ret < 0) | ||
268 | return ret; | ||
269 | ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OFFH, | ||
270 | ®valh); | ||
271 | if (ret < 0) | ||
272 | return ret; | ||
273 | *val = temp_from_reg_signed(regvalh, regvall); | ||
274 | return 0; | ||
275 | case hwmon_temp_max_alarm: | ||
276 | ret = regmap_read(regmap, LM95245_REG_R_STATUS1, ®valh); | ||
277 | if (ret < 0) | ||
278 | return ret; | ||
279 | *val = !!(regvalh & STATUS1_ROS); | ||
280 | return 0; | ||
281 | case hwmon_temp_crit_alarm: | ||
282 | ret = regmap_read(regmap, LM95245_REG_R_STATUS1, ®valh); | ||
283 | if (ret < 0) | ||
284 | return ret; | ||
285 | *val = !!(regvalh & (channel ? STATUS1_RTCRIT : STATUS1_LOC)); | ||
286 | return 0; | ||
287 | case hwmon_temp_fault: | ||
288 | ret = regmap_read(regmap, LM95245_REG_R_STATUS1, ®valh); | ||
289 | if (ret < 0) | ||
290 | return ret; | ||
291 | *val = !!(regvalh & STATUS1_DIODE_FAULT); | ||
292 | return 0; | ||
293 | default: | ||
294 | return -EOPNOTSUPP; | ||
295 | } | ||
269 | } | 296 | } |
270 | 297 | ||
271 | static ssize_t show_crit_hyst(struct device *dev, struct device_attribute *attr, | 298 | static int lm95245_write_temp(struct device *dev, u32 attr, int channel, |
272 | char *buf) | 299 | long val) |
273 | { | 300 | { |
274 | struct lm95245_data *data = lm95245_update_device(dev); | 301 | struct lm95245_data *data = dev_get_drvdata(dev); |
275 | int index = to_sensor_dev_attr(attr)->index; | 302 | struct regmap *regmap = data->regmap; |
276 | int hyst = data->regs[index] - data->regs[8]; | 303 | unsigned int regval; |
277 | 304 | int ret, reg; | |
278 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", hyst * 1000); | 305 | |
306 | switch (attr) { | ||
307 | case hwmon_temp_max: | ||
308 | val = clamp_val(val / 1000, 0, 255); | ||
309 | ret = regmap_write(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT, val); | ||
310 | return ret; | ||
311 | case hwmon_temp_crit: | ||
312 | reg = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT : | ||
313 | LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT; | ||
314 | val = clamp_val(val / 1000, 0, channel ? 255 : 127); | ||
315 | ret = regmap_write(regmap, reg, val); | ||
316 | return ret; | ||
317 | case hwmon_temp_crit_hyst: | ||
318 | mutex_lock(&data->update_lock); | ||
319 | ret = regmap_read(regmap, LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT, | ||
320 | ®val); | ||
321 | if (ret < 0) { | ||
322 | mutex_unlock(&data->update_lock); | ||
323 | return ret; | ||
324 | } | ||
325 | /* Clamp to reasonable range to prevent overflow */ | ||
326 | val = clamp_val(val, -1000000, 1000000); | ||
327 | val = regval - val / 1000; | ||
328 | val = clamp_val(val, 0, 31); | ||
329 | ret = regmap_write(regmap, LM95245_REG_RW_COMMON_HYSTERESIS, | ||
330 | val); | ||
331 | mutex_unlock(&data->update_lock); | ||
332 | return ret; | ||
333 | case hwmon_temp_offset: | ||
334 | val = clamp_val(val, -128000, 127875); | ||
335 | val = val * 256 / 1000; | ||
336 | mutex_lock(&data->update_lock); | ||
337 | ret = regmap_write(regmap, LM95245_REG_RW_REMOTE_OFFL, | ||
338 | val & 0xe0); | ||
339 | if (ret < 0) { | ||
340 | mutex_unlock(&data->update_lock); | ||
341 | return ret; | ||
342 | } | ||
343 | ret = regmap_write(regmap, LM95245_REG_RW_REMOTE_OFFH, | ||
344 | (val >> 8) & 0xff); | ||
345 | mutex_unlock(&data->update_lock); | ||
346 | return ret; | ||
347 | case hwmon_temp_type: | ||
348 | if (val != 1 && val != 2) | ||
349 | return -EINVAL; | ||
350 | ret = regmap_update_bits(regmap, LM95245_REG_RW_CONFIG2, | ||
351 | CFG2_REMOTE_TT, | ||
352 | val == 1 ? CFG2_REMOTE_TT : 0); | ||
353 | return ret; | ||
354 | default: | ||
355 | return -EOPNOTSUPP; | ||
356 | } | ||
279 | } | 357 | } |
280 | 358 | ||
281 | static ssize_t set_crit_hyst(struct device *dev, struct device_attribute *attr, | 359 | static int lm95245_read_chip(struct device *dev, u32 attr, int channel, |
282 | const char *buf, size_t count) | 360 | long *val) |
283 | { | 361 | { |
284 | struct lm95245_data *data = dev_get_drvdata(dev); | 362 | struct lm95245_data *data = dev_get_drvdata(dev); |
285 | int index = to_sensor_dev_attr(attr)->index; | ||
286 | struct i2c_client *client = data->client; | ||
287 | unsigned long val; | ||
288 | int hyst, limit; | ||
289 | |||
290 | if (kstrtoul(buf, 10, &val) < 0) | ||
291 | return -EINVAL; | ||
292 | |||
293 | mutex_lock(&data->update_lock); | ||
294 | |||
295 | limit = i2c_smbus_read_byte_data(client, lm95245_reg_address[index]); | ||
296 | hyst = limit - val / 1000; | ||
297 | hyst = clamp_val(hyst, 0, 31); | ||
298 | data->regs[8] = hyst; | ||
299 | 363 | ||
300 | /* shared crit hysteresis */ | 364 | switch (attr) { |
301 | i2c_smbus_write_byte_data(client, LM95245_REG_RW_COMMON_HYSTERESIS, | 365 | case hwmon_chip_update_interval: |
302 | hyst); | 366 | *val = data->interval; |
303 | 367 | return 0; | |
304 | mutex_unlock(&data->update_lock); | 368 | default: |
305 | 369 | return -EOPNOTSUPP; | |
306 | return count; | 370 | } |
307 | } | 371 | } |
308 | 372 | ||
309 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, | 373 | static int lm95245_write_chip(struct device *dev, u32 attr, int channel, |
310 | char *buf) | 374 | long val) |
311 | { | 375 | { |
312 | struct lm95245_data *data = dev_get_drvdata(dev); | 376 | struct lm95245_data *data = dev_get_drvdata(dev); |
313 | 377 | int ret; | |
314 | return snprintf(buf, PAGE_SIZE - 1, | 378 | |
315 | data->config2 & CFG2_REMOTE_TT ? "1\n" : "2\n"); | 379 | switch (attr) { |
380 | case hwmon_chip_update_interval: | ||
381 | mutex_lock(&data->update_lock); | ||
382 | ret = lm95245_set_conversion_rate(data, val); | ||
383 | mutex_unlock(&data->update_lock); | ||
384 | return ret; | ||
385 | default: | ||
386 | return -EOPNOTSUPP; | ||
387 | } | ||
316 | } | 388 | } |
317 | 389 | ||
318 | static ssize_t set_type(struct device *dev, struct device_attribute *attr, | 390 | static int lm95245_read(struct device *dev, enum hwmon_sensor_types type, |
319 | const char *buf, size_t count) | 391 | u32 attr, int channel, long *val) |
320 | { | 392 | { |
321 | struct lm95245_data *data = dev_get_drvdata(dev); | 393 | switch (type) { |
322 | struct i2c_client *client = data->client; | 394 | case hwmon_chip: |
323 | unsigned long val; | 395 | return lm95245_read_chip(dev, attr, channel, val); |
324 | 396 | case hwmon_temp: | |
325 | if (kstrtoul(buf, 10, &val) < 0) | 397 | return lm95245_read_temp(dev, attr, channel, val); |
326 | return -EINVAL; | 398 | default: |
327 | if (val != 1 && val != 2) | 399 | return -EOPNOTSUPP; |
328 | return -EINVAL; | 400 | } |
329 | |||
330 | mutex_lock(&data->update_lock); | ||
331 | |||
332 | if (val == 1) | ||
333 | data->config2 |= CFG2_REMOTE_TT; | ||
334 | else | ||
335 | data->config2 &= ~CFG2_REMOTE_TT; | ||
336 | |||
337 | data->valid = 0; | ||
338 | |||
339 | i2c_smbus_write_byte_data(client, LM95245_REG_RW_CONFIG2, | ||
340 | data->config2); | ||
341 | |||
342 | mutex_unlock(&data->update_lock); | ||
343 | |||
344 | return count; | ||
345 | } | 401 | } |
346 | 402 | ||
347 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | 403 | static int lm95245_write(struct device *dev, enum hwmon_sensor_types type, |
348 | char *buf) | 404 | u32 attr, int channel, long val) |
349 | { | 405 | { |
350 | struct lm95245_data *data = lm95245_update_device(dev); | 406 | switch (type) { |
351 | int index = to_sensor_dev_attr(attr)->index; | 407 | case hwmon_chip: |
352 | 408 | return lm95245_write_chip(dev, attr, channel, val); | |
353 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", | 409 | case hwmon_temp: |
354 | !!(data->regs[9] & index)); | 410 | return lm95245_write_temp(dev, attr, channel, val); |
411 | default: | ||
412 | return -EOPNOTSUPP; | ||
413 | } | ||
355 | } | 414 | } |
356 | 415 | ||
357 | static ssize_t show_interval(struct device *dev, struct device_attribute *attr, | 416 | static umode_t lm95245_temp_is_visible(const void *data, u32 attr, int channel) |
358 | char *buf) | ||
359 | { | 417 | { |
360 | struct lm95245_data *data = lm95245_update_device(dev); | 418 | switch (attr) { |
361 | 419 | case hwmon_temp_input: | |
362 | return snprintf(buf, PAGE_SIZE - 1, "%lu\n", data->interval); | 420 | case hwmon_temp_max_alarm: |
421 | case hwmon_temp_max_hyst: | ||
422 | case hwmon_temp_crit_alarm: | ||
423 | case hwmon_temp_fault: | ||
424 | return S_IRUGO; | ||
425 | case hwmon_temp_type: | ||
426 | case hwmon_temp_max: | ||
427 | case hwmon_temp_crit: | ||
428 | case hwmon_temp_offset: | ||
429 | return S_IRUGO | S_IWUSR; | ||
430 | case hwmon_temp_crit_hyst: | ||
431 | return (channel == 0) ? S_IRUGO | S_IWUSR : S_IRUGO; | ||
432 | default: | ||
433 | return 0; | ||
434 | } | ||
363 | } | 435 | } |
364 | 436 | ||
365 | static ssize_t set_interval(struct device *dev, struct device_attribute *attr, | 437 | static umode_t lm95245_is_visible(const void *data, |
366 | const char *buf, size_t count) | 438 | enum hwmon_sensor_types type, |
439 | u32 attr, int channel) | ||
367 | { | 440 | { |
368 | struct lm95245_data *data = dev_get_drvdata(dev); | 441 | switch (type) { |
369 | struct i2c_client *client = data->client; | 442 | case hwmon_chip: |
370 | unsigned long val; | 443 | switch (attr) { |
371 | 444 | case hwmon_chip_update_interval: | |
372 | if (kstrtoul(buf, 10, &val) < 0) | 445 | return S_IRUGO | S_IWUSR; |
373 | return -EINVAL; | 446 | default: |
374 | 447 | return 0; | |
375 | mutex_lock(&data->update_lock); | 448 | } |
376 | 449 | case hwmon_temp: | |
377 | data->interval = lm95245_set_conversion_rate(client, val); | 450 | return lm95245_temp_is_visible(data, attr, channel); |
378 | 451 | default: | |
379 | mutex_unlock(&data->update_lock); | 452 | return 0; |
380 | 453 | } | |
381 | return count; | ||
382 | } | 454 | } |
383 | 455 | ||
384 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0); | ||
385 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_limit, | ||
386 | set_limit, 6); | ||
387 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_crit_hyst, | ||
388 | set_crit_hyst, 6); | ||
389 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
390 | STATUS1_LOC); | ||
391 | |||
392 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2); | ||
393 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_limit, | ||
394 | set_limit, 7); | ||
395 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_crit_hyst, NULL, 7); | ||
396 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
397 | STATUS1_RTCRIT); | ||
398 | static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, | ||
399 | set_type, 0); | ||
400 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, | ||
401 | STATUS1_DIODE_FAULT); | ||
402 | |||
403 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, | ||
404 | set_interval); | ||
405 | |||
406 | static struct attribute *lm95245_attrs[] = { | ||
407 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
408 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
409 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | ||
410 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
411 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
412 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
413 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
414 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
415 | &sensor_dev_attr_temp2_type.dev_attr.attr, | ||
416 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
417 | &dev_attr_update_interval.attr, | ||
418 | NULL | ||
419 | }; | ||
420 | ATTRIBUTE_GROUPS(lm95245); | ||
421 | |||
422 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 456 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
423 | static int lm95245_detect(struct i2c_client *new_client, | 457 | static int lm95245_detect(struct i2c_client *new_client, |
424 | struct i2c_board_info *info) | 458 | struct i2c_board_info *info) |
@@ -453,44 +487,130 @@ static int lm95245_detect(struct i2c_client *new_client, | |||
453 | return 0; | 487 | return 0; |
454 | } | 488 | } |
455 | 489 | ||
456 | static void lm95245_init_client(struct i2c_client *client, | 490 | static int lm95245_init_client(struct lm95245_data *data) |
457 | struct lm95245_data *data) | ||
458 | { | 491 | { |
459 | data->interval = lm95245_read_conversion_rate(client); | 492 | int ret; |
460 | 493 | ||
461 | data->config1 = i2c_smbus_read_byte_data(client, | 494 | ret = lm95245_read_conversion_rate(data); |
462 | LM95245_REG_RW_CONFIG1); | 495 | if (ret < 0) |
463 | data->config2 = i2c_smbus_read_byte_data(client, | 496 | return ret; |
464 | LM95245_REG_RW_CONFIG2); | 497 | |
465 | 498 | return regmap_update_bits(data->regmap, LM95245_REG_RW_CONFIG1, | |
466 | if (data->config1 & CFG_STOP) { | 499 | CFG_STOP, 0); |
467 | /* Clear the standby bit */ | 500 | } |
468 | data->config1 &= ~CFG_STOP; | 501 | |
469 | i2c_smbus_write_byte_data(client, LM95245_REG_RW_CONFIG1, | 502 | static bool lm95245_is_writeable_reg(struct device *dev, unsigned int reg) |
470 | data->config1); | 503 | { |
504 | switch (reg) { | ||
505 | case LM95245_REG_RW_CONFIG1: | ||
506 | case LM95245_REG_RW_CONVERS_RATE: | ||
507 | case LM95245_REG_W_ONE_SHOT: | ||
508 | case LM95245_REG_RW_CONFIG2: | ||
509 | case LM95245_REG_RW_REMOTE_OFFH: | ||
510 | case LM95245_REG_RW_REMOTE_OFFL: | ||
511 | case LM95245_REG_RW_REMOTE_OS_LIMIT: | ||
512 | case LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT: | ||
513 | case LM95245_REG_RW_REMOTE_TCRIT_LIMIT: | ||
514 | case LM95245_REG_RW_COMMON_HYSTERESIS: | ||
515 | return true; | ||
516 | default: | ||
517 | return false; | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static bool lm95245_is_volatile_reg(struct device *dev, unsigned int reg) | ||
522 | { | ||
523 | switch (reg) { | ||
524 | case LM95245_REG_R_STATUS1: | ||
525 | case LM95245_REG_R_STATUS2: | ||
526 | case LM95245_REG_R_LOCAL_TEMPH_S: | ||
527 | case LM95245_REG_R_LOCAL_TEMPL_S: | ||
528 | case LM95245_REG_R_REMOTE_TEMPH_S: | ||
529 | case LM95245_REG_R_REMOTE_TEMPL_S: | ||
530 | case LM95245_REG_R_REMOTE_TEMPH_U: | ||
531 | case LM95245_REG_R_REMOTE_TEMPL_U: | ||
532 | return true; | ||
533 | default: | ||
534 | return false; | ||
471 | } | 535 | } |
472 | } | 536 | } |
473 | 537 | ||
538 | static const struct regmap_config lm95245_regmap_config = { | ||
539 | .reg_bits = 8, | ||
540 | .val_bits = 8, | ||
541 | .writeable_reg = lm95245_is_writeable_reg, | ||
542 | .volatile_reg = lm95245_is_volatile_reg, | ||
543 | .cache_type = REGCACHE_RBTREE, | ||
544 | .use_single_rw = true, | ||
545 | }; | ||
546 | |||
547 | static const u32 lm95245_chip_config[] = { | ||
548 | HWMON_C_UPDATE_INTERVAL, | ||
549 | 0 | ||
550 | }; | ||
551 | |||
552 | static const struct hwmon_channel_info lm95245_chip = { | ||
553 | .type = hwmon_chip, | ||
554 | .config = lm95245_chip_config, | ||
555 | }; | ||
556 | |||
557 | static const u32 lm95245_temp_config[] = { | ||
558 | HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_CRIT_ALARM, | ||
559 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | HWMON_T_CRIT | | ||
560 | HWMON_T_CRIT_HYST | HWMON_T_FAULT | HWMON_T_MAX_ALARM | | ||
561 | HWMON_T_CRIT_ALARM | HWMON_T_TYPE | HWMON_T_OFFSET, | ||
562 | 0 | ||
563 | }; | ||
564 | |||
565 | static const struct hwmon_channel_info lm95245_temp = { | ||
566 | .type = hwmon_temp, | ||
567 | .config = lm95245_temp_config, | ||
568 | }; | ||
569 | |||
570 | static const struct hwmon_channel_info *lm95245_info[] = { | ||
571 | &lm95245_chip, | ||
572 | &lm95245_temp, | ||
573 | NULL | ||
574 | }; | ||
575 | |||
576 | static const struct hwmon_ops lm95245_hwmon_ops = { | ||
577 | .is_visible = lm95245_is_visible, | ||
578 | .read = lm95245_read, | ||
579 | .write = lm95245_write, | ||
580 | }; | ||
581 | |||
582 | static const struct hwmon_chip_info lm95245_chip_info = { | ||
583 | .ops = &lm95245_hwmon_ops, | ||
584 | .info = lm95245_info, | ||
585 | }; | ||
586 | |||
474 | static int lm95245_probe(struct i2c_client *client, | 587 | static int lm95245_probe(struct i2c_client *client, |
475 | const struct i2c_device_id *id) | 588 | const struct i2c_device_id *id) |
476 | { | 589 | { |
477 | struct device *dev = &client->dev; | 590 | struct device *dev = &client->dev; |
478 | struct lm95245_data *data; | 591 | struct lm95245_data *data; |
479 | struct device *hwmon_dev; | 592 | struct device *hwmon_dev; |
593 | int ret; | ||
480 | 594 | ||
481 | data = devm_kzalloc(dev, sizeof(struct lm95245_data), GFP_KERNEL); | 595 | data = devm_kzalloc(dev, sizeof(struct lm95245_data), GFP_KERNEL); |
482 | if (!data) | 596 | if (!data) |
483 | return -ENOMEM; | 597 | return -ENOMEM; |
484 | 598 | ||
485 | data->client = client; | 599 | data->regmap = devm_regmap_init_i2c(client, &lm95245_regmap_config); |
600 | if (IS_ERR(data->regmap)) | ||
601 | return PTR_ERR(data->regmap); | ||
602 | |||
486 | mutex_init(&data->update_lock); | 603 | mutex_init(&data->update_lock); |
487 | 604 | ||
488 | /* Initialize the LM95245 chip */ | 605 | /* Initialize the LM95245 chip */ |
489 | lm95245_init_client(client, data); | 606 | ret = lm95245_init_client(data); |
490 | 607 | if (ret < 0) | |
491 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 608 | return ret; |
492 | data, | 609 | |
493 | lm95245_groups); | 610 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
611 | data, | ||
612 | &lm95245_chip_info, | ||
613 | NULL); | ||
494 | return PTR_ERR_OR_ZERO(hwmon_dev); | 614 | return PTR_ERR_OR_ZERO(hwmon_dev); |
495 | } | 615 | } |
496 | 616 | ||
diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c index c86a18402496..8445c9fd946b 100644 --- a/drivers/hwmon/ltc4151.c +++ b/drivers/hwmon/ltc4151.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/of.h> | ||
33 | #include <linux/init.h> | 34 | #include <linux/init.h> |
34 | #include <linux/err.h> | 35 | #include <linux/err.h> |
35 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
@@ -52,6 +53,7 @@ struct ltc4151_data { | |||
52 | struct mutex update_lock; | 53 | struct mutex update_lock; |
53 | bool valid; | 54 | bool valid; |
54 | unsigned long last_updated; /* in jiffies */ | 55 | unsigned long last_updated; /* in jiffies */ |
56 | unsigned int shunt; /* in micro ohms */ | ||
55 | 57 | ||
56 | /* Registers */ | 58 | /* Registers */ |
57 | u8 regs[6]; | 59 | u8 regs[6]; |
@@ -111,9 +113,9 @@ static int ltc4151_get_value(struct ltc4151_data *data, u8 reg) | |||
111 | case LTC4151_SENSE_H: | 113 | case LTC4151_SENSE_H: |
112 | /* | 114 | /* |
113 | * 20uV resolution. Convert to current as measured with | 115 | * 20uV resolution. Convert to current as measured with |
114 | * an 1 mOhm sense resistor, in mA. | 116 | * a given sense resistor, in mA. |
115 | */ | 117 | */ |
116 | val = val * 20; | 118 | val = val * 20 * 1000 / data->shunt; |
117 | break; | 119 | break; |
118 | case LTC4151_VIN_H: | 120 | case LTC4151_VIN_H: |
119 | /* 25 mV per increment */ | 121 | /* 25 mV per increment */ |
@@ -176,6 +178,7 @@ static int ltc4151_probe(struct i2c_client *client, | |||
176 | struct device *dev = &client->dev; | 178 | struct device *dev = &client->dev; |
177 | struct ltc4151_data *data; | 179 | struct ltc4151_data *data; |
178 | struct device *hwmon_dev; | 180 | struct device *hwmon_dev; |
181 | u32 shunt; | ||
179 | 182 | ||
180 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 183 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
181 | return -ENODEV; | 184 | return -ENODEV; |
@@ -184,6 +187,15 @@ static int ltc4151_probe(struct i2c_client *client, | |||
184 | if (!data) | 187 | if (!data) |
185 | return -ENOMEM; | 188 | return -ENOMEM; |
186 | 189 | ||
190 | if (of_property_read_u32(client->dev.of_node, | ||
191 | "shunt-resistor-micro-ohms", &shunt)) | ||
192 | shunt = 1000; /* 1 mOhm if not set via DT */ | ||
193 | |||
194 | if (shunt == 0) | ||
195 | return -EINVAL; | ||
196 | |||
197 | data->shunt = shunt; | ||
198 | |||
187 | data->client = client; | 199 | data->client = client; |
188 | mutex_init(&data->update_lock); | 200 | mutex_init(&data->update_lock); |
189 | 201 | ||
@@ -199,10 +211,16 @@ static const struct i2c_device_id ltc4151_id[] = { | |||
199 | }; | 211 | }; |
200 | MODULE_DEVICE_TABLE(i2c, ltc4151_id); | 212 | MODULE_DEVICE_TABLE(i2c, ltc4151_id); |
201 | 213 | ||
214 | static const struct of_device_id ltc4151_match[] = { | ||
215 | { .compatible = "lltc,ltc4151" }, | ||
216 | {}, | ||
217 | }; | ||
218 | |||
202 | /* This is the driver that will be inserted */ | 219 | /* This is the driver that will be inserted */ |
203 | static struct i2c_driver ltc4151_driver = { | 220 | static struct i2c_driver ltc4151_driver = { |
204 | .driver = { | 221 | .driver = { |
205 | .name = "ltc4151", | 222 | .name = "ltc4151", |
223 | .of_match_table = of_match_ptr(ltc4151_match), | ||
206 | }, | 224 | }, |
207 | .probe = ltc4151_probe, | 225 | .probe = ltc4151_probe, |
208 | .id_table = ltc4151_id, | 226 | .id_table = ltc4151_id, |
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 681b5b7b3c3b..4680d89556ce 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/bitops.h> | ||
19 | #include <linux/err.h> | 20 | #include <linux/err.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
@@ -53,8 +54,6 @@ enum ltc4245_cmd { | |||
53 | struct ltc4245_data { | 54 | struct ltc4245_data { |
54 | struct i2c_client *client; | 55 | struct i2c_client *client; |
55 | 56 | ||
56 | const struct attribute_group *groups[3]; | ||
57 | |||
58 | struct mutex update_lock; | 57 | struct mutex update_lock; |
59 | bool valid; | 58 | bool valid; |
60 | unsigned long last_updated; /* in jiffies */ | 59 | unsigned long last_updated; /* in jiffies */ |
@@ -162,7 +161,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev) | |||
162 | ltc4245_update_gpios(dev); | 161 | ltc4245_update_gpios(dev); |
163 | 162 | ||
164 | data->last_updated = jiffies; | 163 | data->last_updated = jiffies; |
165 | data->valid = 1; | 164 | data->valid = true; |
166 | } | 165 | } |
167 | 166 | ||
168 | mutex_unlock(&data->update_lock); | 167 | mutex_unlock(&data->update_lock); |
@@ -256,213 +255,204 @@ static unsigned int ltc4245_get_current(struct device *dev, u8 reg) | |||
256 | return curr; | 255 | return curr; |
257 | } | 256 | } |
258 | 257 | ||
259 | static ssize_t ltc4245_show_voltage(struct device *dev, | 258 | /* Map from voltage channel index to voltage register */ |
260 | struct device_attribute *da, | ||
261 | char *buf) | ||
262 | { | ||
263 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
264 | const int voltage = ltc4245_get_voltage(dev, attr->index); | ||
265 | 259 | ||
266 | return snprintf(buf, PAGE_SIZE, "%d\n", voltage); | 260 | static const s8 ltc4245_in_regs[] = { |
267 | } | 261 | LTC4245_12VIN, LTC4245_5VIN, LTC4245_3VIN, LTC4245_VEEIN, |
262 | LTC4245_12VOUT, LTC4245_5VOUT, LTC4245_3VOUT, LTC4245_VEEOUT, | ||
263 | }; | ||
264 | |||
265 | /* Map from current channel index to current register */ | ||
268 | 266 | ||
269 | static ssize_t ltc4245_show_current(struct device *dev, | 267 | static const s8 ltc4245_curr_regs[] = { |
270 | struct device_attribute *da, | 268 | LTC4245_12VSENSE, LTC4245_5VSENSE, LTC4245_3VSENSE, LTC4245_VEESENSE, |
271 | char *buf) | 269 | }; |
270 | |||
271 | static int ltc4245_read_curr(struct device *dev, u32 attr, int channel, | ||
272 | long *val) | ||
272 | { | 273 | { |
273 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 274 | struct ltc4245_data *data = ltc4245_update_device(dev); |
274 | const unsigned int curr = ltc4245_get_current(dev, attr->index); | ||
275 | 275 | ||
276 | return snprintf(buf, PAGE_SIZE, "%u\n", curr); | 276 | switch (attr) { |
277 | case hwmon_curr_input: | ||
278 | *val = ltc4245_get_current(dev, ltc4245_curr_regs[channel]); | ||
279 | return 0; | ||
280 | case hwmon_curr_max_alarm: | ||
281 | *val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel + 4)); | ||
282 | return 0; | ||
283 | default: | ||
284 | return -EOPNOTSUPP; | ||
285 | } | ||
277 | } | 286 | } |
278 | 287 | ||
279 | static ssize_t ltc4245_show_power(struct device *dev, | 288 | static int ltc4245_read_in(struct device *dev, u32 attr, int channel, long *val) |
280 | struct device_attribute *da, | ||
281 | char *buf) | ||
282 | { | 289 | { |
283 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 290 | struct ltc4245_data *data = ltc4245_update_device(dev); |
284 | const unsigned int curr = ltc4245_get_current(dev, attr->index); | ||
285 | const int output_voltage = ltc4245_get_voltage(dev, attr->index+1); | ||
286 | 291 | ||
287 | /* current in mA * voltage in mV == power in uW */ | 292 | switch (attr) { |
288 | const unsigned int power = abs(output_voltage * curr); | 293 | case hwmon_in_input: |
294 | if (channel < 8) { | ||
295 | *val = ltc4245_get_voltage(dev, | ||
296 | ltc4245_in_regs[channel]); | ||
297 | } else { | ||
298 | int regval = data->gpios[channel - 8]; | ||
299 | |||
300 | if (regval < 0) | ||
301 | return regval; | ||
302 | *val = regval * 10; | ||
303 | } | ||
304 | return 0; | ||
305 | case hwmon_in_min_alarm: | ||
306 | if (channel < 4) | ||
307 | *val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel)); | ||
308 | else | ||
309 | *val = !!(data->cregs[LTC4245_FAULT2] & | ||
310 | BIT(channel - 4)); | ||
311 | return 0; | ||
312 | default: | ||
313 | return -EOPNOTSUPP; | ||
314 | } | ||
315 | } | ||
289 | 316 | ||
290 | return snprintf(buf, PAGE_SIZE, "%u\n", power); | 317 | static int ltc4245_read_power(struct device *dev, u32 attr, int channel, |
318 | long *val) | ||
319 | { | ||
320 | unsigned long curr; | ||
321 | long voltage; | ||
322 | |||
323 | switch (attr) { | ||
324 | case hwmon_power_input: | ||
325 | (void)ltc4245_update_device(dev); | ||
326 | curr = ltc4245_get_current(dev, ltc4245_curr_regs[channel]); | ||
327 | voltage = ltc4245_get_voltage(dev, ltc4245_in_regs[channel]); | ||
328 | *val = abs(curr * voltage); | ||
329 | return 0; | ||
330 | default: | ||
331 | return -EOPNOTSUPP; | ||
332 | } | ||
291 | } | 333 | } |
292 | 334 | ||
293 | static ssize_t ltc4245_show_alarm(struct device *dev, | 335 | static int ltc4245_read(struct device *dev, enum hwmon_sensor_types type, |
294 | struct device_attribute *da, | 336 | u32 attr, int channel, long *val) |
295 | char *buf) | ||
296 | { | 337 | { |
297 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da); | ||
298 | struct ltc4245_data *data = ltc4245_update_device(dev); | ||
299 | const u8 reg = data->cregs[attr->index]; | ||
300 | const u32 mask = attr->nr; | ||
301 | 338 | ||
302 | return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); | 339 | switch (type) { |
340 | case hwmon_curr: | ||
341 | return ltc4245_read_curr(dev, attr, channel, val); | ||
342 | case hwmon_power: | ||
343 | return ltc4245_read_power(dev, attr, channel, val); | ||
344 | case hwmon_in: | ||
345 | return ltc4245_read_in(dev, attr, channel - 1, val); | ||
346 | default: | ||
347 | return -EOPNOTSUPP; | ||
348 | } | ||
303 | } | 349 | } |
304 | 350 | ||
305 | static ssize_t ltc4245_show_gpio(struct device *dev, | 351 | static umode_t ltc4245_is_visible(const void *_data, |
306 | struct device_attribute *da, | 352 | enum hwmon_sensor_types type, |
307 | char *buf) | 353 | u32 attr, int channel) |
308 | { | 354 | { |
309 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 355 | const struct ltc4245_data *data = _data; |
310 | struct ltc4245_data *data = ltc4245_update_device(dev); | 356 | |
311 | int val = data->gpios[attr->index]; | 357 | switch (type) { |
358 | case hwmon_in: | ||
359 | if (channel == 0) | ||
360 | return 0; | ||
361 | switch (attr) { | ||
362 | case hwmon_in_input: | ||
363 | if (channel > 9 && !data->use_extra_gpios) | ||
364 | return 0; | ||
365 | return S_IRUGO; | ||
366 | case hwmon_in_min_alarm: | ||
367 | if (channel > 8) | ||
368 | return 0; | ||
369 | return S_IRUGO; | ||
370 | default: | ||
371 | return 0; | ||
372 | } | ||
373 | case hwmon_curr: | ||
374 | switch (attr) { | ||
375 | case hwmon_curr_input: | ||
376 | case hwmon_curr_max_alarm: | ||
377 | return S_IRUGO; | ||
378 | default: | ||
379 | return 0; | ||
380 | } | ||
381 | case hwmon_power: | ||
382 | switch (attr) { | ||
383 | case hwmon_power_input: | ||
384 | return S_IRUGO; | ||
385 | default: | ||
386 | return 0; | ||
387 | } | ||
388 | default: | ||
389 | return 0; | ||
390 | } | ||
391 | } | ||
312 | 392 | ||
313 | /* handle stale GPIO's */ | 393 | static const u32 ltc4245_in_config[] = { |
314 | if (val < 0) | 394 | HWMON_I_INPUT, /* dummy, skipped in is_visible */ |
315 | return val; | 395 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, |
396 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
397 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
398 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
399 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
400 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
401 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
402 | HWMON_I_INPUT | HWMON_I_MIN_ALARM, | ||
403 | HWMON_I_INPUT, | ||
404 | HWMON_I_INPUT, | ||
405 | HWMON_I_INPUT, | ||
406 | 0 | ||
407 | }; | ||
316 | 408 | ||
317 | /* Convert to millivolts and print */ | 409 | static const struct hwmon_channel_info ltc4245_in = { |
318 | return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); | 410 | .type = hwmon_in, |
319 | } | 411 | .config = ltc4245_in_config, |
412 | }; | ||
320 | 413 | ||
321 | /* Construct a sensor_device_attribute structure for each register */ | 414 | static const u32 ltc4245_curr_config[] = { |
322 | 415 | HWMON_C_INPUT | HWMON_C_MAX_ALARM, | |
323 | /* Input voltages */ | 416 | HWMON_C_INPUT | HWMON_C_MAX_ALARM, |
324 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4245_show_voltage, NULL, | 417 | HWMON_C_INPUT | HWMON_C_MAX_ALARM, |
325 | LTC4245_12VIN); | 418 | HWMON_C_INPUT | HWMON_C_MAX_ALARM, |
326 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4245_show_voltage, NULL, | 419 | 0 |
327 | LTC4245_5VIN); | 420 | }; |
328 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
329 | LTC4245_3VIN); | ||
330 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
331 | LTC4245_VEEIN); | ||
332 | |||
333 | /* Input undervoltage alarms */ | ||
334 | static SENSOR_DEVICE_ATTR_2(in1_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
335 | 1 << 0, LTC4245_FAULT1); | ||
336 | static SENSOR_DEVICE_ATTR_2(in2_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
337 | 1 << 1, LTC4245_FAULT1); | ||
338 | static SENSOR_DEVICE_ATTR_2(in3_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
339 | 1 << 2, LTC4245_FAULT1); | ||
340 | static SENSOR_DEVICE_ATTR_2(in4_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
341 | 1 << 3, LTC4245_FAULT1); | ||
342 | |||
343 | /* Currents (via sense resistor) */ | ||
344 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4245_show_current, NULL, | ||
345 | LTC4245_12VSENSE); | ||
346 | static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc4245_show_current, NULL, | ||
347 | LTC4245_5VSENSE); | ||
348 | static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, ltc4245_show_current, NULL, | ||
349 | LTC4245_3VSENSE); | ||
350 | static SENSOR_DEVICE_ATTR(curr4_input, S_IRUGO, ltc4245_show_current, NULL, | ||
351 | LTC4245_VEESENSE); | ||
352 | |||
353 | /* Overcurrent alarms */ | ||
354 | static SENSOR_DEVICE_ATTR_2(curr1_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
355 | 1 << 4, LTC4245_FAULT1); | ||
356 | static SENSOR_DEVICE_ATTR_2(curr2_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
357 | 1 << 5, LTC4245_FAULT1); | ||
358 | static SENSOR_DEVICE_ATTR_2(curr3_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
359 | 1 << 6, LTC4245_FAULT1); | ||
360 | static SENSOR_DEVICE_ATTR_2(curr4_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
361 | 1 << 7, LTC4245_FAULT1); | ||
362 | |||
363 | /* Output voltages */ | ||
364 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
365 | LTC4245_12VOUT); | ||
366 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
367 | LTC4245_5VOUT); | ||
368 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
369 | LTC4245_3VOUT); | ||
370 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, ltc4245_show_voltage, NULL, | ||
371 | LTC4245_VEEOUT); | ||
372 | |||
373 | /* Power Bad alarms */ | ||
374 | static SENSOR_DEVICE_ATTR_2(in5_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
375 | 1 << 0, LTC4245_FAULT2); | ||
376 | static SENSOR_DEVICE_ATTR_2(in6_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
377 | 1 << 1, LTC4245_FAULT2); | ||
378 | static SENSOR_DEVICE_ATTR_2(in7_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
379 | 1 << 2, LTC4245_FAULT2); | ||
380 | static SENSOR_DEVICE_ATTR_2(in8_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, | ||
381 | 1 << 3, LTC4245_FAULT2); | ||
382 | |||
383 | /* GPIO voltages */ | ||
384 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, ltc4245_show_gpio, NULL, 0); | ||
385 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, ltc4245_show_gpio, NULL, 1); | ||
386 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, ltc4245_show_gpio, NULL, 2); | ||
387 | |||
388 | /* Power Consumption (virtual) */ | ||
389 | static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4245_show_power, NULL, | ||
390 | LTC4245_12VSENSE); | ||
391 | static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, ltc4245_show_power, NULL, | ||
392 | LTC4245_5VSENSE); | ||
393 | static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, ltc4245_show_power, NULL, | ||
394 | LTC4245_3VSENSE); | ||
395 | static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, ltc4245_show_power, NULL, | ||
396 | LTC4245_VEESENSE); | ||
397 | 421 | ||
398 | /* | 422 | static const struct hwmon_channel_info ltc4245_curr = { |
399 | * Finally, construct an array of pointers to members of the above objects, | 423 | .type = hwmon_curr, |
400 | * as required for sysfs_create_group() | 424 | .config = ltc4245_curr_config, |
401 | */ | ||
402 | static struct attribute *ltc4245_std_attributes[] = { | ||
403 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
404 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
405 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
406 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
407 | |||
408 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, | ||
409 | &sensor_dev_attr_in2_min_alarm.dev_attr.attr, | ||
410 | &sensor_dev_attr_in3_min_alarm.dev_attr.attr, | ||
411 | &sensor_dev_attr_in4_min_alarm.dev_attr.attr, | ||
412 | |||
413 | &sensor_dev_attr_curr1_input.dev_attr.attr, | ||
414 | &sensor_dev_attr_curr2_input.dev_attr.attr, | ||
415 | &sensor_dev_attr_curr3_input.dev_attr.attr, | ||
416 | &sensor_dev_attr_curr4_input.dev_attr.attr, | ||
417 | |||
418 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, | ||
419 | &sensor_dev_attr_curr2_max_alarm.dev_attr.attr, | ||
420 | &sensor_dev_attr_curr3_max_alarm.dev_attr.attr, | ||
421 | &sensor_dev_attr_curr4_max_alarm.dev_attr.attr, | ||
422 | |||
423 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
424 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
425 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
426 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
427 | |||
428 | &sensor_dev_attr_in5_min_alarm.dev_attr.attr, | ||
429 | &sensor_dev_attr_in6_min_alarm.dev_attr.attr, | ||
430 | &sensor_dev_attr_in7_min_alarm.dev_attr.attr, | ||
431 | &sensor_dev_attr_in8_min_alarm.dev_attr.attr, | ||
432 | |||
433 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
434 | |||
435 | &sensor_dev_attr_power1_input.dev_attr.attr, | ||
436 | &sensor_dev_attr_power2_input.dev_attr.attr, | ||
437 | &sensor_dev_attr_power3_input.dev_attr.attr, | ||
438 | &sensor_dev_attr_power4_input.dev_attr.attr, | ||
439 | |||
440 | NULL, | ||
441 | }; | 425 | }; |
442 | 426 | ||
443 | static struct attribute *ltc4245_gpio_attributes[] = { | 427 | static const u32 ltc4245_power_config[] = { |
444 | &sensor_dev_attr_in10_input.dev_attr.attr, | 428 | HWMON_P_INPUT, |
445 | &sensor_dev_attr_in11_input.dev_attr.attr, | 429 | HWMON_P_INPUT, |
446 | NULL, | 430 | HWMON_P_INPUT, |
431 | HWMON_P_INPUT, | ||
432 | 0 | ||
447 | }; | 433 | }; |
448 | 434 | ||
449 | static const struct attribute_group ltc4245_std_group = { | 435 | static const struct hwmon_channel_info ltc4245_power = { |
450 | .attrs = ltc4245_std_attributes, | 436 | .type = hwmon_power, |
437 | .config = ltc4245_power_config, | ||
451 | }; | 438 | }; |
452 | 439 | ||
453 | static const struct attribute_group ltc4245_gpio_group = { | 440 | static const struct hwmon_channel_info *ltc4245_info[] = { |
454 | .attrs = ltc4245_gpio_attributes, | 441 | <c4245_in, |
442 | <c4245_curr, | ||
443 | <c4245_power, | ||
444 | NULL | ||
455 | }; | 445 | }; |
456 | 446 | ||
457 | static void ltc4245_sysfs_add_groups(struct ltc4245_data *data) | 447 | static const struct hwmon_ops ltc4245_hwmon_ops = { |
458 | { | 448 | .is_visible = ltc4245_is_visible, |
459 | /* standard sysfs attributes */ | 449 | .read = ltc4245_read, |
460 | data->groups[0] = <c4245_std_group; | 450 | }; |
461 | 451 | ||
462 | /* if we're using the extra gpio support, register it's attributes */ | 452 | static const struct hwmon_chip_info ltc4245_chip_info = { |
463 | if (data->use_extra_gpios) | 453 | .ops = <c4245_hwmon_ops, |
464 | data->groups[1] = <c4245_gpio_group; | 454 | .info = ltc4245_info, |
465 | } | 455 | }; |
466 | 456 | ||
467 | static bool ltc4245_use_extra_gpios(struct i2c_client *client) | 457 | static bool ltc4245_use_extra_gpios(struct i2c_client *client) |
468 | { | 458 | { |
@@ -502,12 +492,10 @@ static int ltc4245_probe(struct i2c_client *client, | |||
502 | i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00); | 492 | i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00); |
503 | i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00); | 493 | i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00); |
504 | 494 | ||
505 | /* Add sysfs hooks */ | 495 | hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, |
506 | ltc4245_sysfs_add_groups(data); | 496 | client->name, data, |
507 | 497 | <c4245_chip_info, | |
508 | hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, | 498 | NULL); |
509 | client->name, data, | ||
510 | data->groups); | ||
511 | return PTR_ERR_OR_ZERO(hwmon_dev); | 499 | return PTR_ERR_OR_ZERO(hwmon_dev); |
512 | } | 500 | } |
513 | 501 | ||
diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c index 69c0ac80a946..bef84e085973 100644 --- a/drivers/hwmon/max31790.c +++ b/drivers/hwmon/max31790.c | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/hwmon.h> | 19 | #include <linux/hwmon.h> |
20 | #include <linux/hwmon-sysfs.h> | ||
21 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
23 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
@@ -169,362 +168,288 @@ static u8 bits_for_tach_period(int rpm) | |||
169 | return bits; | 168 | return bits; |
170 | } | 169 | } |
171 | 170 | ||
172 | static ssize_t get_fan(struct device *dev, | 171 | static int max31790_read_fan(struct device *dev, u32 attr, int channel, |
173 | struct device_attribute *devattr, char *buf) | 172 | long *val) |
174 | { | 173 | { |
175 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
176 | struct max31790_data *data = max31790_update_device(dev); | 174 | struct max31790_data *data = max31790_update_device(dev); |
177 | int sr, rpm; | 175 | int sr, rpm; |
178 | 176 | ||
179 | if (IS_ERR(data)) | 177 | if (IS_ERR(data)) |
180 | return PTR_ERR(data); | 178 | return PTR_ERR(data); |
181 | 179 | ||
182 | sr = get_tach_period(data->fan_dynamics[attr->index]); | 180 | switch (attr) { |
183 | rpm = RPM_FROM_REG(data->tach[attr->index], sr); | 181 | case hwmon_fan_input: |
184 | 182 | sr = get_tach_period(data->fan_dynamics[channel]); | |
185 | return sprintf(buf, "%d\n", rpm); | 183 | rpm = RPM_FROM_REG(data->tach[channel], sr); |
186 | } | 184 | *val = rpm; |
187 | 185 | return 0; | |
188 | static ssize_t get_fan_target(struct device *dev, | 186 | case hwmon_fan_target: |
189 | struct device_attribute *devattr, char *buf) | 187 | sr = get_tach_period(data->fan_dynamics[channel]); |
190 | { | 188 | rpm = RPM_FROM_REG(data->target_count[channel], sr); |
191 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 189 | *val = rpm; |
192 | struct max31790_data *data = max31790_update_device(dev); | 190 | return 0; |
193 | int sr, rpm; | 191 | case hwmon_fan_fault: |
194 | 192 | *val = !!(data->fault_status & (1 << channel)); | |
195 | if (IS_ERR(data)) | 193 | return 0; |
196 | return PTR_ERR(data); | 194 | default: |
197 | 195 | return -EOPNOTSUPP; | |
198 | sr = get_tach_period(data->fan_dynamics[attr->index]); | 196 | } |
199 | rpm = RPM_FROM_REG(data->target_count[attr->index], sr); | ||
200 | |||
201 | return sprintf(buf, "%d\n", rpm); | ||
202 | } | 197 | } |
203 | 198 | ||
204 | static ssize_t set_fan_target(struct device *dev, | 199 | static int max31790_write_fan(struct device *dev, u32 attr, int channel, |
205 | struct device_attribute *devattr, | 200 | long val) |
206 | const char *buf, size_t count) | ||
207 | { | 201 | { |
208 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
209 | struct max31790_data *data = dev_get_drvdata(dev); | 202 | struct max31790_data *data = dev_get_drvdata(dev); |
210 | struct i2c_client *client = data->client; | 203 | struct i2c_client *client = data->client; |
204 | int target_count; | ||
205 | int err = 0; | ||
211 | u8 bits; | 206 | u8 bits; |
212 | int sr; | 207 | int sr; |
213 | int target_count; | ||
214 | unsigned long rpm; | ||
215 | int err; | ||
216 | |||
217 | err = kstrtoul(buf, 10, &rpm); | ||
218 | if (err) | ||
219 | return err; | ||
220 | 208 | ||
221 | mutex_lock(&data->update_lock); | 209 | mutex_lock(&data->update_lock); |
222 | 210 | ||
223 | rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX); | 211 | switch (attr) { |
224 | bits = bits_for_tach_period(rpm); | 212 | case hwmon_fan_target: |
225 | data->fan_dynamics[attr->index] = | 213 | val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX); |
226 | ((data->fan_dynamics[attr->index] | 214 | bits = bits_for_tach_period(val); |
227 | & ~MAX31790_FAN_DYN_SR_MASK) | 215 | data->fan_dynamics[channel] = |
228 | | (bits << MAX31790_FAN_DYN_SR_SHIFT)); | 216 | ((data->fan_dynamics[channel] & |
229 | err = i2c_smbus_write_byte_data(client, | 217 | ~MAX31790_FAN_DYN_SR_MASK) | |
230 | MAX31790_REG_FAN_DYNAMICS(attr->index), | 218 | (bits << MAX31790_FAN_DYN_SR_SHIFT)); |
231 | data->fan_dynamics[attr->index]); | 219 | err = i2c_smbus_write_byte_data(client, |
232 | 220 | MAX31790_REG_FAN_DYNAMICS(channel), | |
233 | if (err < 0) { | 221 | data->fan_dynamics[channel]); |
234 | mutex_unlock(&data->update_lock); | 222 | if (err < 0) |
235 | return err; | 223 | break; |
224 | |||
225 | sr = get_tach_period(data->fan_dynamics[channel]); | ||
226 | target_count = RPM_TO_REG(val, sr); | ||
227 | target_count = clamp_val(target_count, 0x1, 0x7FF); | ||
228 | |||
229 | data->target_count[channel] = target_count << 5; | ||
230 | |||
231 | err = i2c_smbus_write_word_swapped(client, | ||
232 | MAX31790_REG_TARGET_COUNT(channel), | ||
233 | data->target_count[channel]); | ||
234 | break; | ||
235 | default: | ||
236 | err = -EOPNOTSUPP; | ||
237 | break; | ||
236 | } | 238 | } |
237 | 239 | ||
238 | sr = get_tach_period(data->fan_dynamics[attr->index]); | ||
239 | target_count = RPM_TO_REG(rpm, sr); | ||
240 | target_count = clamp_val(target_count, 0x1, 0x7FF); | ||
241 | |||
242 | data->target_count[attr->index] = target_count << 5; | ||
243 | |||
244 | err = i2c_smbus_write_word_swapped(client, | ||
245 | MAX31790_REG_TARGET_COUNT(attr->index), | ||
246 | data->target_count[attr->index]); | ||
247 | |||
248 | mutex_unlock(&data->update_lock); | 240 | mutex_unlock(&data->update_lock); |
249 | 241 | ||
250 | if (err < 0) | 242 | return err; |
251 | return err; | 243 | } |
252 | 244 | ||
253 | return count; | 245 | static umode_t max31790_fan_is_visible(const void *_data, u32 attr, int channel) |
246 | { | ||
247 | const struct max31790_data *data = _data; | ||
248 | u8 fan_config = data->fan_config[channel % NR_CHANNEL]; | ||
249 | |||
250 | switch (attr) { | ||
251 | case hwmon_fan_input: | ||
252 | case hwmon_fan_fault: | ||
253 | if (channel < NR_CHANNEL || | ||
254 | (fan_config & MAX31790_FAN_CFG_TACH_INPUT)) | ||
255 | return S_IRUGO; | ||
256 | return 0; | ||
257 | case hwmon_fan_target: | ||
258 | if (channel < NR_CHANNEL && | ||
259 | !(fan_config & MAX31790_FAN_CFG_TACH_INPUT)) | ||
260 | return S_IRUGO | S_IWUSR; | ||
261 | return 0; | ||
262 | default: | ||
263 | return 0; | ||
264 | } | ||
254 | } | 265 | } |
255 | 266 | ||
256 | static ssize_t get_pwm(struct device *dev, | 267 | static int max31790_read_pwm(struct device *dev, u32 attr, int channel, |
257 | struct device_attribute *devattr, char *buf) | 268 | long *val) |
258 | { | 269 | { |
259 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
260 | struct max31790_data *data = max31790_update_device(dev); | 270 | struct max31790_data *data = max31790_update_device(dev); |
261 | int pwm; | 271 | u8 fan_config = data->fan_config[channel]; |
262 | 272 | ||
263 | if (IS_ERR(data)) | 273 | if (IS_ERR(data)) |
264 | return PTR_ERR(data); | 274 | return PTR_ERR(data); |
265 | 275 | ||
266 | pwm = data->pwm[attr->index] >> 8; | 276 | switch (attr) { |
267 | 277 | case hwmon_pwm_input: | |
268 | return sprintf(buf, "%d\n", pwm); | 278 | *val = data->pwm[channel] >> 8; |
279 | return 0; | ||
280 | case hwmon_pwm_enable: | ||
281 | if (fan_config & MAX31790_FAN_CFG_RPM_MODE) | ||
282 | *val = 2; | ||
283 | else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN) | ||
284 | *val = 1; | ||
285 | else | ||
286 | *val = 0; | ||
287 | return 0; | ||
288 | default: | ||
289 | return -EOPNOTSUPP; | ||
290 | } | ||
269 | } | 291 | } |
270 | 292 | ||
271 | static ssize_t set_pwm(struct device *dev, | 293 | static int max31790_write_pwm(struct device *dev, u32 attr, int channel, |
272 | struct device_attribute *devattr, | 294 | long val) |
273 | const char *buf, size_t count) | ||
274 | { | 295 | { |
275 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
276 | struct max31790_data *data = dev_get_drvdata(dev); | 296 | struct max31790_data *data = dev_get_drvdata(dev); |
277 | struct i2c_client *client = data->client; | 297 | struct i2c_client *client = data->client; |
278 | unsigned long pwm; | 298 | u8 fan_config; |
279 | int err; | 299 | int err = 0; |
280 | |||
281 | err = kstrtoul(buf, 10, &pwm); | ||
282 | if (err) | ||
283 | return err; | ||
284 | |||
285 | if (pwm > 255) | ||
286 | return -EINVAL; | ||
287 | 300 | ||
288 | mutex_lock(&data->update_lock); | 301 | mutex_lock(&data->update_lock); |
289 | 302 | ||
290 | data->pwm[attr->index] = pwm << 8; | 303 | switch (attr) { |
291 | err = i2c_smbus_write_word_swapped(client, | 304 | case hwmon_pwm_input: |
292 | MAX31790_REG_PWMOUT(attr->index), | 305 | if (val < 0 || val > 255) { |
293 | data->pwm[attr->index]); | 306 | err = -EINVAL; |
307 | break; | ||
308 | } | ||
309 | data->pwm[channel] = val << 8; | ||
310 | err = i2c_smbus_write_word_swapped(client, | ||
311 | MAX31790_REG_PWMOUT(channel), | ||
312 | val); | ||
313 | break; | ||
314 | case hwmon_pwm_enable: | ||
315 | fan_config = data->fan_config[channel]; | ||
316 | if (val == 0) { | ||
317 | fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN | | ||
318 | MAX31790_FAN_CFG_RPM_MODE); | ||
319 | } else if (val == 1) { | ||
320 | fan_config = (fan_config | | ||
321 | MAX31790_FAN_CFG_TACH_INPUT_EN) & | ||
322 | ~MAX31790_FAN_CFG_RPM_MODE; | ||
323 | } else if (val == 2) { | ||
324 | fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN | | ||
325 | MAX31790_FAN_CFG_RPM_MODE; | ||
326 | } else { | ||
327 | err = -EINVAL; | ||
328 | break; | ||
329 | } | ||
330 | data->fan_config[channel] = fan_config; | ||
331 | err = i2c_smbus_write_byte_data(client, | ||
332 | MAX31790_REG_FAN_CONFIG(channel), | ||
333 | fan_config); | ||
334 | break; | ||
335 | default: | ||
336 | err = -EOPNOTSUPP; | ||
337 | break; | ||
338 | } | ||
294 | 339 | ||
295 | mutex_unlock(&data->update_lock); | 340 | mutex_unlock(&data->update_lock); |
296 | 341 | ||
297 | if (err < 0) | 342 | return err; |
298 | return err; | ||
299 | |||
300 | return count; | ||
301 | } | 343 | } |
302 | 344 | ||
303 | static ssize_t get_pwm_enable(struct device *dev, | 345 | static umode_t max31790_pwm_is_visible(const void *_data, u32 attr, int channel) |
304 | struct device_attribute *devattr, char *buf) | ||
305 | { | 346 | { |
306 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 347 | const struct max31790_data *data = _data; |
307 | struct max31790_data *data = max31790_update_device(dev); | 348 | u8 fan_config = data->fan_config[channel]; |
308 | int mode; | 349 | |
309 | 350 | switch (attr) { | |
310 | if (IS_ERR(data)) | 351 | case hwmon_pwm_input: |
311 | return PTR_ERR(data); | 352 | case hwmon_pwm_enable: |
312 | 353 | if (!(fan_config & MAX31790_FAN_CFG_TACH_INPUT)) | |
313 | if (data->fan_config[attr->index] & MAX31790_FAN_CFG_RPM_MODE) | 354 | return S_IRUGO | S_IWUSR; |
314 | mode = 2; | 355 | return 0; |
315 | else if (data->fan_config[attr->index] & MAX31790_FAN_CFG_TACH_INPUT_EN) | 356 | default: |
316 | mode = 1; | 357 | return 0; |
317 | else | 358 | } |
318 | mode = 0; | ||
319 | |||
320 | return sprintf(buf, "%d\n", mode); | ||
321 | } | 359 | } |
322 | 360 | ||
323 | static ssize_t set_pwm_enable(struct device *dev, | 361 | static int max31790_read(struct device *dev, enum hwmon_sensor_types type, |
324 | struct device_attribute *devattr, | 362 | u32 attr, int channel, long *val) |
325 | const char *buf, size_t count) | ||
326 | { | 363 | { |
327 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 364 | switch (type) { |
328 | struct max31790_data *data = dev_get_drvdata(dev); | 365 | case hwmon_fan: |
329 | struct i2c_client *client = data->client; | 366 | return max31790_read_fan(dev, attr, channel, val); |
330 | unsigned long mode; | 367 | case hwmon_pwm: |
331 | int err; | 368 | return max31790_read_pwm(dev, attr, channel, val); |
332 | |||
333 | err = kstrtoul(buf, 10, &mode); | ||
334 | if (err) | ||
335 | return err; | ||
336 | |||
337 | switch (mode) { | ||
338 | case 0: | ||
339 | data->fan_config[attr->index] = | ||
340 | data->fan_config[attr->index] | ||
341 | & ~(MAX31790_FAN_CFG_TACH_INPUT_EN | ||
342 | | MAX31790_FAN_CFG_RPM_MODE); | ||
343 | break; | ||
344 | case 1: | ||
345 | data->fan_config[attr->index] = | ||
346 | (data->fan_config[attr->index] | ||
347 | | MAX31790_FAN_CFG_TACH_INPUT_EN) | ||
348 | & ~MAX31790_FAN_CFG_RPM_MODE; | ||
349 | break; | ||
350 | case 2: | ||
351 | data->fan_config[attr->index] = | ||
352 | data->fan_config[attr->index] | ||
353 | | MAX31790_FAN_CFG_TACH_INPUT_EN | ||
354 | | MAX31790_FAN_CFG_RPM_MODE; | ||
355 | break; | ||
356 | default: | 369 | default: |
357 | return -EINVAL; | 370 | return -EOPNOTSUPP; |
358 | } | 371 | } |
359 | |||
360 | mutex_lock(&data->update_lock); | ||
361 | |||
362 | err = i2c_smbus_write_byte_data(client, | ||
363 | MAX31790_REG_FAN_CONFIG(attr->index), | ||
364 | data->fan_config[attr->index]); | ||
365 | |||
366 | mutex_unlock(&data->update_lock); | ||
367 | |||
368 | if (err < 0) | ||
369 | return err; | ||
370 | |||
371 | return count; | ||
372 | } | 372 | } |
373 | 373 | ||
374 | static ssize_t get_fan_fault(struct device *dev, | 374 | static int max31790_write(struct device *dev, enum hwmon_sensor_types type, |
375 | struct device_attribute *devattr, char *buf) | 375 | u32 attr, int channel, long val) |
376 | { | 376 | { |
377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 377 | switch (type) { |
378 | struct max31790_data *data = max31790_update_device(dev); | 378 | case hwmon_fan: |
379 | int fault; | 379 | return max31790_write_fan(dev, attr, channel, val); |
380 | 380 | case hwmon_pwm: | |
381 | if (IS_ERR(data)) | 381 | return max31790_write_pwm(dev, attr, channel, val); |
382 | return PTR_ERR(data); | 382 | default: |
383 | 383 | return -EOPNOTSUPP; | |
384 | fault = !!(data->fault_status & (1 << attr->index)); | 384 | } |
385 | } | ||
385 | 386 | ||
386 | return sprintf(buf, "%d\n", fault); | 387 | static umode_t max31790_is_visible(const void *data, |
388 | enum hwmon_sensor_types type, | ||
389 | u32 attr, int channel) | ||
390 | { | ||
391 | switch (type) { | ||
392 | case hwmon_fan: | ||
393 | return max31790_fan_is_visible(data, attr, channel); | ||
394 | case hwmon_pwm: | ||
395 | return max31790_pwm_is_visible(data, attr, channel); | ||
396 | default: | ||
397 | return 0; | ||
398 | } | ||
387 | } | 399 | } |
388 | 400 | ||
389 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); | 401 | static const u32 max31790_fan_config[] = { |
390 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); | 402 | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, |
391 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); | 403 | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, |
392 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3); | 404 | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, |
393 | static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, get_fan, NULL, 4); | 405 | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, |
394 | static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, get_fan, NULL, 5); | 406 | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, |
395 | 407 | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, | |
396 | static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_fault, NULL, 0); | 408 | HWMON_F_INPUT | HWMON_F_FAULT, |
397 | static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, get_fan_fault, NULL, 1); | 409 | HWMON_F_INPUT | HWMON_F_FAULT, |
398 | static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, get_fan_fault, NULL, 2); | 410 | HWMON_F_INPUT | HWMON_F_FAULT, |
399 | static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, get_fan_fault, NULL, 3); | 411 | HWMON_F_INPUT | HWMON_F_FAULT, |
400 | static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, get_fan_fault, NULL, 4); | 412 | HWMON_F_INPUT | HWMON_F_FAULT, |
401 | static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, get_fan_fault, NULL, 5); | 413 | HWMON_F_INPUT | HWMON_F_FAULT, |
402 | 414 | 0 | |
403 | static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, get_fan, NULL, 6); | ||
404 | static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, get_fan, NULL, 7); | ||
405 | static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, get_fan, NULL, 8); | ||
406 | static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, get_fan, NULL, 9); | ||
407 | static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, get_fan, NULL, 10); | ||
408 | static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, get_fan, NULL, 11); | ||
409 | |||
410 | static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, get_fan_fault, NULL, 6); | ||
411 | static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, get_fan_fault, NULL, 7); | ||
412 | static SENSOR_DEVICE_ATTR(fan9_fault, S_IRUGO, get_fan_fault, NULL, 8); | ||
413 | static SENSOR_DEVICE_ATTR(fan10_fault, S_IRUGO, get_fan_fault, NULL, 9); | ||
414 | static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, get_fan_fault, NULL, 10); | ||
415 | static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, get_fan_fault, NULL, 11); | ||
416 | |||
417 | static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, | ||
418 | get_fan_target, set_fan_target, 0); | ||
419 | static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, | ||
420 | get_fan_target, set_fan_target, 1); | ||
421 | static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, | ||
422 | get_fan_target, set_fan_target, 2); | ||
423 | static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, | ||
424 | get_fan_target, set_fan_target, 3); | ||
425 | static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, | ||
426 | get_fan_target, set_fan_target, 4); | ||
427 | static SENSOR_DEVICE_ATTR(fan6_target, S_IWUSR | S_IRUGO, | ||
428 | get_fan_target, set_fan_target, 5); | ||
429 | |||
430 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 0); | ||
431 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 1); | ||
432 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 2); | ||
433 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 3); | ||
434 | static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 4); | ||
435 | static SENSOR_DEVICE_ATTR(pwm6, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 5); | ||
436 | |||
437 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
438 | get_pwm_enable, set_pwm_enable, 0); | ||
439 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, | ||
440 | get_pwm_enable, set_pwm_enable, 1); | ||
441 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, | ||
442 | get_pwm_enable, set_pwm_enable, 2); | ||
443 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, | ||
444 | get_pwm_enable, set_pwm_enable, 3); | ||
445 | static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, | ||
446 | get_pwm_enable, set_pwm_enable, 4); | ||
447 | static SENSOR_DEVICE_ATTR(pwm6_enable, S_IWUSR | S_IRUGO, | ||
448 | get_pwm_enable, set_pwm_enable, 5); | ||
449 | |||
450 | static struct attribute *max31790_attrs[] = { | ||
451 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
452 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
453 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
454 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
455 | &sensor_dev_attr_fan5_input.dev_attr.attr, | ||
456 | &sensor_dev_attr_fan6_input.dev_attr.attr, | ||
457 | |||
458 | &sensor_dev_attr_fan1_fault.dev_attr.attr, | ||
459 | &sensor_dev_attr_fan2_fault.dev_attr.attr, | ||
460 | &sensor_dev_attr_fan3_fault.dev_attr.attr, | ||
461 | &sensor_dev_attr_fan4_fault.dev_attr.attr, | ||
462 | &sensor_dev_attr_fan5_fault.dev_attr.attr, | ||
463 | &sensor_dev_attr_fan6_fault.dev_attr.attr, | ||
464 | |||
465 | &sensor_dev_attr_fan7_input.dev_attr.attr, | ||
466 | &sensor_dev_attr_fan8_input.dev_attr.attr, | ||
467 | &sensor_dev_attr_fan9_input.dev_attr.attr, | ||
468 | &sensor_dev_attr_fan10_input.dev_attr.attr, | ||
469 | &sensor_dev_attr_fan11_input.dev_attr.attr, | ||
470 | &sensor_dev_attr_fan12_input.dev_attr.attr, | ||
471 | |||
472 | &sensor_dev_attr_fan7_fault.dev_attr.attr, | ||
473 | &sensor_dev_attr_fan8_fault.dev_attr.attr, | ||
474 | &sensor_dev_attr_fan9_fault.dev_attr.attr, | ||
475 | &sensor_dev_attr_fan10_fault.dev_attr.attr, | ||
476 | &sensor_dev_attr_fan11_fault.dev_attr.attr, | ||
477 | &sensor_dev_attr_fan12_fault.dev_attr.attr, | ||
478 | |||
479 | &sensor_dev_attr_fan1_target.dev_attr.attr, | ||
480 | &sensor_dev_attr_fan2_target.dev_attr.attr, | ||
481 | &sensor_dev_attr_fan3_target.dev_attr.attr, | ||
482 | &sensor_dev_attr_fan4_target.dev_attr.attr, | ||
483 | &sensor_dev_attr_fan5_target.dev_attr.attr, | ||
484 | &sensor_dev_attr_fan6_target.dev_attr.attr, | ||
485 | |||
486 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
487 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
488 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
489 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
490 | &sensor_dev_attr_pwm5.dev_attr.attr, | ||
491 | &sensor_dev_attr_pwm6.dev_attr.attr, | ||
492 | |||
493 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
494 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
495 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
496 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
497 | &sensor_dev_attr_pwm5_enable.dev_attr.attr, | ||
498 | &sensor_dev_attr_pwm6_enable.dev_attr.attr, | ||
499 | NULL | ||
500 | }; | 415 | }; |
501 | 416 | ||
502 | static umode_t max31790_attrs_visible(struct kobject *kobj, | 417 | static const struct hwmon_channel_info max31790_fan = { |
503 | struct attribute *a, int n) | 418 | .type = hwmon_fan, |
504 | { | 419 | .config = max31790_fan_config, |
505 | struct device *dev = container_of(kobj, struct device, kobj); | 420 | }; |
506 | struct max31790_data *data = dev_get_drvdata(dev); | ||
507 | struct device_attribute *devattr = | ||
508 | container_of(a, struct device_attribute, attr); | ||
509 | int index = to_sensor_dev_attr(devattr)->index % NR_CHANNEL; | ||
510 | u8 fan_config; | ||
511 | 421 | ||
512 | fan_config = data->fan_config[index]; | 422 | static const u32 max31790_pwm_config[] = { |
423 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
424 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
425 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
426 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
427 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
428 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
429 | 0 | ||
430 | }; | ||
513 | 431 | ||
514 | if (n >= NR_CHANNEL * 2 && n < NR_CHANNEL * 4 && | 432 | static const struct hwmon_channel_info max31790_pwm = { |
515 | !(fan_config & MAX31790_FAN_CFG_TACH_INPUT)) | 433 | .type = hwmon_pwm, |
516 | return 0; | 434 | .config = max31790_pwm_config, |
517 | if (n >= NR_CHANNEL * 4 && (fan_config & MAX31790_FAN_CFG_TACH_INPUT)) | 435 | }; |
518 | return 0; | ||
519 | 436 | ||
520 | return a->mode; | 437 | static const struct hwmon_channel_info *max31790_info[] = { |
521 | } | 438 | &max31790_fan, |
439 | &max31790_pwm, | ||
440 | NULL | ||
441 | }; | ||
442 | |||
443 | static const struct hwmon_ops max31790_hwmon_ops = { | ||
444 | .is_visible = max31790_is_visible, | ||
445 | .read = max31790_read, | ||
446 | .write = max31790_write, | ||
447 | }; | ||
522 | 448 | ||
523 | static const struct attribute_group max31790_group = { | 449 | static const struct hwmon_chip_info max31790_chip_info = { |
524 | .attrs = max31790_attrs, | 450 | .ops = &max31790_hwmon_ops, |
525 | .is_visible = max31790_attrs_visible, | 451 | .info = max31790_info, |
526 | }; | 452 | }; |
527 | __ATTRIBUTE_GROUPS(max31790); | ||
528 | 453 | ||
529 | static int max31790_init_client(struct i2c_client *client, | 454 | static int max31790_init_client(struct i2c_client *client, |
530 | struct max31790_data *data) | 455 | struct max31790_data *data) |
@@ -575,8 +500,10 @@ static int max31790_probe(struct i2c_client *client, | |||
575 | if (err) | 500 | if (err) |
576 | return err; | 501 | return err; |
577 | 502 | ||
578 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, | 503 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
579 | client->name, data, max31790_groups); | 504 | data, |
505 | &max31790_chip_info, | ||
506 | NULL); | ||
580 | 507 | ||
581 | return PTR_ERR_OR_ZERO(hwmon_dev); | 508 | return PTR_ERR_OR_ZERO(hwmon_dev); |
582 | } | 509 | } |
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 162a520f4bd6..a993b44ed538 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/hwmon.h> | 39 | #include <linux/hwmon.h> |
40 | #include <linux/hwmon-sysfs.h> | 40 | #include <linux/hwmon-sysfs.h> |
41 | #include <linux/err.h> | 41 | #include <linux/err.h> |
42 | #include <linux/of_device.h> | ||
42 | 43 | ||
43 | /* | 44 | /* |
44 | * Insmod parameters | 45 | * Insmod parameters |
@@ -48,7 +49,7 @@ | |||
48 | static int fan_voltage; | 49 | static int fan_voltage; |
49 | /* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */ | 50 | /* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */ |
50 | static int prescaler; | 51 | static int prescaler; |
51 | /* clock: The clock frequency of the chip the driver should assume */ | 52 | /* clock: The clock frequency of the chip (max6651 can be clocked externally) */ |
52 | static int clock = 254000; | 53 | static int clock = 254000; |
53 | 54 | ||
54 | module_param(fan_voltage, int, S_IRUGO); | 55 | module_param(fan_voltage, int, S_IRUGO); |
@@ -133,6 +134,19 @@ static const u8 tach_reg[] = { | |||
133 | MAX6650_REG_TACH3, | 134 | MAX6650_REG_TACH3, |
134 | }; | 135 | }; |
135 | 136 | ||
137 | static const struct of_device_id max6650_dt_match[] = { | ||
138 | { | ||
139 | .compatible = "maxim,max6650", | ||
140 | .data = (void *)1 | ||
141 | }, | ||
142 | { | ||
143 | .compatible = "maxim,max6651", | ||
144 | .data = (void *)4 | ||
145 | }, | ||
146 | { }, | ||
147 | }; | ||
148 | MODULE_DEVICE_TABLE(of, max6650_dt_match); | ||
149 | |||
136 | static struct max6650_data *max6650_update_device(struct device *dev) | 150 | static struct max6650_data *max6650_update_device(struct device *dev) |
137 | { | 151 | { |
138 | struct max6650_data *data = dev_get_drvdata(dev); | 152 | struct max6650_data *data = dev_get_drvdata(dev); |
@@ -171,6 +185,30 @@ static struct max6650_data *max6650_update_device(struct device *dev) | |||
171 | return data; | 185 | return data; |
172 | } | 186 | } |
173 | 187 | ||
188 | /* | ||
189 | * Change the operating mode of the chip (if needed). | ||
190 | * mode is one of the MAX6650_CFG_MODE_* values. | ||
191 | */ | ||
192 | static int max6650_set_operating_mode(struct max6650_data *data, u8 mode) | ||
193 | { | ||
194 | int result; | ||
195 | u8 config = data->config; | ||
196 | |||
197 | if (mode == (config & MAX6650_CFG_MODE_MASK)) | ||
198 | return 0; | ||
199 | |||
200 | config = (config & ~MAX6650_CFG_MODE_MASK) | mode; | ||
201 | |||
202 | result = i2c_smbus_write_byte_data(data->client, MAX6650_REG_CONFIG, | ||
203 | config); | ||
204 | if (result < 0) | ||
205 | return result; | ||
206 | |||
207 | data->config = config; | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
174 | static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, | 212 | static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, |
175 | char *buf) | 213 | char *buf) |
176 | { | 214 | { |
@@ -252,18 +290,12 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr, | |||
252 | return sprintf(buf, "%d\n", rpm); | 290 | return sprintf(buf, "%d\n", rpm); |
253 | } | 291 | } |
254 | 292 | ||
255 | static ssize_t set_target(struct device *dev, struct device_attribute *devattr, | 293 | static int max6650_set_target(struct max6650_data *data, unsigned long rpm) |
256 | const char *buf, size_t count) | ||
257 | { | 294 | { |
258 | struct max6650_data *data = dev_get_drvdata(dev); | ||
259 | struct i2c_client *client = data->client; | ||
260 | int kscale, ktach; | 295 | int kscale, ktach; |
261 | unsigned long rpm; | ||
262 | int err; | ||
263 | 296 | ||
264 | err = kstrtoul(buf, 10, &rpm); | 297 | if (rpm == 0) |
265 | if (err) | 298 | return max6650_set_operating_mode(data, MAX6650_CFG_MODE_OFF); |
266 | return err; | ||
267 | 299 | ||
268 | rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX); | 300 | rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX); |
269 | 301 | ||
@@ -274,8 +306,6 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr, | |||
274 | * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 | 306 | * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 |
275 | */ | 307 | */ |
276 | 308 | ||
277 | mutex_lock(&data->update_lock); | ||
278 | |||
279 | kscale = DIV_FROM_REG(data->config); | 309 | kscale = DIV_FROM_REG(data->config); |
280 | ktach = ((clock * kscale) / (256 * rpm / 60)) - 1; | 310 | ktach = ((clock * kscale) / (256 * rpm / 60)) - 1; |
281 | if (ktach < 0) | 311 | if (ktach < 0) |
@@ -284,10 +314,30 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr, | |||
284 | ktach = 255; | 314 | ktach = 255; |
285 | data->speed = ktach; | 315 | data->speed = ktach; |
286 | 316 | ||
287 | i2c_smbus_write_byte_data(client, MAX6650_REG_SPEED, data->speed); | 317 | return i2c_smbus_write_byte_data(data->client, MAX6650_REG_SPEED, |
318 | data->speed); | ||
319 | } | ||
320 | |||
321 | static ssize_t set_target(struct device *dev, struct device_attribute *devattr, | ||
322 | const char *buf, size_t count) | ||
323 | { | ||
324 | struct max6650_data *data = dev_get_drvdata(dev); | ||
325 | unsigned long rpm; | ||
326 | int err; | ||
327 | |||
328 | err = kstrtoul(buf, 10, &rpm); | ||
329 | if (err) | ||
330 | return err; | ||
331 | |||
332 | mutex_lock(&data->update_lock); | ||
333 | |||
334 | err = max6650_set_target(data, rpm); | ||
288 | 335 | ||
289 | mutex_unlock(&data->update_lock); | 336 | mutex_unlock(&data->update_lock); |
290 | 337 | ||
338 | if (err < 0) | ||
339 | return err; | ||
340 | |||
291 | return count; | 341 | return count; |
292 | } | 342 | } |
293 | 343 | ||
@@ -341,12 +391,11 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
341 | data->dac = 180 - (180 * pwm)/255; | 391 | data->dac = 180 - (180 * pwm)/255; |
342 | else | 392 | else |
343 | data->dac = 76 - (76 * pwm)/255; | 393 | data->dac = 76 - (76 * pwm)/255; |
344 | 394 | err = i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac); | |
345 | i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac); | ||
346 | 395 | ||
347 | mutex_unlock(&data->update_lock); | 396 | mutex_unlock(&data->update_lock); |
348 | 397 | ||
349 | return count; | 398 | return err < 0 ? err : count; |
350 | } | 399 | } |
351 | 400 | ||
352 | /* | 401 | /* |
@@ -355,14 +404,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
355 | * 0 = Fan always on | 404 | * 0 = Fan always on |
356 | * 1 = Open loop, Voltage is set according to speed, not regulated. | 405 | * 1 = Open loop, Voltage is set according to speed, not regulated. |
357 | * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer | 406 | * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer |
407 | * 3 = Fan off | ||
358 | */ | 408 | */ |
359 | |||
360 | static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, | 409 | static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, |
361 | char *buf) | 410 | char *buf) |
362 | { | 411 | { |
363 | struct max6650_data *data = max6650_update_device(dev); | 412 | struct max6650_data *data = max6650_update_device(dev); |
364 | int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4; | 413 | int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4; |
365 | int sysfs_modes[4] = {0, 1, 2, 1}; | 414 | int sysfs_modes[4] = {0, 3, 2, 1}; |
366 | 415 | ||
367 | return sprintf(buf, "%d\n", sysfs_modes[mode]); | 416 | return sprintf(buf, "%d\n", sysfs_modes[mode]); |
368 | } | 417 | } |
@@ -371,25 +420,25 @@ static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, | |||
371 | const char *buf, size_t count) | 420 | const char *buf, size_t count) |
372 | { | 421 | { |
373 | struct max6650_data *data = dev_get_drvdata(dev); | 422 | struct max6650_data *data = dev_get_drvdata(dev); |
374 | struct i2c_client *client = data->client; | ||
375 | int max6650_modes[3] = {0, 3, 2}; | ||
376 | unsigned long mode; | 423 | unsigned long mode; |
377 | int err; | 424 | int err; |
425 | const u8 max6650_modes[] = { | ||
426 | MAX6650_CFG_MODE_ON, | ||
427 | MAX6650_CFG_MODE_OPEN_LOOP, | ||
428 | MAX6650_CFG_MODE_CLOSED_LOOP, | ||
429 | MAX6650_CFG_MODE_OFF, | ||
430 | }; | ||
378 | 431 | ||
379 | err = kstrtoul(buf, 10, &mode); | 432 | err = kstrtoul(buf, 10, &mode); |
380 | if (err) | 433 | if (err) |
381 | return err; | 434 | return err; |
382 | 435 | ||
383 | if (mode > 2) | 436 | if (mode >= ARRAY_SIZE(max6650_modes)) |
384 | return -EINVAL; | 437 | return -EINVAL; |
385 | 438 | ||
386 | mutex_lock(&data->update_lock); | 439 | mutex_lock(&data->update_lock); |
387 | 440 | ||
388 | data->config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); | 441 | max6650_set_operating_mode(data, max6650_modes[mode]); |
389 | data->config = (data->config & ~MAX6650_CFG_MODE_MASK) | ||
390 | | (max6650_modes[mode] << 4); | ||
391 | |||
392 | i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, data->config); | ||
393 | 442 | ||
394 | mutex_unlock(&data->update_lock); | 443 | mutex_unlock(&data->update_lock); |
395 | 444 | ||
@@ -566,6 +615,18 @@ static int max6650_init_client(struct max6650_data *data, | |||
566 | struct device *dev = &client->dev; | 615 | struct device *dev = &client->dev; |
567 | int config; | 616 | int config; |
568 | int err = -EIO; | 617 | int err = -EIO; |
618 | u32 voltage; | ||
619 | u32 prescale; | ||
620 | u32 target_rpm; | ||
621 | |||
622 | if (of_property_read_u32(dev->of_node, "maxim,fan-microvolt", | ||
623 | &voltage)) | ||
624 | voltage = fan_voltage; | ||
625 | else | ||
626 | voltage /= 1000000; /* Microvolts to volts */ | ||
627 | if (of_property_read_u32(dev->of_node, "maxim,fan-prescale", | ||
628 | &prescale)) | ||
629 | prescale = prescaler; | ||
569 | 630 | ||
570 | config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); | 631 | config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); |
571 | 632 | ||
@@ -574,7 +635,7 @@ static int max6650_init_client(struct max6650_data *data, | |||
574 | return err; | 635 | return err; |
575 | } | 636 | } |
576 | 637 | ||
577 | switch (fan_voltage) { | 638 | switch (voltage) { |
578 | case 0: | 639 | case 0: |
579 | break; | 640 | break; |
580 | case 5: | 641 | case 5: |
@@ -584,14 +645,10 @@ static int max6650_init_client(struct max6650_data *data, | |||
584 | config |= MAX6650_CFG_V12; | 645 | config |= MAX6650_CFG_V12; |
585 | break; | 646 | break; |
586 | default: | 647 | default: |
587 | dev_err(dev, "illegal value for fan_voltage (%d)\n", | 648 | dev_err(dev, "illegal value for fan_voltage (%d)\n", voltage); |
588 | fan_voltage); | ||
589 | } | 649 | } |
590 | 650 | ||
591 | dev_info(dev, "Fan voltage is set to %dV.\n", | 651 | switch (prescale) { |
592 | (config & MAX6650_CFG_V12) ? 12 : 5); | ||
593 | |||
594 | switch (prescaler) { | ||
595 | case 0: | 652 | case 0: |
596 | break; | 653 | break; |
597 | case 1: | 654 | case 1: |
@@ -614,28 +671,13 @@ static int max6650_init_client(struct max6650_data *data, | |||
614 | | MAX6650_CFG_PRESCALER_16; | 671 | | MAX6650_CFG_PRESCALER_16; |
615 | break; | 672 | break; |
616 | default: | 673 | default: |
617 | dev_err(dev, "illegal value for prescaler (%d)\n", prescaler); | 674 | dev_err(dev, "illegal value for prescaler (%d)\n", prescale); |
618 | } | 675 | } |
619 | 676 | ||
620 | dev_info(dev, "Prescaler is set to %d.\n", | 677 | dev_info(dev, "Fan voltage: %dV, prescaler: %d.\n", |
678 | (config & MAX6650_CFG_V12) ? 12 : 5, | ||
621 | 1 << (config & MAX6650_CFG_PRESCALER_MASK)); | 679 | 1 << (config & MAX6650_CFG_PRESCALER_MASK)); |
622 | 680 | ||
623 | /* | ||
624 | * If mode is set to "full off", we change it to "open loop" and | ||
625 | * set DAC to 255, which has the same effect. We do this because | ||
626 | * there's no "full off" mode defined in hwmon specifications. | ||
627 | */ | ||
628 | |||
629 | if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) { | ||
630 | dev_dbg(dev, "Change mode to open loop, full off.\n"); | ||
631 | config = (config & ~MAX6650_CFG_MODE_MASK) | ||
632 | | MAX6650_CFG_MODE_OPEN_LOOP; | ||
633 | if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) { | ||
634 | dev_err(dev, "DAC write error, aborting.\n"); | ||
635 | return err; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) { | 681 | if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) { |
640 | dev_err(dev, "Config write error, aborting.\n"); | 682 | dev_err(dev, "Config write error, aborting.\n"); |
641 | return err; | 683 | return err; |
@@ -644,6 +686,12 @@ static int max6650_init_client(struct max6650_data *data, | |||
644 | data->config = config; | 686 | data->config = config; |
645 | data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT); | 687 | data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT); |
646 | 688 | ||
689 | if (!of_property_read_u32(client->dev.of_node, "maxim,fan-target-rpm", | ||
690 | &target_rpm)) { | ||
691 | max6650_set_target(data, target_rpm); | ||
692 | max6650_set_operating_mode(data, MAX6650_CFG_MODE_CLOSED_LOOP); | ||
693 | } | ||
694 | |||
647 | return 0; | 695 | return 0; |
648 | } | 696 | } |
649 | 697 | ||
@@ -651,6 +699,8 @@ static int max6650_probe(struct i2c_client *client, | |||
651 | const struct i2c_device_id *id) | 699 | const struct i2c_device_id *id) |
652 | { | 700 | { |
653 | struct device *dev = &client->dev; | 701 | struct device *dev = &client->dev; |
702 | const struct of_device_id *of_id = | ||
703 | of_match_device(of_match_ptr(max6650_dt_match), dev); | ||
654 | struct max6650_data *data; | 704 | struct max6650_data *data; |
655 | struct device *hwmon_dev; | 705 | struct device *hwmon_dev; |
656 | int err; | 706 | int err; |
@@ -661,7 +711,7 @@ static int max6650_probe(struct i2c_client *client, | |||
661 | 711 | ||
662 | data->client = client; | 712 | data->client = client; |
663 | mutex_init(&data->update_lock); | 713 | mutex_init(&data->update_lock); |
664 | data->nr_fans = id->driver_data; | 714 | data->nr_fans = of_id ? (int)(uintptr_t)of_id->data : id->driver_data; |
665 | 715 | ||
666 | /* | 716 | /* |
667 | * Initialize the max6650 chip | 717 | * Initialize the max6650 chip |
@@ -691,6 +741,7 @@ MODULE_DEVICE_TABLE(i2c, max6650_id); | |||
691 | static struct i2c_driver max6650_driver = { | 741 | static struct i2c_driver max6650_driver = { |
692 | .driver = { | 742 | .driver = { |
693 | .name = "max6650", | 743 | .name = "max6650", |
744 | .of_match_table = of_match_ptr(max6650_dt_match), | ||
694 | }, | 745 | }, |
695 | .probe = max6650_probe, | 746 | .probe = max6650_probe, |
696 | .id_table = max6650_id, | 747 | .id_table = max6650_id, |
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index d087a8e00cf5..ce75dd4db7eb 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -195,6 +195,8 @@ superio_exit(int ioreg) | |||
195 | 195 | ||
196 | #define NUM_FAN 6 | 196 | #define NUM_FAN 6 |
197 | 197 | ||
198 | #define TEMP_SOURCE_VIRTUAL 0x1f | ||
199 | |||
198 | /* Common and NCT6775 specific data */ | 200 | /* Common and NCT6775 specific data */ |
199 | 201 | ||
200 | /* Voltage min/max registers for nr=7..14 are in bank 5 */ | 202 | /* Voltage min/max registers for nr=7..14 are in bank 5 */ |
@@ -3940,7 +3942,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3940 | continue; | 3942 | continue; |
3941 | 3943 | ||
3942 | src = nct6775_read_value(data, data->REG_TEMP_SEL[i]) & 0x1f; | 3944 | src = nct6775_read_value(data, data->REG_TEMP_SEL[i]) & 0x1f; |
3943 | if (!src || (mask & (1 << src))) | 3945 | if (!src) |
3944 | continue; | 3946 | continue; |
3945 | 3947 | ||
3946 | if (src >= data->temp_label_num || | 3948 | if (src >= data->temp_label_num || |
@@ -3952,7 +3954,16 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3952 | continue; | 3954 | continue; |
3953 | } | 3955 | } |
3954 | 3956 | ||
3955 | mask |= 1 << src; | 3957 | /* |
3958 | * For virtual temperature sources, the 'virtual' temperature | ||
3959 | * for each fan reflects a different temperature, and there | ||
3960 | * are no duplicates. | ||
3961 | */ | ||
3962 | if (src != TEMP_SOURCE_VIRTUAL) { | ||
3963 | if (mask & (1 << src)) | ||
3964 | continue; | ||
3965 | mask |= 1 << src; | ||
3966 | } | ||
3956 | 3967 | ||
3957 | /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */ | 3968 | /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */ |
3958 | if (src <= data->temp_fixed_num) { | 3969 | if (src <= data->temp_fixed_num) { |
@@ -4232,11 +4243,11 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) | |||
4232 | if (err) | 4243 | if (err) |
4233 | return err; | 4244 | return err; |
4234 | 4245 | ||
4235 | if (force_id) | 4246 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | |
4247 | superio_inb(sioaddr, SIO_REG_DEVID + 1); | ||
4248 | if (force_id && val != 0xffff) | ||
4236 | val = force_id; | 4249 | val = force_id; |
4237 | else | 4250 | |
4238 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | ||
4239 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); | ||
4240 | switch (val & SIO_ID_MASK) { | 4251 | switch (val & SIO_ID_MASK) { |
4241 | case SIO_NCT6106_ID: | 4252 | case SIO_NCT6106_ID: |
4242 | sio_data->kind = nct6106; | 4253 | sio_data->kind = nct6106; |
diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c index 08ff89d222e5..95a68ab175c7 100644 --- a/drivers/hwmon/nct7904.c +++ b/drivers/hwmon/nct7904.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/hwmon.h> | 23 | #include <linux/hwmon.h> |
24 | #include <linux/hwmon-sysfs.h> | ||
25 | 24 | ||
26 | #define VENDOR_ID_REG 0x7A /* Any bank */ | 25 | #define VENDOR_ID_REG 0x7A /* Any bank */ |
27 | #define NUVOTON_ID 0x50 | 26 | #define NUVOTON_ID 0x50 |
@@ -153,341 +152,230 @@ static int nct7904_write_reg(struct nct7904_data *data, | |||
153 | return ret; | 152 | return ret; |
154 | } | 153 | } |
155 | 154 | ||
156 | /* FANIN ATTR */ | 155 | static int nct7904_read_fan(struct device *dev, u32 attr, int channel, |
157 | static ssize_t show_fan(struct device *dev, | 156 | long *val) |
158 | struct device_attribute *devattr, char *buf) | ||
159 | { | 157 | { |
160 | int index = to_sensor_dev_attr(devattr)->index; | ||
161 | struct nct7904_data *data = dev_get_drvdata(dev); | 158 | struct nct7904_data *data = dev_get_drvdata(dev); |
159 | unsigned int cnt, rpm; | ||
162 | int ret; | 160 | int ret; |
163 | unsigned cnt, rpm; | ||
164 | 161 | ||
165 | ret = nct7904_read_reg16(data, BANK_0, FANIN1_HV_REG + index * 2); | 162 | switch(attr) { |
166 | if (ret < 0) | 163 | case hwmon_fan_input: |
167 | return ret; | 164 | ret = nct7904_read_reg16(data, BANK_0, |
168 | cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); | 165 | FANIN1_HV_REG + channel * 2); |
169 | if (cnt == 0x1fff) | 166 | if (ret < 0) |
170 | rpm = 0; | 167 | return ret; |
171 | else | 168 | cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); |
172 | rpm = 1350000 / cnt; | 169 | if (cnt == 0x1fff) |
173 | return sprintf(buf, "%u\n", rpm); | 170 | rpm = 0; |
171 | else | ||
172 | rpm = 1350000 / cnt; | ||
173 | *val = rpm; | ||
174 | return 0; | ||
175 | default: | ||
176 | return -EOPNOTSUPP; | ||
177 | } | ||
174 | } | 178 | } |
175 | 179 | ||
176 | static umode_t nct7904_fanin_is_visible(struct kobject *kobj, | 180 | static umode_t nct7904_fan_is_visible(const void *_data, u32 attr, int channel) |
177 | struct attribute *a, int n) | ||
178 | { | 181 | { |
179 | struct device *dev = container_of(kobj, struct device, kobj); | 182 | const struct nct7904_data *data = _data; |
180 | struct nct7904_data *data = dev_get_drvdata(dev); | ||
181 | 183 | ||
182 | if (data->fanin_mask & (1 << n)) | 184 | if (attr == hwmon_fan_input && data->fanin_mask & (1 << channel)) |
183 | return a->mode; | 185 | return S_IRUGO; |
184 | return 0; | 186 | return 0; |
185 | } | 187 | } |
186 | 188 | ||
187 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | 189 | static u8 nct7904_chan_to_index[] = { |
188 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | 190 | 0, /* Not used */ |
189 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | 191 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
190 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | 192 | 18, 19, 20, 16 |
191 | static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); | ||
192 | static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); | ||
193 | static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); | ||
194 | static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); | ||
195 | static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_fan, NULL, 8); | ||
196 | static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_fan, NULL, 9); | ||
197 | static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_fan, NULL, 10); | ||
198 | static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, show_fan, NULL, 11); | ||
199 | |||
200 | static struct attribute *nct7904_fanin_attrs[] = { | ||
201 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
202 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
203 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
204 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
205 | &sensor_dev_attr_fan5_input.dev_attr.attr, | ||
206 | &sensor_dev_attr_fan6_input.dev_attr.attr, | ||
207 | &sensor_dev_attr_fan7_input.dev_attr.attr, | ||
208 | &sensor_dev_attr_fan8_input.dev_attr.attr, | ||
209 | &sensor_dev_attr_fan9_input.dev_attr.attr, | ||
210 | &sensor_dev_attr_fan10_input.dev_attr.attr, | ||
211 | &sensor_dev_attr_fan11_input.dev_attr.attr, | ||
212 | &sensor_dev_attr_fan12_input.dev_attr.attr, | ||
213 | NULL | ||
214 | }; | ||
215 | |||
216 | static const struct attribute_group nct7904_fanin_group = { | ||
217 | .attrs = nct7904_fanin_attrs, | ||
218 | .is_visible = nct7904_fanin_is_visible, | ||
219 | }; | 193 | }; |
220 | 194 | ||
221 | /* VSEN ATTR */ | 195 | static int nct7904_read_in(struct device *dev, u32 attr, int channel, |
222 | static ssize_t show_voltage(struct device *dev, | 196 | long *val) |
223 | struct device_attribute *devattr, char *buf) | ||
224 | { | 197 | { |
225 | int index = to_sensor_dev_attr(devattr)->index; | ||
226 | struct nct7904_data *data = dev_get_drvdata(dev); | 198 | struct nct7904_data *data = dev_get_drvdata(dev); |
227 | int ret; | 199 | int ret, volt, index; |
228 | int volt; | ||
229 | 200 | ||
230 | ret = nct7904_read_reg16(data, BANK_0, VSEN1_HV_REG + index * 2); | 201 | index = nct7904_chan_to_index[channel]; |
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | volt = ((ret & 0xff00) >> 5) | (ret & 0x7); | ||
234 | if (index < 14) | ||
235 | volt *= 2; /* 0.002V scale */ | ||
236 | else | ||
237 | volt *= 6; /* 0.006V scale */ | ||
238 | 202 | ||
239 | return sprintf(buf, "%d\n", volt); | 203 | switch(attr) { |
204 | case hwmon_in_input: | ||
205 | ret = nct7904_read_reg16(data, BANK_0, | ||
206 | VSEN1_HV_REG + index * 2); | ||
207 | if (ret < 0) | ||
208 | return ret; | ||
209 | volt = ((ret & 0xff00) >> 5) | (ret & 0x7); | ||
210 | if (index < 14) | ||
211 | volt *= 2; /* 0.002V scale */ | ||
212 | else | ||
213 | volt *= 6; /* 0.006V scale */ | ||
214 | *val = volt; | ||
215 | return 0; | ||
216 | default: | ||
217 | return -EOPNOTSUPP; | ||
218 | } | ||
240 | } | 219 | } |
241 | 220 | ||
242 | static ssize_t show_ltemp(struct device *dev, | 221 | static umode_t nct7904_in_is_visible(const void *_data, u32 attr, int channel) |
243 | struct device_attribute *devattr, char *buf) | ||
244 | { | 222 | { |
245 | struct nct7904_data *data = dev_get_drvdata(dev); | 223 | const struct nct7904_data *data = _data; |
246 | int ret; | 224 | int index = nct7904_chan_to_index[channel]; |
247 | int temp; | ||
248 | 225 | ||
249 | ret = nct7904_read_reg16(data, BANK_0, LTD_HV_REG); | 226 | if (channel > 0 && attr == hwmon_in_input && |
250 | if (ret < 0) | 227 | (data->vsen_mask & BIT(index))) |
251 | return ret; | 228 | return S_IRUGO; |
252 | temp = ((ret & 0xff00) >> 5) | (ret & 0x7); | ||
253 | temp = sign_extend32(temp, 10) * 125; | ||
254 | |||
255 | return sprintf(buf, "%d\n", temp); | ||
256 | } | ||
257 | |||
258 | static umode_t nct7904_vsen_is_visible(struct kobject *kobj, | ||
259 | struct attribute *a, int n) | ||
260 | { | ||
261 | struct device *dev = container_of(kobj, struct device, kobj); | ||
262 | struct nct7904_data *data = dev_get_drvdata(dev); | ||
263 | 229 | ||
264 | if (data->vsen_mask & (1 << n)) | ||
265 | return a->mode; | ||
266 | return 0; | 230 | return 0; |
267 | } | 231 | } |
268 | 232 | ||
269 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); | 233 | static int nct7904_read_temp(struct device *dev, u32 attr, int channel, |
270 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); | 234 | long *val) |
271 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); | ||
272 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); | ||
273 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); | ||
274 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); | ||
275 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); | ||
276 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); | ||
277 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); | ||
278 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); | ||
279 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); | ||
280 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); | ||
281 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); | ||
282 | static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_voltage, NULL, 13); | ||
283 | /* | ||
284 | * Next 3 voltage sensors have specific names in the Nuvoton doc | ||
285 | * (3VDD, VBAT, 3VSB) but we use vacant numbers for them. | ||
286 | */ | ||
287 | static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_voltage, NULL, 14); | ||
288 | static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_voltage, NULL, 15); | ||
289 | static SENSOR_DEVICE_ATTR(in20_input, S_IRUGO, show_voltage, NULL, 16); | ||
290 | /* This is not a voltage, but a local temperature sensor. */ | ||
291 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_ltemp, NULL, 0); | ||
292 | static SENSOR_DEVICE_ATTR(in17_input, S_IRUGO, show_voltage, NULL, 18); | ||
293 | static SENSOR_DEVICE_ATTR(in18_input, S_IRUGO, show_voltage, NULL, 19); | ||
294 | static SENSOR_DEVICE_ATTR(in19_input, S_IRUGO, show_voltage, NULL, 20); | ||
295 | |||
296 | static struct attribute *nct7904_vsen_attrs[] = { | ||
297 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
298 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
299 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
300 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
301 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
302 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
303 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
304 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
305 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
306 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
307 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
308 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
309 | &sensor_dev_attr_in13_input.dev_attr.attr, | ||
310 | &sensor_dev_attr_in14_input.dev_attr.attr, | ||
311 | &sensor_dev_attr_in15_input.dev_attr.attr, | ||
312 | &sensor_dev_attr_in16_input.dev_attr.attr, | ||
313 | &sensor_dev_attr_in20_input.dev_attr.attr, | ||
314 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
315 | &sensor_dev_attr_in17_input.dev_attr.attr, | ||
316 | &sensor_dev_attr_in18_input.dev_attr.attr, | ||
317 | &sensor_dev_attr_in19_input.dev_attr.attr, | ||
318 | NULL | ||
319 | }; | ||
320 | |||
321 | static const struct attribute_group nct7904_vsen_group = { | ||
322 | .attrs = nct7904_vsen_attrs, | ||
323 | .is_visible = nct7904_vsen_is_visible, | ||
324 | }; | ||
325 | |||
326 | /* CPU_TEMP ATTR */ | ||
327 | static ssize_t show_tcpu(struct device *dev, | ||
328 | struct device_attribute *devattr, char *buf) | ||
329 | { | 235 | { |
330 | int index = to_sensor_dev_attr(devattr)->index; | ||
331 | struct nct7904_data *data = dev_get_drvdata(dev); | 236 | struct nct7904_data *data = dev_get_drvdata(dev); |
332 | int ret; | 237 | int ret, temp; |
333 | int temp; | 238 | |
334 | 239 | switch(attr) { | |
335 | ret = nct7904_read_reg16(data, BANK_0, T_CPU1_HV_REG + index * 2); | 240 | case hwmon_temp_input: |
336 | if (ret < 0) | 241 | if (channel == 0) |
337 | return ret; | 242 | ret = nct7904_read_reg16(data, BANK_0, LTD_HV_REG); |
338 | 243 | else | |
339 | temp = ((ret & 0xff00) >> 5) | (ret & 0x7); | 244 | ret = nct7904_read_reg16(data, BANK_0, |
340 | temp = sign_extend32(temp, 10) * 125; | 245 | T_CPU1_HV_REG + (channel - 1) * 2); |
341 | return sprintf(buf, "%d\n", temp); | 246 | if (ret < 0) |
247 | return ret; | ||
248 | temp = ((ret & 0xff00) >> 5) | (ret & 0x7); | ||
249 | *val = sign_extend32(temp, 10) * 125; | ||
250 | return 0; | ||
251 | default: | ||
252 | return -EOPNOTSUPP; | ||
253 | } | ||
342 | } | 254 | } |
343 | 255 | ||
344 | static umode_t nct7904_tcpu_is_visible(struct kobject *kobj, | 256 | static umode_t nct7904_temp_is_visible(const void *_data, u32 attr, int channel) |
345 | struct attribute *a, int n) | ||
346 | { | 257 | { |
347 | struct device *dev = container_of(kobj, struct device, kobj); | 258 | const struct nct7904_data *data = _data; |
348 | struct nct7904_data *data = dev_get_drvdata(dev); | 259 | |
260 | if (attr == hwmon_temp_input) { | ||
261 | if (channel == 0) { | ||
262 | if (data->vsen_mask & BIT(17)) | ||
263 | return S_IRUGO; | ||
264 | } else { | ||
265 | if (data->tcpu_mask & BIT(channel - 1)) | ||
266 | return S_IRUGO; | ||
267 | } | ||
268 | } | ||
349 | 269 | ||
350 | if (data->tcpu_mask & (1 << n)) | ||
351 | return a->mode; | ||
352 | return 0; | 270 | return 0; |
353 | } | 271 | } |
354 | 272 | ||
355 | /* "temp1_input" reserved for local temp */ | 273 | static int nct7904_read_pwm(struct device *dev, u32 attr, int channel, |
356 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_tcpu, NULL, 0); | 274 | long *val) |
357 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_tcpu, NULL, 1); | ||
358 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_tcpu, NULL, 2); | ||
359 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_tcpu, NULL, 3); | ||
360 | static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_tcpu, NULL, 4); | ||
361 | static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_tcpu, NULL, 5); | ||
362 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_tcpu, NULL, 6); | ||
363 | static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_tcpu, NULL, 7); | ||
364 | |||
365 | static struct attribute *nct7904_tcpu_attrs[] = { | ||
366 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
367 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
368 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
369 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
370 | &sensor_dev_attr_temp6_input.dev_attr.attr, | ||
371 | &sensor_dev_attr_temp7_input.dev_attr.attr, | ||
372 | &sensor_dev_attr_temp8_input.dev_attr.attr, | ||
373 | &sensor_dev_attr_temp9_input.dev_attr.attr, | ||
374 | NULL | ||
375 | }; | ||
376 | |||
377 | static const struct attribute_group nct7904_tcpu_group = { | ||
378 | .attrs = nct7904_tcpu_attrs, | ||
379 | .is_visible = nct7904_tcpu_is_visible, | ||
380 | }; | ||
381 | |||
382 | /* PWM ATTR */ | ||
383 | static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, | ||
384 | const char *buf, size_t count) | ||
385 | { | 275 | { |
386 | int index = to_sensor_dev_attr(devattr)->index; | ||
387 | struct nct7904_data *data = dev_get_drvdata(dev); | 276 | struct nct7904_data *data = dev_get_drvdata(dev); |
388 | unsigned long val; | ||
389 | int ret; | 277 | int ret; |
390 | 278 | ||
391 | if (kstrtoul(buf, 10, &val) < 0) | 279 | switch(attr) { |
392 | return -EINVAL; | 280 | case hwmon_pwm_input: |
393 | if (val > 255) | 281 | ret = nct7904_read_reg(data, BANK_3, FANCTL1_OUT_REG + channel); |
394 | return -EINVAL; | 282 | if (ret < 0) |
395 | 283 | return ret; | |
396 | ret = nct7904_write_reg(data, BANK_3, FANCTL1_OUT_REG + index, val); | 284 | *val = ret; |
285 | return 0; | ||
286 | case hwmon_pwm_enable: | ||
287 | ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + channel); | ||
288 | if (ret < 0) | ||
289 | return ret; | ||
397 | 290 | ||
398 | return ret ? ret : count; | 291 | *val = ret ? 2 : 1; |
292 | return 0; | ||
293 | default: | ||
294 | return -EOPNOTSUPP; | ||
295 | } | ||
399 | } | 296 | } |
400 | 297 | ||
401 | static ssize_t show_pwm(struct device *dev, | 298 | static int nct7904_write_pwm(struct device *dev, u32 attr, int channel, |
402 | struct device_attribute *devattr, char *buf) | 299 | long val) |
403 | { | 300 | { |
404 | int index = to_sensor_dev_attr(devattr)->index; | ||
405 | struct nct7904_data *data = dev_get_drvdata(dev); | 301 | struct nct7904_data *data = dev_get_drvdata(dev); |
406 | int val; | 302 | int ret; |
407 | |||
408 | val = nct7904_read_reg(data, BANK_3, FANCTL1_OUT_REG + index); | ||
409 | if (val < 0) | ||
410 | return val; | ||
411 | 303 | ||
412 | return sprintf(buf, "%d\n", val); | 304 | switch(attr) { |
305 | case hwmon_pwm_input: | ||
306 | if (val < 0 || val > 255) | ||
307 | return -EINVAL; | ||
308 | ret = nct7904_write_reg(data, BANK_3, FANCTL1_OUT_REG + channel, | ||
309 | val); | ||
310 | return ret; | ||
311 | case hwmon_pwm_enable: | ||
312 | if (val < 1 || val > 2 || | ||
313 | (val == 2 && !data->fan_mode[channel])) | ||
314 | return -EINVAL; | ||
315 | ret = nct7904_write_reg(data, BANK_3, FANCTL1_FMR_REG + channel, | ||
316 | val == 2 ? data->fan_mode[channel] : 0); | ||
317 | return ret; | ||
318 | default: | ||
319 | return -EOPNOTSUPP; | ||
320 | } | ||
413 | } | 321 | } |
414 | 322 | ||
415 | static ssize_t store_enable(struct device *dev, | 323 | static umode_t nct7904_pwm_is_visible(const void *_data, u32 attr, int channel) |
416 | struct device_attribute *devattr, | ||
417 | const char *buf, size_t count) | ||
418 | { | 324 | { |
419 | int index = to_sensor_dev_attr(devattr)->index; | 325 | switch(attr) { |
420 | struct nct7904_data *data = dev_get_drvdata(dev); | 326 | case hwmon_pwm_input: |
421 | unsigned long val; | 327 | case hwmon_pwm_enable: |
422 | int ret; | 328 | return S_IRUGO | S_IWUSR; |
423 | 329 | default: | |
424 | if (kstrtoul(buf, 10, &val) < 0) | 330 | return 0; |
425 | return -EINVAL; | 331 | } |
426 | if (val < 1 || val > 2 || (val == 2 && !data->fan_mode[index])) | ||
427 | return -EINVAL; | ||
428 | |||
429 | ret = nct7904_write_reg(data, BANK_3, FANCTL1_FMR_REG + index, | ||
430 | val == 2 ? data->fan_mode[index] : 0); | ||
431 | |||
432 | return ret ? ret : count; | ||
433 | } | 332 | } |
434 | 333 | ||
435 | /* Return 1 for manual mode or 2 for SmartFan mode */ | 334 | static int nct7904_read(struct device *dev, enum hwmon_sensor_types type, |
436 | static ssize_t show_enable(struct device *dev, | 335 | u32 attr, int channel, long *val) |
437 | struct device_attribute *devattr, char *buf) | ||
438 | { | 336 | { |
439 | int index = to_sensor_dev_attr(devattr)->index; | 337 | switch (type) { |
440 | struct nct7904_data *data = dev_get_drvdata(dev); | 338 | case hwmon_in: |
441 | int val; | 339 | return nct7904_read_in(dev, attr, channel, val); |
442 | 340 | case hwmon_fan: | |
443 | val = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + index); | 341 | return nct7904_read_fan(dev, attr, channel, val); |
444 | if (val < 0) | 342 | case hwmon_pwm: |
445 | return val; | 343 | return nct7904_read_pwm(dev, attr, channel, val); |
446 | 344 | case hwmon_temp: | |
447 | return sprintf(buf, "%d\n", val ? 2 : 1); | 345 | return nct7904_read_temp(dev, attr, channel, val); |
346 | default: | ||
347 | return -EOPNOTSUPP; | ||
348 | } | ||
448 | } | 349 | } |
449 | 350 | ||
450 | /* 2 attributes per channel: pwm and mode */ | 351 | static int nct7904_write(struct device *dev, enum hwmon_sensor_types type, |
451 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, | 352 | u32 attr, int channel, long val) |
452 | show_pwm, store_pwm, 0); | 353 | { |
453 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, | 354 | switch (type) { |
454 | show_enable, store_enable, 0); | 355 | case hwmon_pwm: |
455 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, | 356 | return nct7904_write_pwm(dev, attr, channel, val); |
456 | show_pwm, store_pwm, 1); | 357 | default: |
457 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, | 358 | return -EOPNOTSUPP; |
458 | show_enable, store_enable, 1); | 359 | } |
459 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, | 360 | } |
460 | show_pwm, store_pwm, 2); | ||
461 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, | ||
462 | show_enable, store_enable, 2); | ||
463 | static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, | ||
464 | show_pwm, store_pwm, 3); | ||
465 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR, | ||
466 | show_enable, store_enable, 3); | ||
467 | |||
468 | static struct attribute *nct7904_fanctl_attrs[] = { | ||
469 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
470 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
471 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
472 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
473 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
474 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
475 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
476 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
477 | NULL | ||
478 | }; | ||
479 | |||
480 | static const struct attribute_group nct7904_fanctl_group = { | ||
481 | .attrs = nct7904_fanctl_attrs, | ||
482 | }; | ||
483 | 361 | ||
484 | static const struct attribute_group *nct7904_groups[] = { | 362 | static umode_t nct7904_is_visible(const void *data, |
485 | &nct7904_fanin_group, | 363 | enum hwmon_sensor_types type, |
486 | &nct7904_vsen_group, | 364 | u32 attr, int channel) |
487 | &nct7904_tcpu_group, | 365 | { |
488 | &nct7904_fanctl_group, | 366 | switch (type) { |
489 | NULL | 367 | case hwmon_in: |
490 | }; | 368 | return nct7904_in_is_visible(data, attr, channel); |
369 | case hwmon_fan: | ||
370 | return nct7904_fan_is_visible(data, attr, channel); | ||
371 | case hwmon_pwm: | ||
372 | return nct7904_pwm_is_visible(data, attr, channel); | ||
373 | case hwmon_temp: | ||
374 | return nct7904_temp_is_visible(data, attr, channel); | ||
375 | default: | ||
376 | return 0; | ||
377 | } | ||
378 | } | ||
491 | 379 | ||
492 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 380 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
493 | static int nct7904_detect(struct i2c_client *client, | 381 | static int nct7904_detect(struct i2c_client *client, |
@@ -512,6 +400,103 @@ static int nct7904_detect(struct i2c_client *client, | |||
512 | return 0; | 400 | return 0; |
513 | } | 401 | } |
514 | 402 | ||
403 | static const u32 nct7904_in_config[] = { | ||
404 | HWMON_I_INPUT, /* dummy, skipped in is_visible */ | ||
405 | HWMON_I_INPUT, | ||
406 | HWMON_I_INPUT, | ||
407 | HWMON_I_INPUT, | ||
408 | HWMON_I_INPUT, | ||
409 | HWMON_I_INPUT, | ||
410 | HWMON_I_INPUT, | ||
411 | HWMON_I_INPUT, | ||
412 | HWMON_I_INPUT, | ||
413 | HWMON_I_INPUT, | ||
414 | HWMON_I_INPUT, | ||
415 | HWMON_I_INPUT, | ||
416 | HWMON_I_INPUT, | ||
417 | HWMON_I_INPUT, | ||
418 | HWMON_I_INPUT, | ||
419 | HWMON_I_INPUT, | ||
420 | HWMON_I_INPUT, | ||
421 | HWMON_I_INPUT, | ||
422 | HWMON_I_INPUT, | ||
423 | HWMON_I_INPUT, | ||
424 | HWMON_I_INPUT, | ||
425 | 0 | ||
426 | }; | ||
427 | |||
428 | static const struct hwmon_channel_info nct7904_in = { | ||
429 | .type = hwmon_in, | ||
430 | .config = nct7904_in_config, | ||
431 | }; | ||
432 | |||
433 | static const u32 nct7904_fan_config[] = { | ||
434 | HWMON_F_INPUT, | ||
435 | HWMON_F_INPUT, | ||
436 | HWMON_F_INPUT, | ||
437 | HWMON_F_INPUT, | ||
438 | HWMON_F_INPUT, | ||
439 | HWMON_F_INPUT, | ||
440 | HWMON_F_INPUT, | ||
441 | HWMON_F_INPUT, | ||
442 | 0 | ||
443 | }; | ||
444 | |||
445 | static const struct hwmon_channel_info nct7904_fan = { | ||
446 | .type = hwmon_fan, | ||
447 | .config = nct7904_fan_config, | ||
448 | }; | ||
449 | |||
450 | static const u32 nct7904_pwm_config[] = { | ||
451 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
452 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
453 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
454 | HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | ||
455 | 0 | ||
456 | }; | ||
457 | |||
458 | static const struct hwmon_channel_info nct7904_pwm = { | ||
459 | .type = hwmon_pwm, | ||
460 | .config = nct7904_pwm_config, | ||
461 | }; | ||
462 | |||
463 | static const u32 nct7904_temp_config[] = { | ||
464 | HWMON_T_INPUT, | ||
465 | HWMON_T_INPUT, | ||
466 | HWMON_T_INPUT, | ||
467 | HWMON_T_INPUT, | ||
468 | HWMON_T_INPUT, | ||
469 | HWMON_T_INPUT, | ||
470 | HWMON_T_INPUT, | ||
471 | HWMON_T_INPUT, | ||
472 | HWMON_T_INPUT, | ||
473 | 0 | ||
474 | }; | ||
475 | |||
476 | static const struct hwmon_channel_info nct7904_temp = { | ||
477 | .type = hwmon_temp, | ||
478 | .config = nct7904_temp_config, | ||
479 | }; | ||
480 | |||
481 | static const struct hwmon_channel_info *nct7904_info[] = { | ||
482 | &nct7904_in, | ||
483 | &nct7904_fan, | ||
484 | &nct7904_pwm, | ||
485 | &nct7904_temp, | ||
486 | NULL | ||
487 | }; | ||
488 | |||
489 | static const struct hwmon_ops nct7904_hwmon_ops = { | ||
490 | .is_visible = nct7904_is_visible, | ||
491 | .read = nct7904_read, | ||
492 | .write = nct7904_write, | ||
493 | }; | ||
494 | |||
495 | static const struct hwmon_chip_info nct7904_chip_info = { | ||
496 | .ops = &nct7904_hwmon_ops, | ||
497 | .info = nct7904_info, | ||
498 | }; | ||
499 | |||
515 | static int nct7904_probe(struct i2c_client *client, | 500 | static int nct7904_probe(struct i2c_client *client, |
516 | const struct i2c_device_id *id) | 501 | const struct i2c_device_id *id) |
517 | { | 502 | { |
@@ -566,8 +551,8 @@ static int nct7904_probe(struct i2c_client *client, | |||
566 | } | 551 | } |
567 | 552 | ||
568 | hwmon_dev = | 553 | hwmon_dev = |
569 | devm_hwmon_device_register_with_groups(dev, client->name, data, | 554 | devm_hwmon_device_register_with_info(dev, client->name, data, |
570 | nct7904_groups); | 555 | &nct7904_chip_info, NULL); |
571 | return PTR_ERR_OR_ZERO(hwmon_dev); | 556 | return PTR_ERR_OR_ZERO(hwmon_dev); |
572 | } | 557 | } |
573 | 558 | ||
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 8ef7b713cb1a..c52d07c6b49f 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c | |||
@@ -253,12 +253,9 @@ static const struct ntc_compensation b57330v2103[] = { | |||
253 | }; | 253 | }; |
254 | 254 | ||
255 | struct ntc_data { | 255 | struct ntc_data { |
256 | struct device *hwmon_dev; | ||
257 | struct ntc_thermistor_platform_data *pdata; | 256 | struct ntc_thermistor_platform_data *pdata; |
258 | const struct ntc_compensation *comp; | 257 | const struct ntc_compensation *comp; |
259 | struct device *dev; | ||
260 | int n_comp; | 258 | int n_comp; |
261 | char name[PLATFORM_NAME_SIZE]; | ||
262 | }; | 259 | }; |
263 | 260 | ||
264 | #if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO) | 261 | #if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO) |
@@ -316,22 +313,22 @@ static const struct of_device_id ntc_match[] = { | |||
316 | MODULE_DEVICE_TABLE(of, ntc_match); | 313 | MODULE_DEVICE_TABLE(of, ntc_match); |
317 | 314 | ||
318 | static struct ntc_thermistor_platform_data * | 315 | static struct ntc_thermistor_platform_data * |
319 | ntc_thermistor_parse_dt(struct platform_device *pdev) | 316 | ntc_thermistor_parse_dt(struct device *dev) |
320 | { | 317 | { |
321 | struct iio_channel *chan; | 318 | struct iio_channel *chan; |
322 | enum iio_chan_type type; | 319 | enum iio_chan_type type; |
323 | struct device_node *np = pdev->dev.of_node; | 320 | struct device_node *np = dev->of_node; |
324 | struct ntc_thermistor_platform_data *pdata; | 321 | struct ntc_thermistor_platform_data *pdata; |
325 | int ret; | 322 | int ret; |
326 | 323 | ||
327 | if (!np) | 324 | if (!np) |
328 | return NULL; | 325 | return NULL; |
329 | 326 | ||
330 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 327 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
331 | if (!pdata) | 328 | if (!pdata) |
332 | return ERR_PTR(-ENOMEM); | 329 | return ERR_PTR(-ENOMEM); |
333 | 330 | ||
334 | chan = iio_channel_get(&pdev->dev, NULL); | 331 | chan = devm_iio_channel_get(dev, NULL); |
335 | if (IS_ERR(chan)) | 332 | if (IS_ERR(chan)) |
336 | return ERR_CAST(chan); | 333 | return ERR_CAST(chan); |
337 | 334 | ||
@@ -359,22 +356,15 @@ ntc_thermistor_parse_dt(struct platform_device *pdev) | |||
359 | 356 | ||
360 | return pdata; | 357 | return pdata; |
361 | } | 358 | } |
362 | static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) | ||
363 | { | ||
364 | if (pdata->chan) | ||
365 | iio_channel_release(pdata->chan); | ||
366 | } | ||
367 | #else | 359 | #else |
368 | static struct ntc_thermistor_platform_data * | 360 | static struct ntc_thermistor_platform_data * |
369 | ntc_thermistor_parse_dt(struct platform_device *pdev) | 361 | ntc_thermistor_parse_dt(struct device *dev) |
370 | { | 362 | { |
371 | return NULL; | 363 | return NULL; |
372 | } | 364 | } |
373 | 365 | ||
374 | #define ntc_match NULL | 366 | #define ntc_match NULL |
375 | 367 | ||
376 | static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) | ||
377 | { } | ||
378 | #endif | 368 | #endif |
379 | 369 | ||
380 | static inline u64 div64_u64_safe(u64 dividend, u64 divisor) | 370 | static inline u64 div64_u64_safe(u64 dividend, u64 divisor) |
@@ -516,9 +506,8 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data) | |||
516 | return -EINVAL; | 506 | return -EINVAL; |
517 | } | 507 | } |
518 | 508 | ||
519 | static int ntc_read_temp(void *dev, int *temp) | 509 | static int ntc_read_temp(void *data, int *temp) |
520 | { | 510 | { |
521 | struct ntc_data *data = dev_get_drvdata(dev); | ||
522 | int ohm; | 511 | int ohm; |
523 | 512 | ||
524 | ohm = ntc_thermistor_get_ohm(data); | 513 | ohm = ntc_thermistor_get_ohm(data); |
@@ -530,14 +519,6 @@ static int ntc_read_temp(void *dev, int *temp) | |||
530 | return 0; | 519 | return 0; |
531 | } | 520 | } |
532 | 521 | ||
533 | static ssize_t ntc_show_name(struct device *dev, | ||
534 | struct device_attribute *attr, char *buf) | ||
535 | { | ||
536 | struct ntc_data *data = dev_get_drvdata(dev); | ||
537 | |||
538 | return sprintf(buf, "%s\n", data->name); | ||
539 | } | ||
540 | |||
541 | static ssize_t ntc_show_type(struct device *dev, | 522 | static ssize_t ntc_show_type(struct device *dev, |
542 | struct device_attribute *attr, char *buf) | 523 | struct device_attribute *attr, char *buf) |
543 | { | 524 | { |
@@ -559,18 +540,13 @@ static ssize_t ntc_show_temp(struct device *dev, | |||
559 | 540 | ||
560 | static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0); | 541 | static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0); |
561 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ntc_show_temp, NULL, 0); | 542 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ntc_show_temp, NULL, 0); |
562 | static DEVICE_ATTR(name, S_IRUGO, ntc_show_name, NULL); | ||
563 | 543 | ||
564 | static struct attribute *ntc_attributes[] = { | 544 | static struct attribute *ntc_attrs[] = { |
565 | &dev_attr_name.attr, | ||
566 | &sensor_dev_attr_temp1_type.dev_attr.attr, | 545 | &sensor_dev_attr_temp1_type.dev_attr.attr, |
567 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 546 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
568 | NULL, | 547 | NULL, |
569 | }; | 548 | }; |
570 | 549 | ATTRIBUTE_GROUPS(ntc); | |
571 | static const struct attribute_group ntc_attr_group = { | ||
572 | .attrs = ntc_attributes, | ||
573 | }; | ||
574 | 550 | ||
575 | static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { | 551 | static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { |
576 | .get_temp = ntc_read_temp, | 552 | .get_temp = ntc_read_temp, |
@@ -579,33 +555,34 @@ static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { | |||
579 | static int ntc_thermistor_probe(struct platform_device *pdev) | 555 | static int ntc_thermistor_probe(struct platform_device *pdev) |
580 | { | 556 | { |
581 | struct thermal_zone_device *tz; | 557 | struct thermal_zone_device *tz; |
558 | struct device *dev = &pdev->dev; | ||
582 | const struct of_device_id *of_id = | 559 | const struct of_device_id *of_id = |
583 | of_match_device(of_match_ptr(ntc_match), &pdev->dev); | 560 | of_match_device(of_match_ptr(ntc_match), dev); |
584 | const struct platform_device_id *pdev_id; | 561 | const struct platform_device_id *pdev_id; |
585 | struct ntc_thermistor_platform_data *pdata; | 562 | struct ntc_thermistor_platform_data *pdata; |
563 | struct device *hwmon_dev; | ||
586 | struct ntc_data *data; | 564 | struct ntc_data *data; |
587 | int ret; | ||
588 | 565 | ||
589 | pdata = ntc_thermistor_parse_dt(pdev); | 566 | pdata = ntc_thermistor_parse_dt(dev); |
590 | if (IS_ERR(pdata)) | 567 | if (IS_ERR(pdata)) |
591 | return PTR_ERR(pdata); | 568 | return PTR_ERR(pdata); |
592 | else if (pdata == NULL) | 569 | else if (pdata == NULL) |
593 | pdata = dev_get_platdata(&pdev->dev); | 570 | pdata = dev_get_platdata(dev); |
594 | 571 | ||
595 | if (!pdata) { | 572 | if (!pdata) { |
596 | dev_err(&pdev->dev, "No platform init data supplied.\n"); | 573 | dev_err(dev, "No platform init data supplied.\n"); |
597 | return -ENODEV; | 574 | return -ENODEV; |
598 | } | 575 | } |
599 | 576 | ||
600 | /* Either one of the two is required. */ | 577 | /* Either one of the two is required. */ |
601 | if (!pdata->read_uv && !pdata->read_ohm) { | 578 | if (!pdata->read_uv && !pdata->read_ohm) { |
602 | dev_err(&pdev->dev, | 579 | dev_err(dev, |
603 | "Both read_uv and read_ohm missing. Need either one of the two.\n"); | 580 | "Both read_uv and read_ohm missing. Need either one of the two.\n"); |
604 | return -EINVAL; | 581 | return -EINVAL; |
605 | } | 582 | } |
606 | 583 | ||
607 | if (pdata->read_uv && pdata->read_ohm) { | 584 | if (pdata->read_uv && pdata->read_ohm) { |
608 | dev_warn(&pdev->dev, | 585 | dev_warn(dev, |
609 | "Only one of read_uv and read_ohm is needed; ignoring read_uv.\n"); | 586 | "Only one of read_uv and read_ohm is needed; ignoring read_uv.\n"); |
610 | pdata->read_uv = NULL; | 587 | pdata->read_uv = NULL; |
611 | } | 588 | } |
@@ -617,20 +594,17 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
617 | NTC_CONNECTED_POSITIVE) || | 594 | NTC_CONNECTED_POSITIVE) || |
618 | (pdata->connect != NTC_CONNECTED_POSITIVE && | 595 | (pdata->connect != NTC_CONNECTED_POSITIVE && |
619 | pdata->connect != NTC_CONNECTED_GROUND))) { | 596 | pdata->connect != NTC_CONNECTED_GROUND))) { |
620 | dev_err(&pdev->dev, | 597 | dev_err(dev, "Required data to use read_uv not supplied.\n"); |
621 | "Required data to use read_uv not supplied.\n"); | ||
622 | return -EINVAL; | 598 | return -EINVAL; |
623 | } | 599 | } |
624 | 600 | ||
625 | data = devm_kzalloc(&pdev->dev, sizeof(struct ntc_data), GFP_KERNEL); | 601 | data = devm_kzalloc(dev, sizeof(struct ntc_data), GFP_KERNEL); |
626 | if (!data) | 602 | if (!data) |
627 | return -ENOMEM; | 603 | return -ENOMEM; |
628 | 604 | ||
629 | pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); | 605 | pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); |
630 | 606 | ||
631 | data->dev = &pdev->dev; | ||
632 | data->pdata = pdata; | 607 | data->pdata = pdata; |
633 | strlcpy(data->name, pdev_id->name, sizeof(data->name)); | ||
634 | 608 | ||
635 | switch (pdev_id->driver_data) { | 609 | switch (pdev_id->driver_data) { |
636 | case TYPE_NCPXXWB473: | 610 | case TYPE_NCPXXWB473: |
@@ -654,49 +628,25 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
654 | data->n_comp = ARRAY_SIZE(ncpXXxh103); | 628 | data->n_comp = ARRAY_SIZE(ncpXXxh103); |
655 | break; | 629 | break; |
656 | default: | 630 | default: |
657 | dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", | 631 | dev_err(dev, "Unknown device type: %lu(%s)\n", |
658 | pdev_id->driver_data, pdev_id->name); | 632 | pdev_id->driver_data, pdev_id->name); |
659 | return -EINVAL; | 633 | return -EINVAL; |
660 | } | 634 | } |
661 | 635 | ||
662 | platform_set_drvdata(pdev, data); | 636 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, pdev_id->name, |
663 | 637 | data, ntc_groups); | |
664 | ret = sysfs_create_group(&data->dev->kobj, &ntc_attr_group); | 638 | if (IS_ERR(hwmon_dev)) { |
665 | if (ret) { | 639 | dev_err(dev, "unable to register as hwmon device.\n"); |
666 | dev_err(data->dev, "unable to create sysfs files\n"); | 640 | return PTR_ERR(hwmon_dev); |
667 | return ret; | ||
668 | } | ||
669 | |||
670 | data->hwmon_dev = hwmon_device_register(data->dev); | ||
671 | if (IS_ERR(data->hwmon_dev)) { | ||
672 | dev_err(data->dev, "unable to register as hwmon device.\n"); | ||
673 | ret = PTR_ERR(data->hwmon_dev); | ||
674 | goto err_after_sysfs; | ||
675 | } | 641 | } |
676 | 642 | ||
677 | dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n", | 643 | dev_info(dev, "Thermistor type: %s successfully probed.\n", |
678 | pdev_id->name); | 644 | pdev_id->name); |
679 | 645 | ||
680 | tz = devm_thermal_zone_of_sensor_register(data->dev, 0, data->dev, | 646 | tz = devm_thermal_zone_of_sensor_register(dev, 0, data, |
681 | &ntc_of_thermal_ops); | 647 | &ntc_of_thermal_ops); |
682 | if (IS_ERR(tz)) | 648 | if (IS_ERR(tz)) |
683 | dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); | 649 | dev_dbg(dev, "Failed to register to thermal fw.\n"); |
684 | |||
685 | return 0; | ||
686 | err_after_sysfs: | ||
687 | sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); | ||
688 | ntc_iio_channel_release(pdata); | ||
689 | return ret; | ||
690 | } | ||
691 | |||
692 | static int ntc_thermistor_remove(struct platform_device *pdev) | ||
693 | { | ||
694 | struct ntc_data *data = platform_get_drvdata(pdev); | ||
695 | struct ntc_thermistor_platform_data *pdata = data->pdata; | ||
696 | |||
697 | hwmon_device_unregister(data->hwmon_dev); | ||
698 | sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); | ||
699 | ntc_iio_channel_release(pdata); | ||
700 | 650 | ||
701 | return 0; | 651 | return 0; |
702 | } | 652 | } |
@@ -707,7 +657,6 @@ static struct platform_driver ntc_thermistor_driver = { | |||
707 | .of_match_table = of_match_ptr(ntc_match), | 657 | .of_match_table = of_match_ptr(ntc_match), |
708 | }, | 658 | }, |
709 | .probe = ntc_thermistor_probe, | 659 | .probe = ntc_thermistor_probe, |
710 | .remove = ntc_thermistor_remove, | ||
711 | .id_table = ntc_thermistor_id, | 660 | .id_table = ntc_thermistor_id, |
712 | }; | 661 | }; |
713 | 662 | ||
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 054d3d863802..cad1229b7e17 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -126,12 +126,12 @@ config SENSORS_TPS40422 | |||
126 | be called tps40422. | 126 | be called tps40422. |
127 | 127 | ||
128 | config SENSORS_UCD9000 | 128 | config SENSORS_UCD9000 |
129 | tristate "TI UCD90120, UCD90124, UCD9090, UCD90910" | 129 | tristate "TI UCD90120, UCD90124, UCD90160, UCD9090, UCD90910" |
130 | default n | 130 | default n |
131 | help | 131 | help |
132 | If you say yes here you get hardware monitoring support for TI | 132 | If you say yes here you get hardware monitoring support for TI |
133 | UCD90120, UCD90124, UCD9090, UCD90910 Sequencer and System Health | 133 | UCD90120, UCD90124, UCD90160, UCD9090, UCD90910, Sequencer and System |
134 | Controllers. | 134 | Health Controllers. |
135 | 135 | ||
136 | This driver can also be built as a module. If so, the module will | 136 | This driver can also be built as a module. If so, the module will |
137 | be called ucd9000. | 137 | be called ucd9000. |
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c index 0a74991a60f0..44ca8a94873d 100644 --- a/drivers/hwmon/pmbus/pmbus.c +++ b/drivers/hwmon/pmbus/pmbus.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/i2c/pmbus.h> | ||
28 | #include "pmbus.h" | 29 | #include "pmbus.h" |
29 | 30 | ||
30 | /* | 31 | /* |
@@ -167,14 +168,26 @@ static int pmbus_probe(struct i2c_client *client, | |||
167 | const struct i2c_device_id *id) | 168 | const struct i2c_device_id *id) |
168 | { | 169 | { |
169 | struct pmbus_driver_info *info; | 170 | struct pmbus_driver_info *info; |
171 | struct pmbus_platform_data *pdata = NULL; | ||
172 | struct device *dev = &client->dev; | ||
170 | 173 | ||
171 | info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), | 174 | info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); |
172 | GFP_KERNEL); | ||
173 | if (!info) | 175 | if (!info) |
174 | return -ENOMEM; | 176 | return -ENOMEM; |
175 | 177 | ||
178 | if (!strcmp(id->name, "dps460") || !strcmp(id->name, "dps800") || | ||
179 | !strcmp(id->name, "sgd009")) { | ||
180 | pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data), | ||
181 | GFP_KERNEL); | ||
182 | if (!pdata) | ||
183 | return -ENOMEM; | ||
184 | |||
185 | pdata->flags = PMBUS_SKIP_STATUS_CHECK; | ||
186 | } | ||
187 | |||
176 | info->pages = id->driver_data; | 188 | info->pages = id->driver_data; |
177 | info->identify = pmbus_identify; | 189 | info->identify = pmbus_identify; |
190 | dev->platform_data = pdata; | ||
178 | 191 | ||
179 | return pmbus_do_probe(client, id, info); | 192 | return pmbus_do_probe(client, id, info); |
180 | } | 193 | } |
@@ -186,6 +199,8 @@ static const struct i2c_device_id pmbus_id[] = { | |||
186 | {"adp4000", 1}, | 199 | {"adp4000", 1}, |
187 | {"bmr453", 1}, | 200 | {"bmr453", 1}, |
188 | {"bmr454", 1}, | 201 | {"bmr454", 1}, |
202 | {"dps460", 1}, | ||
203 | {"dps800", 1}, | ||
189 | {"mdt040", 1}, | 204 | {"mdt040", 1}, |
190 | {"ncp4200", 1}, | 205 | {"ncp4200", 1}, |
191 | {"ncp4208", 1}, | 206 | {"ncp4208", 1}, |
@@ -193,6 +208,7 @@ static const struct i2c_device_id pmbus_id[] = { | |||
193 | {"pdt006", 1}, | 208 | {"pdt006", 1}, |
194 | {"pdt012", 1}, | 209 | {"pdt012", 1}, |
195 | {"pmbus", 0}, | 210 | {"pmbus", 0}, |
211 | {"sgd009", 1}, | ||
196 | {"tps40400", 1}, | 212 | {"tps40400", 1}, |
197 | {"tps544b20", 1}, | 213 | {"tps544b20", 1}, |
198 | {"tps544b25", 1}, | 214 | {"tps544b25", 1}, |
diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c index fbb1479d3ad4..3e3aa950277f 100644 --- a/drivers/hwmon/pmbus/ucd9000.c +++ b/drivers/hwmon/pmbus/ucd9000.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/i2c/pmbus.h> | 28 | #include <linux/i2c/pmbus.h> |
29 | #include "pmbus.h" | 29 | #include "pmbus.h" |
30 | 30 | ||
31 | enum chips { ucd9000, ucd90120, ucd90124, ucd9090, ucd90910 }; | 31 | enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 }; |
32 | 32 | ||
33 | #define UCD9000_MONITOR_CONFIG 0xd5 | 33 | #define UCD9000_MONITOR_CONFIG 0xd5 |
34 | #define UCD9000_NUM_PAGES 0xd6 | 34 | #define UCD9000_NUM_PAGES 0xd6 |
@@ -112,6 +112,7 @@ static const struct i2c_device_id ucd9000_id[] = { | |||
112 | {"ucd9000", ucd9000}, | 112 | {"ucd9000", ucd9000}, |
113 | {"ucd90120", ucd90120}, | 113 | {"ucd90120", ucd90120}, |
114 | {"ucd90124", ucd90124}, | 114 | {"ucd90124", ucd90124}, |
115 | {"ucd90160", ucd90160}, | ||
115 | {"ucd9090", ucd9090}, | 116 | {"ucd9090", ucd9090}, |
116 | {"ucd90910", ucd90910}, | 117 | {"ucd90910", ucd90910}, |
117 | {} | 118 | {} |
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index 25b44e68926d..559a3dcd64d8 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c | |||
@@ -255,7 +255,6 @@ static const struct of_device_id scpi_of_match[] = { | |||
255 | static struct platform_driver scpi_hwmon_platdrv = { | 255 | static struct platform_driver scpi_hwmon_platdrv = { |
256 | .driver = { | 256 | .driver = { |
257 | .name = "scpi-hwmon", | 257 | .name = "scpi-hwmon", |
258 | .owner = THIS_MODULE, | ||
259 | .of_match_table = scpi_of_match, | 258 | .of_match_table = scpi_of_match, |
260 | }, | 259 | }, |
261 | .probe = scpi_hwmon_probe, | 260 | .probe = scpi_hwmon_probe, |
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 8479ac5eb853..36bba2a816a4 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/jiffies.h> | 26 | #include <linux/jiffies.h> |
27 | #include <linux/regmap.h> | 27 | #include <linux/regmap.h> |
28 | #include <linux/thermal.h> | ||
29 | #include <linux/of.h> | 28 | #include <linux/of.h> |
30 | 29 | ||
31 | #define DRIVER_NAME "tmp102" | 30 | #define DRIVER_NAME "tmp102" |
@@ -79,84 +78,113 @@ static inline u16 tmp102_mC_to_reg(int val) | |||
79 | return (val * 128) / 1000; | 78 | return (val * 128) / 1000; |
80 | } | 79 | } |
81 | 80 | ||
82 | static int tmp102_read_temp(void *dev, int *temp) | 81 | static int tmp102_read(struct device *dev, enum hwmon_sensor_types type, |
82 | u32 attr, int channel, long *temp) | ||
83 | { | 83 | { |
84 | struct tmp102 *tmp102 = dev_get_drvdata(dev); | 84 | struct tmp102 *tmp102 = dev_get_drvdata(dev); |
85 | unsigned int reg; | 85 | unsigned int regval; |
86 | int ret; | 86 | int err, reg; |
87 | 87 | ||
88 | if (time_before(jiffies, tmp102->ready_time)) { | 88 | switch (attr) { |
89 | dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__); | 89 | case hwmon_temp_input: |
90 | return -EAGAIN; | 90 | /* Is it too early to return a conversion ? */ |
91 | if (time_before(jiffies, tmp102->ready_time)) { | ||
92 | dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__); | ||
93 | return -EAGAIN; | ||
94 | } | ||
95 | reg = TMP102_TEMP_REG; | ||
96 | break; | ||
97 | case hwmon_temp_max_hyst: | ||
98 | reg = TMP102_TLOW_REG; | ||
99 | break; | ||
100 | case hwmon_temp_max: | ||
101 | reg = TMP102_THIGH_REG; | ||
102 | break; | ||
103 | default: | ||
104 | return -EOPNOTSUPP; | ||
91 | } | 105 | } |
92 | 106 | ||
93 | ret = regmap_read(tmp102->regmap, TMP102_TEMP_REG, ®); | 107 | err = regmap_read(tmp102->regmap, reg, ®val); |
94 | if (ret < 0) | 108 | if (err < 0) |
95 | return ret; | 109 | return err; |
96 | 110 | *temp = tmp102_reg_to_mC(regval); | |
97 | *temp = tmp102_reg_to_mC(reg); | ||
98 | 111 | ||
99 | return 0; | 112 | return 0; |
100 | } | 113 | } |
101 | 114 | ||
102 | static ssize_t tmp102_show_temp(struct device *dev, | 115 | static int tmp102_write(struct device *dev, enum hwmon_sensor_types type, |
103 | struct device_attribute *attr, | 116 | u32 attr, int channel, long temp) |
104 | char *buf) | ||
105 | { | 117 | { |
106 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | ||
107 | struct tmp102 *tmp102 = dev_get_drvdata(dev); | 118 | struct tmp102 *tmp102 = dev_get_drvdata(dev); |
108 | int regaddr = sda->index; | 119 | int reg; |
109 | unsigned int reg; | 120 | |
110 | int err; | 121 | switch (attr) { |
111 | 122 | case hwmon_temp_max_hyst: | |
112 | if (regaddr == TMP102_TEMP_REG && | 123 | reg = TMP102_TLOW_REG; |
113 | time_before(jiffies, tmp102->ready_time)) | 124 | break; |
114 | return -EAGAIN; | 125 | case hwmon_temp_max: |
115 | 126 | reg = TMP102_THIGH_REG; | |
116 | err = regmap_read(tmp102->regmap, regaddr, ®); | 127 | break; |
117 | if (err < 0) | 128 | default: |
118 | return err; | 129 | return -EOPNOTSUPP; |
130 | } | ||
119 | 131 | ||
120 | return sprintf(buf, "%d\n", tmp102_reg_to_mC(reg)); | 132 | temp = clamp_val(temp, -256000, 255000); |
133 | return regmap_write(tmp102->regmap, reg, tmp102_mC_to_reg(temp)); | ||
121 | } | 134 | } |
122 | 135 | ||
123 | static ssize_t tmp102_set_temp(struct device *dev, | 136 | static umode_t tmp102_is_visible(const void *data, enum hwmon_sensor_types type, |
124 | struct device_attribute *attr, | 137 | u32 attr, int channel) |
125 | const char *buf, size_t count) | ||
126 | { | 138 | { |
127 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | 139 | if (type != hwmon_temp) |
128 | struct tmp102 *tmp102 = dev_get_drvdata(dev); | 140 | return 0; |
129 | int reg = sda->index; | 141 | |
130 | long val; | 142 | switch (attr) { |
131 | int err; | 143 | case hwmon_temp_input: |
132 | 144 | return S_IRUGO; | |
133 | if (kstrtol(buf, 10, &val) < 0) | 145 | case hwmon_temp_max_hyst: |
134 | return -EINVAL; | 146 | case hwmon_temp_max: |
135 | val = clamp_val(val, -256000, 255000); | 147 | return S_IRUGO | S_IWUSR; |
136 | 148 | default: | |
137 | err = regmap_write(tmp102->regmap, reg, tmp102_mC_to_reg(val)); | 149 | return 0; |
138 | return err ? : count; | 150 | } |
139 | } | 151 | } |
140 | 152 | ||
141 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp102_show_temp, NULL, | 153 | static u32 tmp102_chip_config[] = { |
142 | TMP102_TEMP_REG); | 154 | HWMON_C_REGISTER_TZ, |
155 | 0 | ||
156 | }; | ||
157 | |||
158 | static const struct hwmon_channel_info tmp102_chip = { | ||
159 | .type = hwmon_chip, | ||
160 | .config = tmp102_chip_config, | ||
161 | }; | ||
143 | 162 | ||
144 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, tmp102_show_temp, | 163 | static u32 tmp102_temp_config[] = { |
145 | tmp102_set_temp, TMP102_TLOW_REG); | 164 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST, |
165 | 0 | ||
166 | }; | ||
146 | 167 | ||
147 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp, | 168 | static const struct hwmon_channel_info tmp102_temp = { |
148 | tmp102_set_temp, TMP102_THIGH_REG); | 169 | .type = hwmon_temp, |
170 | .config = tmp102_temp_config, | ||
171 | }; | ||
149 | 172 | ||
150 | static struct attribute *tmp102_attrs[] = { | 173 | static const struct hwmon_channel_info *tmp102_info[] = { |
151 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 174 | &tmp102_chip, |
152 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 175 | &tmp102_temp, |
153 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
154 | NULL | 176 | NULL |
155 | }; | 177 | }; |
156 | ATTRIBUTE_GROUPS(tmp102); | ||
157 | 178 | ||
158 | static const struct thermal_zone_of_device_ops tmp102_of_thermal_ops = { | 179 | static const struct hwmon_ops tmp102_hwmon_ops = { |
159 | .get_temp = tmp102_read_temp, | 180 | .is_visible = tmp102_is_visible, |
181 | .read = tmp102_read, | ||
182 | .write = tmp102_write, | ||
183 | }; | ||
184 | |||
185 | static const struct hwmon_chip_info tmp102_chip_info = { | ||
186 | .ops = &tmp102_hwmon_ops, | ||
187 | .info = tmp102_info, | ||
160 | }; | 188 | }; |
161 | 189 | ||
162 | static void tmp102_restore_config(void *data) | 190 | static void tmp102_restore_config(void *data) |
@@ -188,7 +216,7 @@ static const struct regmap_config tmp102_regmap_config = { | |||
188 | }; | 216 | }; |
189 | 217 | ||
190 | static int tmp102_probe(struct i2c_client *client, | 218 | static int tmp102_probe(struct i2c_client *client, |
191 | const struct i2c_device_id *id) | 219 | const struct i2c_device_id *id) |
192 | { | 220 | { |
193 | struct device *dev = &client->dev; | 221 | struct device *dev = &client->dev; |
194 | struct device *hwmon_dev; | 222 | struct device *hwmon_dev; |
@@ -249,16 +277,14 @@ static int tmp102_probe(struct i2c_client *client, | |||
249 | tmp102->ready_time += msecs_to_jiffies(CONVERSION_TIME_MS); | 277 | tmp102->ready_time += msecs_to_jiffies(CONVERSION_TIME_MS); |
250 | } | 278 | } |
251 | 279 | ||
252 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 280 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
253 | tmp102, | 281 | tmp102, |
254 | tmp102_groups); | 282 | &tmp102_chip_info, |
283 | NULL); | ||
255 | if (IS_ERR(hwmon_dev)) { | 284 | if (IS_ERR(hwmon_dev)) { |
256 | dev_dbg(dev, "unable to register hwmon device\n"); | 285 | dev_dbg(dev, "unable to register hwmon device\n"); |
257 | return PTR_ERR(hwmon_dev); | 286 | return PTR_ERR(hwmon_dev); |
258 | } | 287 | } |
259 | devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, | ||
260 | &tmp102_of_thermal_ops); | ||
261 | |||
262 | dev_info(dev, "initialized\n"); | 288 | dev_info(dev, "initialized\n"); |
263 | 289 | ||
264 | return 0; | 290 | return 0; |
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 85d48d80822a..bfb98b96c781 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c | |||
@@ -72,6 +72,10 @@ MODULE_DEVICE_TABLE(i2c, tmp421_id); | |||
72 | struct tmp421_data { | 72 | struct tmp421_data { |
73 | struct i2c_client *client; | 73 | struct i2c_client *client; |
74 | struct mutex update_lock; | 74 | struct mutex update_lock; |
75 | u32 temp_config[5]; | ||
76 | struct hwmon_channel_info temp_info; | ||
77 | const struct hwmon_channel_info *info[2]; | ||
78 | struct hwmon_chip_info chip; | ||
75 | char valid; | 79 | char valid; |
76 | unsigned long last_updated; | 80 | unsigned long last_updated; |
77 | int channels; | 81 | int channels; |
@@ -125,85 +129,46 @@ static struct tmp421_data *tmp421_update_device(struct device *dev) | |||
125 | return data; | 129 | return data; |
126 | } | 130 | } |
127 | 131 | ||
128 | static ssize_t show_temp_value(struct device *dev, | 132 | static int tmp421_read(struct device *dev, enum hwmon_sensor_types type, |
129 | struct device_attribute *devattr, char *buf) | 133 | u32 attr, int channel, long *val) |
130 | { | 134 | { |
131 | int index = to_sensor_dev_attr(devattr)->index; | 135 | struct tmp421_data *tmp421 = tmp421_update_device(dev); |
132 | struct tmp421_data *data = tmp421_update_device(dev); | 136 | |
133 | int temp; | 137 | switch (attr) { |
134 | 138 | case hwmon_temp_input: | |
135 | mutex_lock(&data->update_lock); | 139 | if (tmp421->config & TMP421_CONFIG_RANGE) |
136 | if (data->config & TMP421_CONFIG_RANGE) | 140 | *val = temp_from_u16(tmp421->temp[channel]); |
137 | temp = temp_from_u16(data->temp[index]); | 141 | else |
138 | else | 142 | *val = temp_from_s16(tmp421->temp[channel]); |
139 | temp = temp_from_s16(data->temp[index]); | 143 | return 0; |
140 | mutex_unlock(&data->update_lock); | 144 | case hwmon_temp_fault: |
141 | 145 | /* | |
142 | return sprintf(buf, "%d\n", temp); | 146 | * The OPEN bit signals a fault. This is bit 0 of the temperature |
143 | } | 147 | * register (low byte). |
148 | */ | ||
149 | *val = tmp421->temp[channel] & 0x01; | ||
150 | return 0; | ||
151 | default: | ||
152 | return -EOPNOTSUPP; | ||
153 | } | ||
144 | 154 | ||
145 | static ssize_t show_fault(struct device *dev, | ||
146 | struct device_attribute *devattr, char *buf) | ||
147 | { | ||
148 | int index = to_sensor_dev_attr(devattr)->index; | ||
149 | struct tmp421_data *data = tmp421_update_device(dev); | ||
150 | |||
151 | /* | ||
152 | * The OPEN bit signals a fault. This is bit 0 of the temperature | ||
153 | * register (low byte). | ||
154 | */ | ||
155 | if (data->temp[index] & 0x01) | ||
156 | return sprintf(buf, "1\n"); | ||
157 | else | ||
158 | return sprintf(buf, "0\n"); | ||
159 | } | 155 | } |
160 | 156 | ||
161 | static umode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, | 157 | static umode_t tmp421_is_visible(const void *data, enum hwmon_sensor_types type, |
162 | int n) | 158 | u32 attr, int channel) |
163 | { | 159 | { |
164 | struct device *dev = container_of(kobj, struct device, kobj); | 160 | switch (attr) { |
165 | struct tmp421_data *data = dev_get_drvdata(dev); | 161 | case hwmon_temp_fault: |
166 | struct device_attribute *devattr; | 162 | if (channel == 0) |
167 | unsigned int index; | 163 | return 0; |
168 | 164 | return S_IRUGO; | |
169 | devattr = container_of(a, struct device_attribute, attr); | 165 | case hwmon_temp_input: |
170 | index = to_sensor_dev_attr(devattr)->index; | 166 | return S_IRUGO; |
171 | 167 | default: | |
172 | if (index < data->channels) | 168 | return 0; |
173 | return a->mode; | 169 | } |
174 | |||
175 | return 0; | ||
176 | } | 170 | } |
177 | 171 | ||
178 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0); | ||
179 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1); | ||
180 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1); | ||
181 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2); | ||
182 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2); | ||
183 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3); | ||
184 | static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3); | ||
185 | |||
186 | static struct attribute *tmp421_attr[] = { | ||
187 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
188 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
189 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
190 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
191 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
192 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
193 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
194 | NULL | ||
195 | }; | ||
196 | |||
197 | static const struct attribute_group tmp421_group = { | ||
198 | .attrs = tmp421_attr, | ||
199 | .is_visible = tmp421_is_visible, | ||
200 | }; | ||
201 | |||
202 | static const struct attribute_group *tmp421_groups[] = { | ||
203 | &tmp421_group, | ||
204 | NULL | ||
205 | }; | ||
206 | |||
207 | static int tmp421_init_client(struct i2c_client *client) | 172 | static int tmp421_init_client(struct i2c_client *client) |
208 | { | 173 | { |
209 | int config, config_orig; | 174 | int config, config_orig; |
@@ -289,13 +254,18 @@ static int tmp421_detect(struct i2c_client *client, | |||
289 | return 0; | 254 | return 0; |
290 | } | 255 | } |
291 | 256 | ||
257 | static const struct hwmon_ops tmp421_ops = { | ||
258 | .is_visible = tmp421_is_visible, | ||
259 | .read = tmp421_read, | ||
260 | }; | ||
261 | |||
292 | static int tmp421_probe(struct i2c_client *client, | 262 | static int tmp421_probe(struct i2c_client *client, |
293 | const struct i2c_device_id *id) | 263 | const struct i2c_device_id *id) |
294 | { | 264 | { |
295 | struct device *dev = &client->dev; | 265 | struct device *dev = &client->dev; |
296 | struct device *hwmon_dev; | 266 | struct device *hwmon_dev; |
297 | struct tmp421_data *data; | 267 | struct tmp421_data *data; |
298 | int err; | 268 | int i, err; |
299 | 269 | ||
300 | data = devm_kzalloc(dev, sizeof(struct tmp421_data), GFP_KERNEL); | 270 | data = devm_kzalloc(dev, sizeof(struct tmp421_data), GFP_KERNEL); |
301 | if (!data) | 271 | if (!data) |
@@ -309,8 +279,21 @@ static int tmp421_probe(struct i2c_client *client, | |||
309 | if (err) | 279 | if (err) |
310 | return err; | 280 | return err; |
311 | 281 | ||
312 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 282 | for (i = 0; i < data->channels; i++) |
313 | data, tmp421_groups); | 283 | data->temp_config[i] = HWMON_T_INPUT | HWMON_T_FAULT; |
284 | |||
285 | data->chip.ops = &tmp421_ops; | ||
286 | data->chip.info = data->info; | ||
287 | |||
288 | data->info[0] = &data->temp_info; | ||
289 | |||
290 | data->temp_info.type = hwmon_temp; | ||
291 | data->temp_info.config = data->temp_config; | ||
292 | |||
293 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, | ||
294 | data, | ||
295 | &data->chip, | ||
296 | NULL); | ||
314 | return PTR_ERR_OR_ZERO(hwmon_dev); | 297 | return PTR_ERR_OR_ZERO(hwmon_dev); |
315 | } | 298 | } |
316 | 299 | ||
diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c new file mode 100644 index 000000000000..9c0dbb8191ad --- /dev/null +++ b/drivers/hwmon/xgene-hwmon.c | |||
@@ -0,0 +1,787 @@ | |||
1 | /* | ||
2 | * APM X-Gene SoC Hardware Monitoring Driver | ||
3 | * | ||
4 | * Copyright (c) 2016, Applied Micro Circuits Corporation | ||
5 | * Author: Loc Ho <lho@apm.com> | ||
6 | * Hoan Tran <hotran@apm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
20 | * | ||
21 | * This driver provides the following features: | ||
22 | * - Retrieve CPU total power (uW) | ||
23 | * - Retrieve IO total power (uW) | ||
24 | * - Retrieve SoC temperature (milli-degree C) and alarm | ||
25 | */ | ||
26 | #include <linux/acpi.h> | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/hwmon.h> | ||
29 | #include <linux/hwmon-sysfs.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/kfifo.h> | ||
33 | #include <linux/mailbox_controller.h> | ||
34 | #include <linux/mailbox_client.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/of.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | |||
39 | #include <acpi/pcc.h> | ||
40 | |||
41 | /* SLIMpro message defines */ | ||
42 | #define MSG_TYPE_DBG 0 | ||
43 | #define MSG_TYPE_ERR 7 | ||
44 | #define MSG_TYPE_PWRMGMT 9 | ||
45 | |||
46 | #define MSG_TYPE(v) (((v) & 0xF0000000) >> 28) | ||
47 | #define MSG_TYPE_SET(v) (((v) << 28) & 0xF0000000) | ||
48 | #define MSG_SUBTYPE(v) (((v) & 0x0F000000) >> 24) | ||
49 | #define MSG_SUBTYPE_SET(v) (((v) << 24) & 0x0F000000) | ||
50 | |||
51 | #define DBG_SUBTYPE_SENSOR_READ 4 | ||
52 | #define SENSOR_RD_MSG 0x04FFE902 | ||
53 | #define SENSOR_RD_EN_ADDR(a) ((a) & 0x000FFFFF) | ||
54 | #define PMD_PWR_REG 0x20 | ||
55 | #define PMD_PWR_MW_REG 0x26 | ||
56 | #define SOC_PWR_REG 0x21 | ||
57 | #define SOC_PWR_MW_REG 0x27 | ||
58 | #define SOC_TEMP_REG 0x10 | ||
59 | |||
60 | #define TEMP_NEGATIVE_BIT 8 | ||
61 | #define SENSOR_INVALID_DATA BIT(15) | ||
62 | |||
63 | #define PWRMGMT_SUBTYPE_TPC 1 | ||
64 | #define TPC_ALARM 2 | ||
65 | #define TPC_GET_ALARM 3 | ||
66 | #define TPC_CMD(v) (((v) & 0x00FF0000) >> 16) | ||
67 | #define TPC_CMD_SET(v) (((v) << 16) & 0x00FF0000) | ||
68 | #define TPC_EN_MSG(hndl, cmd, type) \ | ||
69 | (MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \ | ||
70 | MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type) | ||
71 | |||
72 | /* PCC defines */ | ||
73 | #define PCC_SIGNATURE_MASK 0x50424300 | ||
74 | #define PCCC_GENERATE_DB_INT BIT(15) | ||
75 | #define PCCS_CMD_COMPLETE BIT(0) | ||
76 | #define PCCS_SCI_DOORBEL BIT(1) | ||
77 | #define PCCS_PLATFORM_NOTIFICATION BIT(3) | ||
78 | /* | ||
79 | * Arbitrary retries in case the remote processor is slow to respond | ||
80 | * to PCC commands | ||
81 | */ | ||
82 | #define PCC_NUM_RETRIES 500 | ||
83 | |||
84 | #define ASYNC_MSG_FIFO_SIZE 16 | ||
85 | #define MBOX_OP_TIMEOUTMS 1000 | ||
86 | |||
87 | #define WATT_TO_mWATT(x) ((x) * 1000) | ||
88 | #define mWATT_TO_uWATT(x) ((x) * 1000) | ||
89 | #define CELSIUS_TO_mCELSIUS(x) ((x) * 1000) | ||
90 | |||
91 | #define to_xgene_hwmon_dev(cl) \ | ||
92 | container_of(cl, struct xgene_hwmon_dev, mbox_client) | ||
93 | |||
94 | struct slimpro_resp_msg { | ||
95 | u32 msg; | ||
96 | u32 param1; | ||
97 | u32 param2; | ||
98 | } __packed; | ||
99 | |||
100 | struct xgene_hwmon_dev { | ||
101 | struct device *dev; | ||
102 | struct mbox_chan *mbox_chan; | ||
103 | struct mbox_client mbox_client; | ||
104 | int mbox_idx; | ||
105 | |||
106 | spinlock_t kfifo_lock; | ||
107 | struct mutex rd_mutex; | ||
108 | struct completion rd_complete; | ||
109 | int resp_pending; | ||
110 | struct slimpro_resp_msg sync_msg; | ||
111 | |||
112 | struct work_struct workq; | ||
113 | struct kfifo_rec_ptr_1 async_msg_fifo; | ||
114 | |||
115 | struct device *hwmon_dev; | ||
116 | bool temp_critical_alarm; | ||
117 | |||
118 | phys_addr_t comm_base_addr; | ||
119 | void *pcc_comm_addr; | ||
120 | u64 usecs_lat; | ||
121 | }; | ||
122 | |||
123 | /* | ||
124 | * This function tests and clears a bitmask then returns its old value | ||
125 | */ | ||
126 | static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask) | ||
127 | { | ||
128 | u16 ret, val; | ||
129 | |||
130 | val = le16_to_cpu(READ_ONCE(*addr)); | ||
131 | ret = val & mask; | ||
132 | val &= ~mask; | ||
133 | WRITE_ONCE(*addr, cpu_to_le16(val)); | ||
134 | |||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg) | ||
139 | { | ||
140 | struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr; | ||
141 | u32 *ptr = (void *)(generic_comm_base + 1); | ||
142 | int rc, i; | ||
143 | u16 val; | ||
144 | |||
145 | mutex_lock(&ctx->rd_mutex); | ||
146 | init_completion(&ctx->rd_complete); | ||
147 | ctx->resp_pending = true; | ||
148 | |||
149 | /* Write signature for subspace */ | ||
150 | WRITE_ONCE(generic_comm_base->signature, | ||
151 | cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx)); | ||
152 | |||
153 | /* Write to the shared command region */ | ||
154 | WRITE_ONCE(generic_comm_base->command, | ||
155 | cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT)); | ||
156 | |||
157 | /* Flip CMD COMPLETE bit */ | ||
158 | val = le16_to_cpu(READ_ONCE(generic_comm_base->status)); | ||
159 | val &= ~PCCS_CMD_COMPLETE; | ||
160 | WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val)); | ||
161 | |||
162 | /* Copy the message to the PCC comm space */ | ||
163 | for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++) | ||
164 | WRITE_ONCE(ptr[i], cpu_to_le32(msg[i])); | ||
165 | |||
166 | /* Ring the doorbell */ | ||
167 | rc = mbox_send_message(ctx->mbox_chan, msg); | ||
168 | if (rc < 0) { | ||
169 | dev_err(ctx->dev, "Mailbox send error %d\n", rc); | ||
170 | goto err; | ||
171 | } | ||
172 | if (!wait_for_completion_timeout(&ctx->rd_complete, | ||
173 | usecs_to_jiffies(ctx->usecs_lat))) { | ||
174 | dev_err(ctx->dev, "Mailbox operation timed out\n"); | ||
175 | rc = -ETIMEDOUT; | ||
176 | goto err; | ||
177 | } | ||
178 | |||
179 | /* Check for error message */ | ||
180 | if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) { | ||
181 | rc = -EINVAL; | ||
182 | goto err; | ||
183 | } | ||
184 | |||
185 | msg[0] = ctx->sync_msg.msg; | ||
186 | msg[1] = ctx->sync_msg.param1; | ||
187 | msg[2] = ctx->sync_msg.param2; | ||
188 | |||
189 | err: | ||
190 | mbox_chan_txdone(ctx->mbox_chan, 0); | ||
191 | ctx->resp_pending = false; | ||
192 | mutex_unlock(&ctx->rd_mutex); | ||
193 | return rc; | ||
194 | } | ||
195 | |||
196 | static int xgene_hwmon_rd(struct xgene_hwmon_dev *ctx, u32 *msg) | ||
197 | { | ||
198 | int rc; | ||
199 | |||
200 | mutex_lock(&ctx->rd_mutex); | ||
201 | init_completion(&ctx->rd_complete); | ||
202 | ctx->resp_pending = true; | ||
203 | |||
204 | rc = mbox_send_message(ctx->mbox_chan, msg); | ||
205 | if (rc < 0) { | ||
206 | dev_err(ctx->dev, "Mailbox send error %d\n", rc); | ||
207 | goto err; | ||
208 | } | ||
209 | |||
210 | if (!wait_for_completion_timeout(&ctx->rd_complete, | ||
211 | msecs_to_jiffies(MBOX_OP_TIMEOUTMS))) { | ||
212 | dev_err(ctx->dev, "Mailbox operation timed out\n"); | ||
213 | rc = -ETIMEDOUT; | ||
214 | goto err; | ||
215 | } | ||
216 | |||
217 | /* Check for error message */ | ||
218 | if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) { | ||
219 | rc = -EINVAL; | ||
220 | goto err; | ||
221 | } | ||
222 | |||
223 | msg[0] = ctx->sync_msg.msg; | ||
224 | msg[1] = ctx->sync_msg.param1; | ||
225 | msg[2] = ctx->sync_msg.param2; | ||
226 | |||
227 | err: | ||
228 | ctx->resp_pending = false; | ||
229 | mutex_unlock(&ctx->rd_mutex); | ||
230 | return rc; | ||
231 | } | ||
232 | |||
233 | static int xgene_hwmon_reg_map_rd(struct xgene_hwmon_dev *ctx, u32 addr, | ||
234 | u32 *data) | ||
235 | { | ||
236 | u32 msg[3]; | ||
237 | int rc; | ||
238 | |||
239 | msg[0] = SENSOR_RD_MSG; | ||
240 | msg[1] = SENSOR_RD_EN_ADDR(addr); | ||
241 | msg[2] = 0; | ||
242 | |||
243 | if (acpi_disabled) | ||
244 | rc = xgene_hwmon_rd(ctx, msg); | ||
245 | else | ||
246 | rc = xgene_hwmon_pcc_rd(ctx, msg); | ||
247 | |||
248 | if (rc < 0) | ||
249 | return rc; | ||
250 | |||
251 | /* | ||
252 | * Check if sensor data is valid. | ||
253 | */ | ||
254 | if (msg[1] & SENSOR_INVALID_DATA) | ||
255 | return -ENODATA; | ||
256 | |||
257 | *data = msg[1]; | ||
258 | |||
259 | return rc; | ||
260 | } | ||
261 | |||
262 | static int xgene_hwmon_get_notification_msg(struct xgene_hwmon_dev *ctx, | ||
263 | u32 *amsg) | ||
264 | { | ||
265 | u32 msg[3]; | ||
266 | int rc; | ||
267 | |||
268 | msg[0] = TPC_EN_MSG(PWRMGMT_SUBTYPE_TPC, TPC_GET_ALARM, 0); | ||
269 | msg[1] = 0; | ||
270 | msg[2] = 0; | ||
271 | |||
272 | rc = xgene_hwmon_pcc_rd(ctx, msg); | ||
273 | if (rc < 0) | ||
274 | return rc; | ||
275 | |||
276 | amsg[0] = msg[0]; | ||
277 | amsg[1] = msg[1]; | ||
278 | amsg[2] = msg[2]; | ||
279 | |||
280 | return rc; | ||
281 | } | ||
282 | |||
283 | static int xgene_hwmon_get_cpu_pwr(struct xgene_hwmon_dev *ctx, u32 *val) | ||
284 | { | ||
285 | u32 watt, mwatt; | ||
286 | int rc; | ||
287 | |||
288 | rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_REG, &watt); | ||
289 | if (rc < 0) | ||
290 | return rc; | ||
291 | |||
292 | rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_MW_REG, &mwatt); | ||
293 | if (rc < 0) | ||
294 | return rc; | ||
295 | |||
296 | *val = WATT_TO_mWATT(watt) + mwatt; | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static int xgene_hwmon_get_io_pwr(struct xgene_hwmon_dev *ctx, u32 *val) | ||
301 | { | ||
302 | u32 watt, mwatt; | ||
303 | int rc; | ||
304 | |||
305 | rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_REG, &watt); | ||
306 | if (rc < 0) | ||
307 | return rc; | ||
308 | |||
309 | rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_MW_REG, &mwatt); | ||
310 | if (rc < 0) | ||
311 | return rc; | ||
312 | |||
313 | *val = WATT_TO_mWATT(watt) + mwatt; | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int xgene_hwmon_get_temp(struct xgene_hwmon_dev *ctx, u32 *val) | ||
318 | { | ||
319 | return xgene_hwmon_reg_map_rd(ctx, SOC_TEMP_REG, val); | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | * Sensor temperature/power functions | ||
324 | */ | ||
325 | static ssize_t temp1_input_show(struct device *dev, | ||
326 | struct device_attribute *attr, | ||
327 | char *buf) | ||
328 | { | ||
329 | struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); | ||
330 | int rc, temp; | ||
331 | u32 val; | ||
332 | |||
333 | rc = xgene_hwmon_get_temp(ctx, &val); | ||
334 | if (rc < 0) | ||
335 | return rc; | ||
336 | |||
337 | temp = sign_extend32(val, TEMP_NEGATIVE_BIT); | ||
338 | |||
339 | return snprintf(buf, PAGE_SIZE, "%d\n", CELSIUS_TO_mCELSIUS(temp)); | ||
340 | } | ||
341 | |||
342 | static ssize_t temp1_label_show(struct device *dev, | ||
343 | struct device_attribute *attr, | ||
344 | char *buf) | ||
345 | { | ||
346 | return snprintf(buf, PAGE_SIZE, "SoC Temperature\n"); | ||
347 | } | ||
348 | |||
349 | static ssize_t temp1_critical_alarm_show(struct device *dev, | ||
350 | struct device_attribute *devattr, | ||
351 | char *buf) | ||
352 | { | ||
353 | struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); | ||
354 | |||
355 | return snprintf(buf, PAGE_SIZE, "%d\n", ctx->temp_critical_alarm); | ||
356 | } | ||
357 | |||
358 | static ssize_t power1_label_show(struct device *dev, | ||
359 | struct device_attribute *attr, | ||
360 | char *buf) | ||
361 | { | ||
362 | return snprintf(buf, PAGE_SIZE, "CPU power\n"); | ||
363 | } | ||
364 | |||
365 | static ssize_t power2_label_show(struct device *dev, | ||
366 | struct device_attribute *attr, | ||
367 | char *buf) | ||
368 | { | ||
369 | return snprintf(buf, PAGE_SIZE, "IO power\n"); | ||
370 | } | ||
371 | |||
372 | static ssize_t power1_input_show(struct device *dev, | ||
373 | struct device_attribute *attr, | ||
374 | char *buf) | ||
375 | { | ||
376 | struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); | ||
377 | u32 val; | ||
378 | int rc; | ||
379 | |||
380 | rc = xgene_hwmon_get_cpu_pwr(ctx, &val); | ||
381 | if (rc < 0) | ||
382 | return rc; | ||
383 | |||
384 | return snprintf(buf, PAGE_SIZE, "%u\n", mWATT_TO_uWATT(val)); | ||
385 | } | ||
386 | |||
387 | static ssize_t power2_input_show(struct device *dev, | ||
388 | struct device_attribute *attr, | ||
389 | char *buf) | ||
390 | { | ||
391 | struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); | ||
392 | u32 val; | ||
393 | int rc; | ||
394 | |||
395 | rc = xgene_hwmon_get_io_pwr(ctx, &val); | ||
396 | if (rc < 0) | ||
397 | return rc; | ||
398 | |||
399 | return snprintf(buf, PAGE_SIZE, "%u\n", mWATT_TO_uWATT(val)); | ||
400 | } | ||
401 | |||
402 | static DEVICE_ATTR_RO(temp1_label); | ||
403 | static DEVICE_ATTR_RO(temp1_input); | ||
404 | static DEVICE_ATTR_RO(temp1_critical_alarm); | ||
405 | static DEVICE_ATTR_RO(power1_label); | ||
406 | static DEVICE_ATTR_RO(power1_input); | ||
407 | static DEVICE_ATTR_RO(power2_label); | ||
408 | static DEVICE_ATTR_RO(power2_input); | ||
409 | |||
410 | static struct attribute *xgene_hwmon_attrs[] = { | ||
411 | &dev_attr_temp1_label.attr, | ||
412 | &dev_attr_temp1_input.attr, | ||
413 | &dev_attr_temp1_critical_alarm.attr, | ||
414 | &dev_attr_power1_label.attr, | ||
415 | &dev_attr_power1_input.attr, | ||
416 | &dev_attr_power2_label.attr, | ||
417 | &dev_attr_power2_input.attr, | ||
418 | NULL, | ||
419 | }; | ||
420 | |||
421 | ATTRIBUTE_GROUPS(xgene_hwmon); | ||
422 | |||
423 | static int xgene_hwmon_tpc_alarm(struct xgene_hwmon_dev *ctx, | ||
424 | struct slimpro_resp_msg *amsg) | ||
425 | { | ||
426 | ctx->temp_critical_alarm = !!amsg->param2; | ||
427 | sysfs_notify(&ctx->dev->kobj, NULL, "temp1_critical_alarm"); | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static void xgene_hwmon_process_pwrmsg(struct xgene_hwmon_dev *ctx, | ||
433 | struct slimpro_resp_msg *amsg) | ||
434 | { | ||
435 | if ((MSG_SUBTYPE(amsg->msg) == PWRMGMT_SUBTYPE_TPC) && | ||
436 | (TPC_CMD(amsg->msg) == TPC_ALARM)) | ||
437 | xgene_hwmon_tpc_alarm(ctx, amsg); | ||
438 | } | ||
439 | |||
440 | /* | ||
441 | * This function is called to process async work queue | ||
442 | */ | ||
443 | static void xgene_hwmon_evt_work(struct work_struct *work) | ||
444 | { | ||
445 | struct slimpro_resp_msg amsg; | ||
446 | struct xgene_hwmon_dev *ctx; | ||
447 | int ret; | ||
448 | |||
449 | ctx = container_of(work, struct xgene_hwmon_dev, workq); | ||
450 | while (kfifo_out_spinlocked(&ctx->async_msg_fifo, &amsg, | ||
451 | sizeof(struct slimpro_resp_msg), | ||
452 | &ctx->kfifo_lock)) { | ||
453 | /* | ||
454 | * If PCC, send a consumer command to Platform to get info | ||
455 | * If Slimpro Mailbox, get message from specific FIFO | ||
456 | */ | ||
457 | if (!acpi_disabled) { | ||
458 | ret = xgene_hwmon_get_notification_msg(ctx, | ||
459 | (u32 *)&amsg); | ||
460 | if (ret < 0) | ||
461 | continue; | ||
462 | } | ||
463 | |||
464 | if (MSG_TYPE(amsg.msg) == MSG_TYPE_PWRMGMT) | ||
465 | xgene_hwmon_process_pwrmsg(ctx, &amsg); | ||
466 | } | ||
467 | } | ||
468 | |||
469 | static int xgene_hwmon_rx_ready(struct xgene_hwmon_dev *ctx, void *msg) | ||
470 | { | ||
471 | if (IS_ERR_OR_NULL(ctx->hwmon_dev) && !ctx->resp_pending) { | ||
472 | /* Enqueue to the FIFO */ | ||
473 | kfifo_in_spinlocked(&ctx->async_msg_fifo, msg, | ||
474 | sizeof(struct slimpro_resp_msg), | ||
475 | &ctx->kfifo_lock); | ||
476 | return -ENODEV; | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * This function is called when the SLIMpro Mailbox received a message | ||
484 | */ | ||
485 | static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg) | ||
486 | { | ||
487 | struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl); | ||
488 | |||
489 | /* | ||
490 | * While the driver registers with the mailbox framework, an interrupt | ||
491 | * can be pending before the probe function completes its | ||
492 | * initialization. If such condition occurs, just queue up the message | ||
493 | * as the driver is not ready for servicing the callback. | ||
494 | */ | ||
495 | if (xgene_hwmon_rx_ready(ctx, msg) < 0) | ||
496 | return; | ||
497 | |||
498 | /* | ||
499 | * Response message format: | ||
500 | * msg[0] is the return code of the operation | ||
501 | * msg[1] is the first parameter word | ||
502 | * msg[2] is the second parameter word | ||
503 | * | ||
504 | * As message only supports dword size, just assign it. | ||
505 | */ | ||
506 | |||
507 | /* Check for sync query */ | ||
508 | if (ctx->resp_pending && | ||
509 | ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) || | ||
510 | (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG && | ||
511 | MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) || | ||
512 | (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT && | ||
513 | MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC && | ||
514 | TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) { | ||
515 | ctx->sync_msg.msg = ((u32 *)msg)[0]; | ||
516 | ctx->sync_msg.param1 = ((u32 *)msg)[1]; | ||
517 | ctx->sync_msg.param2 = ((u32 *)msg)[2]; | ||
518 | |||
519 | /* Operation waiting for response */ | ||
520 | complete(&ctx->rd_complete); | ||
521 | |||
522 | return; | ||
523 | } | ||
524 | |||
525 | /* Enqueue to the FIFO */ | ||
526 | kfifo_in_spinlocked(&ctx->async_msg_fifo, msg, | ||
527 | sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock); | ||
528 | /* Schedule the bottom handler */ | ||
529 | schedule_work(&ctx->workq); | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * This function is called when the PCC Mailbox received a message | ||
534 | */ | ||
535 | static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg) | ||
536 | { | ||
537 | struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl); | ||
538 | struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr; | ||
539 | struct slimpro_resp_msg amsg; | ||
540 | |||
541 | /* | ||
542 | * While the driver registers with the mailbox framework, an interrupt | ||
543 | * can be pending before the probe function completes its | ||
544 | * initialization. If such condition occurs, just queue up the message | ||
545 | * as the driver is not ready for servicing the callback. | ||
546 | */ | ||
547 | if (xgene_hwmon_rx_ready(ctx, &amsg) < 0) | ||
548 | return; | ||
549 | |||
550 | msg = generic_comm_base + 1; | ||
551 | /* Check if platform sends interrupt */ | ||
552 | if (!xgene_word_tst_and_clr(&generic_comm_base->status, | ||
553 | PCCS_SCI_DOORBEL)) | ||
554 | return; | ||
555 | |||
556 | /* | ||
557 | * Response message format: | ||
558 | * msg[0] is the return code of the operation | ||
559 | * msg[1] is the first parameter word | ||
560 | * msg[2] is the second parameter word | ||
561 | * | ||
562 | * As message only supports dword size, just assign it. | ||
563 | */ | ||
564 | |||
565 | /* Check for sync query */ | ||
566 | if (ctx->resp_pending && | ||
567 | ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) || | ||
568 | (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG && | ||
569 | MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) || | ||
570 | (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT && | ||
571 | MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC && | ||
572 | TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) { | ||
573 | /* Check if platform completes command */ | ||
574 | if (xgene_word_tst_and_clr(&generic_comm_base->status, | ||
575 | PCCS_CMD_COMPLETE)) { | ||
576 | ctx->sync_msg.msg = ((u32 *)msg)[0]; | ||
577 | ctx->sync_msg.param1 = ((u32 *)msg)[1]; | ||
578 | ctx->sync_msg.param2 = ((u32 *)msg)[2]; | ||
579 | |||
580 | /* Operation waiting for response */ | ||
581 | complete(&ctx->rd_complete); | ||
582 | |||
583 | return; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | /* | ||
588 | * Platform notifies interrupt to OSPM. | ||
589 | * OPSM schedules a consumer command to get this information | ||
590 | * in a workqueue. Platform must wait until OSPM has issued | ||
591 | * a consumer command that serves this notification. | ||
592 | */ | ||
593 | |||
594 | /* Enqueue to the FIFO */ | ||
595 | kfifo_in_spinlocked(&ctx->async_msg_fifo, &amsg, | ||
596 | sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock); | ||
597 | /* Schedule the bottom handler */ | ||
598 | schedule_work(&ctx->workq); | ||
599 | } | ||
600 | |||
601 | static void xgene_hwmon_tx_done(struct mbox_client *cl, void *msg, int ret) | ||
602 | { | ||
603 | if (ret) { | ||
604 | dev_dbg(cl->dev, "TX did not complete: CMD sent:%x, ret:%d\n", | ||
605 | *(u16 *)msg, ret); | ||
606 | } else { | ||
607 | dev_dbg(cl->dev, "TX completed. CMD sent:%x, ret:%d\n", | ||
608 | *(u16 *)msg, ret); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | static int xgene_hwmon_probe(struct platform_device *pdev) | ||
613 | { | ||
614 | struct xgene_hwmon_dev *ctx; | ||
615 | struct mbox_client *cl; | ||
616 | int rc; | ||
617 | |||
618 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); | ||
619 | if (!ctx) | ||
620 | return -ENOMEM; | ||
621 | |||
622 | ctx->dev = &pdev->dev; | ||
623 | platform_set_drvdata(pdev, ctx); | ||
624 | cl = &ctx->mbox_client; | ||
625 | |||
626 | spin_lock_init(&ctx->kfifo_lock); | ||
627 | mutex_init(&ctx->rd_mutex); | ||
628 | |||
629 | rc = kfifo_alloc(&ctx->async_msg_fifo, | ||
630 | sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE, | ||
631 | GFP_KERNEL); | ||
632 | if (rc) | ||
633 | goto out_mbox_free; | ||
634 | |||
635 | INIT_WORK(&ctx->workq, xgene_hwmon_evt_work); | ||
636 | |||
637 | /* Request mailbox channel */ | ||
638 | cl->dev = &pdev->dev; | ||
639 | cl->tx_done = xgene_hwmon_tx_done; | ||
640 | cl->tx_block = false; | ||
641 | cl->tx_tout = MBOX_OP_TIMEOUTMS; | ||
642 | cl->knows_txdone = false; | ||
643 | if (acpi_disabled) { | ||
644 | cl->rx_callback = xgene_hwmon_rx_cb; | ||
645 | ctx->mbox_chan = mbox_request_channel(cl, 0); | ||
646 | if (IS_ERR(ctx->mbox_chan)) { | ||
647 | dev_err(&pdev->dev, | ||
648 | "SLIMpro mailbox channel request failed\n"); | ||
649 | return -ENODEV; | ||
650 | } | ||
651 | } else { | ||
652 | struct acpi_pcct_hw_reduced *cppc_ss; | ||
653 | |||
654 | if (device_property_read_u32(&pdev->dev, "pcc-channel", | ||
655 | &ctx->mbox_idx)) { | ||
656 | dev_err(&pdev->dev, "no pcc-channel property\n"); | ||
657 | return -ENODEV; | ||
658 | } | ||
659 | |||
660 | cl->rx_callback = xgene_hwmon_pcc_rx_cb; | ||
661 | ctx->mbox_chan = pcc_mbox_request_channel(cl, ctx->mbox_idx); | ||
662 | if (IS_ERR(ctx->mbox_chan)) { | ||
663 | dev_err(&pdev->dev, | ||
664 | "PPC channel request failed\n"); | ||
665 | return -ENODEV; | ||
666 | } | ||
667 | |||
668 | /* | ||
669 | * The PCC mailbox controller driver should | ||
670 | * have parsed the PCCT (global table of all | ||
671 | * PCC channels) and stored pointers to the | ||
672 | * subspace communication region in con_priv. | ||
673 | */ | ||
674 | cppc_ss = ctx->mbox_chan->con_priv; | ||
675 | if (!cppc_ss) { | ||
676 | dev_err(&pdev->dev, "PPC subspace not found\n"); | ||
677 | rc = -ENODEV; | ||
678 | goto out_mbox_free; | ||
679 | } | ||
680 | |||
681 | if (!ctx->mbox_chan->mbox->txdone_irq) { | ||
682 | dev_err(&pdev->dev, "PCC IRQ not supported\n"); | ||
683 | rc = -ENODEV; | ||
684 | goto out_mbox_free; | ||
685 | } | ||
686 | |||
687 | /* | ||
688 | * This is the shared communication region | ||
689 | * for the OS and Platform to communicate over. | ||
690 | */ | ||
691 | ctx->comm_base_addr = cppc_ss->base_address; | ||
692 | if (ctx->comm_base_addr) { | ||
693 | ctx->pcc_comm_addr = memremap(ctx->comm_base_addr, | ||
694 | cppc_ss->length, | ||
695 | MEMREMAP_WB); | ||
696 | } else { | ||
697 | dev_err(&pdev->dev, "Failed to get PCC comm region\n"); | ||
698 | rc = -ENODEV; | ||
699 | goto out_mbox_free; | ||
700 | } | ||
701 | |||
702 | if (!ctx->pcc_comm_addr) { | ||
703 | dev_err(&pdev->dev, | ||
704 | "Failed to ioremap PCC comm region\n"); | ||
705 | rc = -ENOMEM; | ||
706 | goto out_mbox_free; | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * cppc_ss->latency is just a Nominal value. In reality | ||
711 | * the remote processor could be much slower to reply. | ||
712 | * So add an arbitrary amount of wait on top of Nominal. | ||
713 | */ | ||
714 | ctx->usecs_lat = PCC_NUM_RETRIES * cppc_ss->latency; | ||
715 | } | ||
716 | |||
717 | ctx->hwmon_dev = hwmon_device_register_with_groups(ctx->dev, | ||
718 | "apm_xgene", | ||
719 | ctx, | ||
720 | xgene_hwmon_groups); | ||
721 | if (IS_ERR(ctx->hwmon_dev)) { | ||
722 | dev_err(&pdev->dev, "Failed to register HW monitor device\n"); | ||
723 | rc = PTR_ERR(ctx->hwmon_dev); | ||
724 | goto out; | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | * Schedule the bottom handler if there is a pending message. | ||
729 | */ | ||
730 | schedule_work(&ctx->workq); | ||
731 | |||
732 | dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n"); | ||
733 | |||
734 | return 0; | ||
735 | |||
736 | out: | ||
737 | if (acpi_disabled) | ||
738 | mbox_free_channel(ctx->mbox_chan); | ||
739 | else | ||
740 | pcc_mbox_free_channel(ctx->mbox_chan); | ||
741 | out_mbox_free: | ||
742 | kfifo_free(&ctx->async_msg_fifo); | ||
743 | |||
744 | return rc; | ||
745 | } | ||
746 | |||
747 | static int xgene_hwmon_remove(struct platform_device *pdev) | ||
748 | { | ||
749 | struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev); | ||
750 | |||
751 | hwmon_device_unregister(ctx->hwmon_dev); | ||
752 | kfifo_free(&ctx->async_msg_fifo); | ||
753 | if (acpi_disabled) | ||
754 | mbox_free_channel(ctx->mbox_chan); | ||
755 | else | ||
756 | pcc_mbox_free_channel(ctx->mbox_chan); | ||
757 | |||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | #ifdef CONFIG_ACPI | ||
762 | static const struct acpi_device_id xgene_hwmon_acpi_match[] = { | ||
763 | {"APMC0D29", 0}, | ||
764 | {}, | ||
765 | }; | ||
766 | MODULE_DEVICE_TABLE(acpi, xgene_hwmon_acpi_match); | ||
767 | #endif | ||
768 | |||
769 | static const struct of_device_id xgene_hwmon_of_match[] = { | ||
770 | {.compatible = "apm,xgene-slimpro-hwmon"}, | ||
771 | {} | ||
772 | }; | ||
773 | MODULE_DEVICE_TABLE(of, xgene_hwmon_of_match); | ||
774 | |||
775 | static struct platform_driver xgene_hwmon_driver __refdata = { | ||
776 | .probe = xgene_hwmon_probe, | ||
777 | .remove = xgene_hwmon_remove, | ||
778 | .driver = { | ||
779 | .name = "xgene-slimpro-hwmon", | ||
780 | .of_match_table = xgene_hwmon_of_match, | ||
781 | .acpi_match_table = ACPI_PTR(xgene_hwmon_acpi_match), | ||
782 | }, | ||
783 | }; | ||
784 | module_platform_driver(xgene_hwmon_driver); | ||
785 | |||
786 | MODULE_DESCRIPTION("APM X-Gene SoC hardware monitor"); | ||
787 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index 09354f6c1d63..9d2f8bde7d12 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h | |||
@@ -14,9 +14,341 @@ | |||
14 | #ifndef _HWMON_H_ | 14 | #ifndef _HWMON_H_ |
15 | #define _HWMON_H_ | 15 | #define _HWMON_H_ |
16 | 16 | ||
17 | #include <linux/bitops.h> | ||
18 | |||
17 | struct device; | 19 | struct device; |
18 | struct attribute_group; | 20 | struct attribute_group; |
19 | 21 | ||
22 | enum hwmon_sensor_types { | ||
23 | hwmon_chip, | ||
24 | hwmon_temp, | ||
25 | hwmon_in, | ||
26 | hwmon_curr, | ||
27 | hwmon_power, | ||
28 | hwmon_energy, | ||
29 | hwmon_humidity, | ||
30 | hwmon_fan, | ||
31 | hwmon_pwm, | ||
32 | }; | ||
33 | |||
34 | enum hwmon_chip_attributes { | ||
35 | hwmon_chip_temp_reset_history, | ||
36 | hwmon_chip_in_reset_history, | ||
37 | hwmon_chip_curr_reset_history, | ||
38 | hwmon_chip_power_reset_history, | ||
39 | hwmon_chip_register_tz, | ||
40 | hwmon_chip_update_interval, | ||
41 | hwmon_chip_alarms, | ||
42 | }; | ||
43 | |||
44 | #define HWMON_C_TEMP_RESET_HISTORY BIT(hwmon_chip_temp_reset_history) | ||
45 | #define HWMON_C_IN_RESET_HISTORY BIT(hwmon_chip_in_reset_history) | ||
46 | #define HWMON_C_CURR_RESET_HISTORY BIT(hwmon_chip_curr_reset_history) | ||
47 | #define HWMON_C_POWER_RESET_HISTORY BIT(hwmon_chip_power_reset_history) | ||
48 | #define HWMON_C_REGISTER_TZ BIT(hwmon_chip_register_tz) | ||
49 | #define HWMON_C_UPDATE_INTERVAL BIT(hwmon_chip_update_interval) | ||
50 | #define HWMON_C_ALARMS BIT(hwmon_chip_alarms) | ||
51 | |||
52 | enum hwmon_temp_attributes { | ||
53 | hwmon_temp_input = 0, | ||
54 | hwmon_temp_type, | ||
55 | hwmon_temp_lcrit, | ||
56 | hwmon_temp_lcrit_hyst, | ||
57 | hwmon_temp_min, | ||
58 | hwmon_temp_min_hyst, | ||
59 | hwmon_temp_max, | ||
60 | hwmon_temp_max_hyst, | ||
61 | hwmon_temp_crit, | ||
62 | hwmon_temp_crit_hyst, | ||
63 | hwmon_temp_emergency, | ||
64 | hwmon_temp_emergency_hyst, | ||
65 | hwmon_temp_alarm, | ||
66 | hwmon_temp_lcrit_alarm, | ||
67 | hwmon_temp_min_alarm, | ||
68 | hwmon_temp_max_alarm, | ||
69 | hwmon_temp_crit_alarm, | ||
70 | hwmon_temp_emergency_alarm, | ||
71 | hwmon_temp_fault, | ||
72 | hwmon_temp_offset, | ||
73 | hwmon_temp_label, | ||
74 | hwmon_temp_lowest, | ||
75 | hwmon_temp_highest, | ||
76 | hwmon_temp_reset_history, | ||
77 | }; | ||
78 | |||
79 | #define HWMON_T_INPUT BIT(hwmon_temp_input) | ||
80 | #define HWMON_T_TYPE BIT(hwmon_temp_type) | ||
81 | #define HWMON_T_LCRIT BIT(hwmon_temp_lcrit) | ||
82 | #define HWMON_T_LCRIT_HYST BIT(hwmon_temp_lcrit_hyst) | ||
83 | #define HWMON_T_MIN BIT(hwmon_temp_min) | ||
84 | #define HWMON_T_MIN_HYST BIT(hwmon_temp_min_hyst) | ||
85 | #define HWMON_T_MAX BIT(hwmon_temp_max) | ||
86 | #define HWMON_T_MAX_HYST BIT(hwmon_temp_max_hyst) | ||
87 | #define HWMON_T_CRIT BIT(hwmon_temp_crit) | ||
88 | #define HWMON_T_CRIT_HYST BIT(hwmon_temp_crit_hyst) | ||
89 | #define HWMON_T_EMERGENCY BIT(hwmon_temp_emergency) | ||
90 | #define HWMON_T_EMERGENCY_HYST BIT(hwmon_temp_emergency_hyst) | ||
91 | #define HWMON_T_MIN_ALARM BIT(hwmon_temp_min_alarm) | ||
92 | #define HWMON_T_MAX_ALARM BIT(hwmon_temp_max_alarm) | ||
93 | #define HWMON_T_CRIT_ALARM BIT(hwmon_temp_crit_alarm) | ||
94 | #define HWMON_T_EMERGENCY_ALARM BIT(hwmon_temp_emergency_alarm) | ||
95 | #define HWMON_T_FAULT BIT(hwmon_temp_fault) | ||
96 | #define HWMON_T_OFFSET BIT(hwmon_temp_offset) | ||
97 | #define HWMON_T_LABEL BIT(hwmon_temp_label) | ||
98 | #define HWMON_T_LOWEST BIT(hwmon_temp_lowest) | ||
99 | #define HWMON_T_HIGHEST BIT(hwmon_temp_highest) | ||
100 | #define HWMON_T_RESET_HISTORY BIT(hwmon_temp_reset_history) | ||
101 | |||
102 | enum hwmon_in_attributes { | ||
103 | hwmon_in_input, | ||
104 | hwmon_in_min, | ||
105 | hwmon_in_max, | ||
106 | hwmon_in_lcrit, | ||
107 | hwmon_in_crit, | ||
108 | hwmon_in_average, | ||
109 | hwmon_in_lowest, | ||
110 | hwmon_in_highest, | ||
111 | hwmon_in_reset_history, | ||
112 | hwmon_in_label, | ||
113 | hwmon_in_alarm, | ||
114 | hwmon_in_min_alarm, | ||
115 | hwmon_in_max_alarm, | ||
116 | hwmon_in_lcrit_alarm, | ||
117 | hwmon_in_crit_alarm, | ||
118 | }; | ||
119 | |||
120 | #define HWMON_I_INPUT BIT(hwmon_in_input) | ||
121 | #define HWMON_I_MIN BIT(hwmon_in_min) | ||
122 | #define HWMON_I_MAX BIT(hwmon_in_max) | ||
123 | #define HWMON_I_LCRIT BIT(hwmon_in_lcrit) | ||
124 | #define HWMON_I_CRIT BIT(hwmon_in_crit) | ||
125 | #define HWMON_I_AVERAGE BIT(hwmon_in_average) | ||
126 | #define HWMON_I_LOWEST BIT(hwmon_in_lowest) | ||
127 | #define HWMON_I_HIGHEST BIT(hwmon_in_highest) | ||
128 | #define HWMON_I_RESET_HISTORY BIT(hwmon_in_reset_history) | ||
129 | #define HWMON_I_LABEL BIT(hwmon_in_label) | ||
130 | #define HWMON_I_ALARM BIT(hwmon_in_alarm) | ||
131 | #define HWMON_I_MIN_ALARM BIT(hwmon_in_min_alarm) | ||
132 | #define HWMON_I_MAX_ALARM BIT(hwmon_in_max_alarm) | ||
133 | #define HWMON_I_LCRIT_ALARM BIT(hwmon_in_lcrit_alarm) | ||
134 | #define HWMON_I_CRIT_ALARM BIT(hwmon_in_crit_alarm) | ||
135 | |||
136 | enum hwmon_curr_attributes { | ||
137 | hwmon_curr_input, | ||
138 | hwmon_curr_min, | ||
139 | hwmon_curr_max, | ||
140 | hwmon_curr_lcrit, | ||
141 | hwmon_curr_crit, | ||
142 | hwmon_curr_average, | ||
143 | hwmon_curr_lowest, | ||
144 | hwmon_curr_highest, | ||
145 | hwmon_curr_reset_history, | ||
146 | hwmon_curr_label, | ||
147 | hwmon_curr_alarm, | ||
148 | hwmon_curr_min_alarm, | ||
149 | hwmon_curr_max_alarm, | ||
150 | hwmon_curr_lcrit_alarm, | ||
151 | hwmon_curr_crit_alarm, | ||
152 | }; | ||
153 | |||
154 | #define HWMON_C_INPUT BIT(hwmon_curr_input) | ||
155 | #define HWMON_C_MIN BIT(hwmon_curr_min) | ||
156 | #define HWMON_C_MAX BIT(hwmon_curr_max) | ||
157 | #define HWMON_C_LCRIT BIT(hwmon_curr_lcrit) | ||
158 | #define HWMON_C_CRIT BIT(hwmon_curr_crit) | ||
159 | #define HWMON_C_AVERAGE BIT(hwmon_curr_average) | ||
160 | #define HWMON_C_LOWEST BIT(hwmon_curr_lowest) | ||
161 | #define HWMON_C_HIGHEST BIT(hwmon_curr_highest) | ||
162 | #define HWMON_C_RESET_HISTORY BIT(hwmon_curr_reset_history) | ||
163 | #define HWMON_C_LABEL BIT(hwmon_curr_label) | ||
164 | #define HWMON_C_ALARM BIT(hwmon_curr_alarm) | ||
165 | #define HWMON_C_MIN_ALARM BIT(hwmon_curr_min_alarm) | ||
166 | #define HWMON_C_MAX_ALARM BIT(hwmon_curr_max_alarm) | ||
167 | #define HWMON_C_LCRIT_ALARM BIT(hwmon_curr_lcrit_alarm) | ||
168 | #define HWMON_C_CRIT_ALARM BIT(hwmon_curr_crit_alarm) | ||
169 | |||
170 | enum hwmon_power_attributes { | ||
171 | hwmon_power_average, | ||
172 | hwmon_power_average_interval, | ||
173 | hwmon_power_average_interval_max, | ||
174 | hwmon_power_average_interval_min, | ||
175 | hwmon_power_average_highest, | ||
176 | hwmon_power_average_lowest, | ||
177 | hwmon_power_average_max, | ||
178 | hwmon_power_average_min, | ||
179 | hwmon_power_input, | ||
180 | hwmon_power_input_highest, | ||
181 | hwmon_power_input_lowest, | ||
182 | hwmon_power_reset_history, | ||
183 | hwmon_power_accuracy, | ||
184 | hwmon_power_cap, | ||
185 | hwmon_power_cap_hyst, | ||
186 | hwmon_power_cap_max, | ||
187 | hwmon_power_cap_min, | ||
188 | hwmon_power_max, | ||
189 | hwmon_power_crit, | ||
190 | hwmon_power_label, | ||
191 | hwmon_power_alarm, | ||
192 | hwmon_power_cap_alarm, | ||
193 | hwmon_power_max_alarm, | ||
194 | hwmon_power_crit_alarm, | ||
195 | }; | ||
196 | |||
197 | #define HWMON_P_AVERAGE BIT(hwmon_power_average) | ||
198 | #define HWMON_P_AVERAGE_INTERVAL BIT(hwmon_power_average_interval) | ||
199 | #define HWMON_P_AVERAGE_INTERVAL_MAX BIT(hwmon_power_average_interval_max) | ||
200 | #define HWMON_P_AVERAGE_INTERVAL_MIN BIT(hwmon_power_average_interval_min) | ||
201 | #define HWMON_P_AVERAGE_HIGHEST BIT(hwmon_power_average_highest) | ||
202 | #define HWMON_P_AVERAGE_LOWEST BIT(hwmon_power_average_lowest) | ||
203 | #define HWMON_P_AVERAGE_MAX BIT(hwmon_power_average_max) | ||
204 | #define HWMON_P_AVERAGE_MIN BIT(hwmon_power_average_min) | ||
205 | #define HWMON_P_INPUT BIT(hwmon_power_input) | ||
206 | #define HWMON_P_INPUT_HIGHEST BIT(hwmon_power_input_highest) | ||
207 | #define HWMON_P_INPUT_LOWEST BIT(hwmon_power_input_lowest) | ||
208 | #define HWMON_P_RESET_HISTORY BIT(hwmon_power_reset_history) | ||
209 | #define HWMON_P_ACCURACY BIT(hwmon_power_accuracy) | ||
210 | #define HWMON_P_CAP BIT(hwmon_power_cap) | ||
211 | #define HWMON_P_CAP_HYST BIT(hwmon_power_cap_hyst) | ||
212 | #define HWMON_P_CAP_MAX BIT(hwmon_power_cap_max) | ||
213 | #define HWMON_P_CAP_MIN BIT(hwmon_power_cap_min) | ||
214 | #define HWMON_P_MAX BIT(hwmon_power_max) | ||
215 | #define HWMON_P_CRIT BIT(hwmon_power_crit) | ||
216 | #define HWMON_P_LABEL BIT(hwmon_power_label) | ||
217 | #define HWMON_P_ALARM BIT(hwmon_power_alarm) | ||
218 | #define HWMON_P_CAP_ALARM BIT(hwmon_power_cap_alarm) | ||
219 | #define HWMON_P_MAX_ALARM BIT(hwmon_power_max_alarm) | ||
220 | #define HWMON_P_CRIT_ALARM BIT(hwmon_power_crit_alarm) | ||
221 | |||
222 | enum hwmon_energy_attributes { | ||
223 | hwmon_energy_input, | ||
224 | hwmon_energy_label, | ||
225 | }; | ||
226 | |||
227 | #define HWMON_E_INPUT BIT(hwmon_energy_input) | ||
228 | #define HWMON_E_LABEL BIT(hwmon_energy_label) | ||
229 | |||
230 | enum hwmon_humidity_attributes { | ||
231 | hwmon_humidity_input, | ||
232 | hwmon_humidity_label, | ||
233 | hwmon_humidity_min, | ||
234 | hwmon_humidity_min_hyst, | ||
235 | hwmon_humidity_max, | ||
236 | hwmon_humidity_max_hyst, | ||
237 | hwmon_humidity_alarm, | ||
238 | hwmon_humidity_fault, | ||
239 | }; | ||
240 | |||
241 | #define HWMON_H_INPUT BIT(hwmon_humidity_input) | ||
242 | #define HWMON_H_LABEL BIT(hwmon_humidity_label) | ||
243 | #define HWMON_H_MIN BIT(hwmon_humidity_min) | ||
244 | #define HWMON_H_MIN_HYST BIT(hwmon_humidity_min_hyst) | ||
245 | #define HWMON_H_MAX BIT(hwmon_humidity_max) | ||
246 | #define HWMON_H_MAX_HYST BIT(hwmon_humidity_max_hyst) | ||
247 | #define HWMON_H_ALARM BIT(hwmon_humidity_alarm) | ||
248 | #define HWMON_H_FAULT BIT(hwmon_humidity_fault) | ||
249 | |||
250 | enum hwmon_fan_attributes { | ||
251 | hwmon_fan_input, | ||
252 | hwmon_fan_label, | ||
253 | hwmon_fan_min, | ||
254 | hwmon_fan_max, | ||
255 | hwmon_fan_div, | ||
256 | hwmon_fan_pulses, | ||
257 | hwmon_fan_target, | ||
258 | hwmon_fan_alarm, | ||
259 | hwmon_fan_min_alarm, | ||
260 | hwmon_fan_max_alarm, | ||
261 | hwmon_fan_fault, | ||
262 | }; | ||
263 | |||
264 | #define HWMON_F_INPUT BIT(hwmon_fan_input) | ||
265 | #define HWMON_F_LABEL BIT(hwmon_fan_label) | ||
266 | #define HWMON_F_MIN BIT(hwmon_fan_min) | ||
267 | #define HWMON_F_MAX BIT(hwmon_fan_max) | ||
268 | #define HWMON_F_DIV BIT(hwmon_fan_div) | ||
269 | #define HWMON_F_PULSES BIT(hwmon_fan_pulses) | ||
270 | #define HWMON_F_TARGET BIT(hwmon_fan_target) | ||
271 | #define HWMON_F_ALARM BIT(hwmon_fan_alarm) | ||
272 | #define HWMON_F_MIN_ALARM BIT(hwmon_fan_min_alarm) | ||
273 | #define HWMON_F_MAX_ALARM BIT(hwmon_fan_max_alarm) | ||
274 | #define HWMON_F_FAULT BIT(hwmon_fan_fault) | ||
275 | |||
276 | enum hwmon_pwm_attributes { | ||
277 | hwmon_pwm_input, | ||
278 | hwmon_pwm_enable, | ||
279 | hwmon_pwm_mode, | ||
280 | hwmon_pwm_freq, | ||
281 | }; | ||
282 | |||
283 | #define HWMON_PWM_INPUT BIT(hwmon_pwm_input) | ||
284 | #define HWMON_PWM_ENABLE BIT(hwmon_pwm_enable) | ||
285 | #define HWMON_PWM_MODE BIT(hwmon_pwm_mode) | ||
286 | #define HWMON_PWM_FREQ BIT(hwmon_pwm_freq) | ||
287 | |||
288 | /** | ||
289 | * struct hwmon_ops - hwmon device operations | ||
290 | * @is_visible: Callback to return attribute visibility. Mandatory. | ||
291 | * Parameters are: | ||
292 | * @const void *drvdata: | ||
293 | * Pointer to driver-private data structure passed | ||
294 | * as argument to hwmon_device_register_with_info(). | ||
295 | * @type: Sensor type | ||
296 | * @attr: Sensor attribute | ||
297 | * @channel: | ||
298 | * Channel number | ||
299 | * The function returns the file permissions. | ||
300 | * If the return value is 0, no attribute will be created. | ||
301 | * @read: Read callback. Optional. If not provided, attributes | ||
302 | * will not be readable. | ||
303 | * Parameters are: | ||
304 | * @dev: Pointer to hardware monitoring device | ||
305 | * @type: Sensor type | ||
306 | * @attr: Sensor attribute | ||
307 | * @channel: | ||
308 | * Channel number | ||
309 | * @val: Pointer to returned value | ||
310 | * The function returns 0 on success or a negative error number. | ||
311 | * @write: Write callback. Optional. If not provided, attributes | ||
312 | * will not be writable. | ||
313 | * Parameters are: | ||
314 | * @dev: Pointer to hardware monitoring device | ||
315 | * @type: Sensor type | ||
316 | * @attr: Sensor attribute | ||
317 | * @channel: | ||
318 | * Channel number | ||
319 | * @val: Value to write | ||
320 | * The function returns 0 on success or a negative error number. | ||
321 | */ | ||
322 | struct hwmon_ops { | ||
323 | umode_t (*is_visible)(const void *drvdata, enum hwmon_sensor_types type, | ||
324 | u32 attr, int channel); | ||
325 | int (*read)(struct device *dev, enum hwmon_sensor_types type, | ||
326 | u32 attr, int channel, long *val); | ||
327 | int (*write)(struct device *dev, enum hwmon_sensor_types type, | ||
328 | u32 attr, int channel, long val); | ||
329 | }; | ||
330 | |||
331 | /** | ||
332 | * Channel information | ||
333 | * @type: Channel type. | ||
334 | * @config: Pointer to NULL-terminated list of channel parameters. | ||
335 | * Use for per-channel attributes. | ||
336 | */ | ||
337 | struct hwmon_channel_info { | ||
338 | enum hwmon_sensor_types type; | ||
339 | const u32 *config; | ||
340 | }; | ||
341 | |||
342 | /** | ||
343 | * Chip configuration | ||
344 | * @ops: Pointer to hwmon operations. | ||
345 | * @info: Null-terminated list of channel information. | ||
346 | */ | ||
347 | struct hwmon_chip_info { | ||
348 | const struct hwmon_ops *ops; | ||
349 | const struct hwmon_channel_info **info; | ||
350 | }; | ||
351 | |||
20 | struct device *hwmon_device_register(struct device *dev); | 352 | struct device *hwmon_device_register(struct device *dev); |
21 | struct device * | 353 | struct device * |
22 | hwmon_device_register_with_groups(struct device *dev, const char *name, | 354 | hwmon_device_register_with_groups(struct device *dev, const char *name, |
@@ -26,6 +358,16 @@ struct device * | |||
26 | devm_hwmon_device_register_with_groups(struct device *dev, const char *name, | 358 | devm_hwmon_device_register_with_groups(struct device *dev, const char *name, |
27 | void *drvdata, | 359 | void *drvdata, |
28 | const struct attribute_group **groups); | 360 | const struct attribute_group **groups); |
361 | struct device * | ||
362 | hwmon_device_register_with_info(struct device *dev, | ||
363 | const char *name, void *drvdata, | ||
364 | const struct hwmon_chip_info *info, | ||
365 | const struct attribute_group **groups); | ||
366 | struct device * | ||
367 | devm_hwmon_device_register_with_info(struct device *dev, | ||
368 | const char *name, void *drvdata, | ||
369 | const struct hwmon_chip_info *info, | ||
370 | const struct attribute_group **groups); | ||
29 | 371 | ||
30 | void hwmon_device_unregister(struct device *dev); | 372 | void hwmon_device_unregister(struct device *dev); |
31 | void devm_hwmon_device_unregister(struct device *dev); | 373 | void devm_hwmon_device_unregister(struct device *dev); |