diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
commit | 7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch) | |
tree | e730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/hwmon | |
parent | 41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) |
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'drivers/hwmon')
38 files changed, 4580 insertions, 2152 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 00ff53348491..6de1e0ffd391 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -57,6 +57,16 @@ config SENSORS_ABITUGURU3 | |||
57 | This driver can also be built as a module. If so, the module | 57 | This driver can also be built as a module. If so, the module |
58 | will be called abituguru3. | 58 | will be called abituguru3. |
59 | 59 | ||
60 | config SENSORS_AD7414 | ||
61 | tristate "Analog Devices AD7414" | ||
62 | depends on I2C && EXPERIMENTAL | ||
63 | help | ||
64 | If you say yes here you get support for the Analog Devices | ||
65 | AD7414 temperature monitoring chip. | ||
66 | |||
67 | This driver can also be built as a module. If so, the module | ||
68 | will be called ad7414. | ||
69 | |||
60 | config SENSORS_AD7418 | 70 | config SENSORS_AD7418 |
61 | tristate "Analog Devices AD7416, AD7417 and AD7418" | 71 | tristate "Analog Devices AD7416, AD7417 and AD7418" |
62 | depends on I2C && EXPERIMENTAL | 72 | depends on I2C && EXPERIMENTAL |
@@ -67,6 +77,22 @@ config SENSORS_AD7418 | |||
67 | This driver can also be built as a module. If so, the module | 77 | This driver can also be built as a module. If so, the module |
68 | will be called ad7418. | 78 | will be called ad7418. |
69 | 79 | ||
80 | config SENSORS_ADCXX | ||
81 | tristate "National Semiconductor ADCxxxSxxx" | ||
82 | depends on SPI_MASTER && EXPERIMENTAL | ||
83 | help | ||
84 | If you say yes here you get support for the National Semiconductor | ||
85 | ADC<bb><c>S<sss> chip family, where | ||
86 | * bb is the resolution in number of bits (8, 10, 12) | ||
87 | * c is the number of channels (1, 2, 4, 8) | ||
88 | * sss is the maximum conversion speed (021 for 200 kSPS, 051 for 500 | ||
89 | kSPS and 101 for 1 MSPS) | ||
90 | |||
91 | Examples : ADC081S101, ADC124S501, ... | ||
92 | |||
93 | This driver can also be built as a module. If so, the module | ||
94 | will be called adcxx. | ||
95 | |||
70 | config SENSORS_ADM1021 | 96 | config SENSORS_ADM1021 |
71 | tristate "Analog Devices ADM1021 and compatibles" | 97 | tristate "Analog Devices ADM1021 and compatibles" |
72 | depends on I2C | 98 | depends on I2C |
@@ -124,7 +150,7 @@ config SENSORS_ADM1031 | |||
124 | 150 | ||
125 | config SENSORS_ADM9240 | 151 | config SENSORS_ADM9240 |
126 | tristate "Analog Devices ADM9240 and compatibles" | 152 | tristate "Analog Devices ADM9240 and compatibles" |
127 | depends on I2C && EXPERIMENTAL | 153 | depends on I2C |
128 | select HWMON_VID | 154 | select HWMON_VID |
129 | help | 155 | help |
130 | If you say yes here you get support for Analog Devices ADM9240, | 156 | If you say yes here you get support for Analog Devices ADM9240, |
@@ -394,13 +420,24 @@ config SENSORS_LM75 | |||
394 | tristate "National Semiconductor LM75 and compatibles" | 420 | tristate "National Semiconductor LM75 and compatibles" |
395 | depends on I2C | 421 | depends on I2C |
396 | help | 422 | help |
397 | If you say yes here you get support for National Semiconductor LM75 | 423 | If you say yes here you get support for one common type of |
398 | sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in | 424 | temperature sensor chip, with models including: |
399 | 9-bit precision mode), and TelCom (now Microchip) TCN75. | ||
400 | 425 | ||
401 | The DS75 and DS1775 in 10- to 12-bit precision modes will require | 426 | - Dallas Semiconductor DS75 and DS1775 |
402 | a force module parameter. The driver will not handle the extra | 427 | - Maxim MAX6625 and MAX6626 |
403 | precision anyhow. | 428 | - Microchip MCP980x |
429 | - National Semiconductor LM75 | ||
430 | - NXP's LM75A | ||
431 | - ST Microelectronics STDS75 | ||
432 | - TelCom (now Microchip) TCN75 | ||
433 | - Texas Instruments TMP100, TMP101, TMP75, TMP175, TMP275 | ||
434 | |||
435 | This driver supports driver model based binding through board | ||
436 | specific I2C device tables. | ||
437 | |||
438 | It also supports the "legacy" style of driver binding. To use | ||
439 | that with some chips which don't replicate LM75 quirks exactly, | ||
440 | you may need the "force" module parameter. | ||
404 | 441 | ||
405 | This driver can also be built as a module. If so, the module | 442 | This driver can also be built as a module. If so, the module |
406 | will be called lm75. | 443 | will be called lm75. |
@@ -473,11 +510,9 @@ config SENSORS_LM90 | |||
473 | depends on I2C | 510 | depends on I2C |
474 | help | 511 | help |
475 | If you say yes here you get support for National Semiconductor LM90, | 512 | If you say yes here you get support for National Semiconductor LM90, |
476 | LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657, | 513 | LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim |
477 | MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips. | 514 | MAX6646, MAX6647, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680 and |
478 | 515 | MAX6681 sensor chips. | |
479 | The Analog Devices ADT7461 sensor chip is also supported, but only | ||
480 | if found in ADM1032 compatibility mode. | ||
481 | 516 | ||
482 | This driver can also be built as a module. If so, the module | 517 | This driver can also be built as a module. If so, the module |
483 | will be called lm90. | 518 | will be called lm90. |
@@ -503,6 +538,15 @@ config SENSORS_LM93 | |||
503 | This driver can also be built as a module. If so, the module | 538 | This driver can also be built as a module. If so, the module |
504 | will be called lm93. | 539 | will be called lm93. |
505 | 540 | ||
541 | config SENSORS_MAX1111 | ||
542 | tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" | ||
543 | depends on SPI_MASTER | ||
544 | help | ||
545 | Say y here to support Maxim's MAX1111 ADC chips. | ||
546 | |||
547 | This driver can also be built as a module. If so, the module | ||
548 | will be called max1111. | ||
549 | |||
506 | config SENSORS_MAX1619 | 550 | config SENSORS_MAX1619 |
507 | tristate "Maxim MAX1619 sensor chip" | 551 | tristate "Maxim MAX1619 sensor chip" |
508 | depends on I2C | 552 | depends on I2C |
@@ -564,8 +608,8 @@ config SENSORS_DME1737 | |||
564 | select HWMON_VID | 608 | select HWMON_VID |
565 | help | 609 | help |
566 | If you say yes here you get support for the hardware monitoring | 610 | If you say yes here you get support for the hardware monitoring |
567 | and fan control features of the SMSC DME1737 (and compatibles | 611 | and fan control features of the SMSC DME1737, SCH311x, SCH5027, and |
568 | like the Asus A8000) and SCH311x Super-I/O chips. | 612 | Asus A8000 Super-I/O chips. |
569 | 613 | ||
570 | This driver can also be built as a module. If so, the module | 614 | This driver can also be built as a module. If so, the module |
571 | will be called dme1737. | 615 | will be called dme1737. |
@@ -754,6 +798,13 @@ config SENSORS_W83627EHF | |||
754 | This driver can also be built as a module. If so, the module | 798 | This driver can also be built as a module. If so, the module |
755 | will be called w83627ehf. | 799 | will be called w83627ehf. |
756 | 800 | ||
801 | config SENSORS_ULTRA45 | ||
802 | tristate "Sun Ultra45 PIC16F747" | ||
803 | depends on SPARC64 | ||
804 | help | ||
805 | This driver provides support for the Ultra45 workstation environmental | ||
806 | sensors. | ||
807 | |||
757 | config SENSORS_HDAPS | 808 | config SENSORS_HDAPS |
758 | tristate "IBM Hard Drive Active Protection System (hdaps)" | 809 | tristate "IBM Hard Drive Active Protection System (hdaps)" |
759 | depends on INPUT && X86 | 810 | depends on INPUT && X86 |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index d098677e08de..042d5a78622e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -15,7 +15,9 @@ obj-$(CONFIG_SENSORS_W83791D) += w83791d.o | |||
15 | 15 | ||
16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o | 16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o |
17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o | 17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o |
18 | obj-$(CONFIG_SENSORS_AD7414) += ad7414.o | ||
18 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o | 19 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o |
20 | obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o | ||
19 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o | 21 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o |
20 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o | 22 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o |
21 | obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o | 23 | obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o |
@@ -39,6 +41,7 @@ obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o | |||
39 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | 41 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o |
40 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 42 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
41 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 43 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
44 | obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o | ||
42 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 45 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
43 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | 46 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o |
44 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | 47 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o |
@@ -57,6 +60,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o | |||
57 | obj-$(CONFIG_SENSORS_LM90) += lm90.o | 60 | obj-$(CONFIG_SENSORS_LM90) += lm90.o |
58 | obj-$(CONFIG_SENSORS_LM92) += lm92.o | 61 | obj-$(CONFIG_SENSORS_LM92) += lm92.o |
59 | obj-$(CONFIG_SENSORS_LM93) += lm93.o | 62 | obj-$(CONFIG_SENSORS_LM93) += lm93.o |
63 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o | ||
60 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 64 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
61 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | 65 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o |
62 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 66 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index f00f497b9ca9..70bb854086df 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -1,5 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | abituguru3.c Copyright (c) 2006 Hans de Goede <j.w.r.degoede@hhs.nl> | 2 | abituguru3.c |
3 | |||
4 | Copyright (c) 2006-2008 Hans de Goede <j.w.r.degoede@hhs.nl> | ||
5 | Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk> | ||
3 | 6 | ||
4 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by |
@@ -116,7 +119,7 @@ struct abituguru3_sensor_info { | |||
116 | 119 | ||
117 | struct abituguru3_motherboard_info { | 120 | struct abituguru3_motherboard_info { |
118 | u16 id; | 121 | u16 id; |
119 | const char *name; | 122 | const char *dmi_name; |
120 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ | 123 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ |
121 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; | 124 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; |
122 | }; | 125 | }; |
@@ -161,7 +164,7 @@ struct abituguru3_data { | |||
161 | 164 | ||
162 | /* Constants */ | 165 | /* Constants */ |
163 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | 166 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { |
164 | { 0x000C, "unknown", { | 167 | { 0x000C, NULL /* Unknown, need DMI string */, { |
165 | { "CPU Core", 0, 0, 10, 1, 0 }, | 168 | { "CPU Core", 0, 0, 10, 1, 0 }, |
166 | { "DDR", 1, 0, 10, 1, 0 }, | 169 | { "DDR", 1, 0, 10, 1, 0 }, |
167 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 170 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -175,7 +178,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
175 | { "+3.3V", 10, 0, 20, 1, 0 }, | 178 | { "+3.3V", 10, 0, 20, 1, 0 }, |
176 | { "5VSB", 11, 0, 30, 1, 0 }, | 179 | { "5VSB", 11, 0, 30, 1, 0 }, |
177 | { "CPU", 24, 1, 1, 1, 0 }, | 180 | { "CPU", 24, 1, 1, 1, 0 }, |
178 | { "System ", 25, 1, 1, 1, 0 }, | 181 | { "System", 25, 1, 1, 1, 0 }, |
179 | { "PWM", 26, 1, 1, 1, 0 }, | 182 | { "PWM", 26, 1, 1, 1, 0 }, |
180 | { "CPU Fan", 32, 2, 60, 1, 0 }, | 183 | { "CPU Fan", 32, 2, 60, 1, 0 }, |
181 | { "NB Fan", 33, 2, 60, 1, 0 }, | 184 | { "NB Fan", 33, 2, 60, 1, 0 }, |
@@ -183,7 +186,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
183 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | 186 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, |
184 | { NULL, 0, 0, 0, 0, 0 } } | 187 | { NULL, 0, 0, 0, 0, 0 } } |
185 | }, | 188 | }, |
186 | { 0x000D, "Abit AW8", { | 189 | { 0x000D, NULL /* Abit AW8, need DMI string */, { |
187 | { "CPU Core", 0, 0, 10, 1, 0 }, | 190 | { "CPU Core", 0, 0, 10, 1, 0 }, |
188 | { "DDR", 1, 0, 10, 1, 0 }, | 191 | { "DDR", 1, 0, 10, 1, 0 }, |
189 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 192 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -197,7 +200,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
197 | { "+3.3V", 10, 0, 20, 1, 0 }, | 200 | { "+3.3V", 10, 0, 20, 1, 0 }, |
198 | { "5VSB", 11, 0, 30, 1, 0 }, | 201 | { "5VSB", 11, 0, 30, 1, 0 }, |
199 | { "CPU", 24, 1, 1, 1, 0 }, | 202 | { "CPU", 24, 1, 1, 1, 0 }, |
200 | { "System ", 25, 1, 1, 1, 0 }, | 203 | { "System", 25, 1, 1, 1, 0 }, |
201 | { "PWM1", 26, 1, 1, 1, 0 }, | 204 | { "PWM1", 26, 1, 1, 1, 0 }, |
202 | { "PWM2", 27, 1, 1, 1, 0 }, | 205 | { "PWM2", 27, 1, 1, 1, 0 }, |
203 | { "PWM3", 28, 1, 1, 1, 0 }, | 206 | { "PWM3", 28, 1, 1, 1, 0 }, |
@@ -212,7 +215,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
212 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 215 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
213 | { NULL, 0, 0, 0, 0, 0 } } | 216 | { NULL, 0, 0, 0, 0, 0 } } |
214 | }, | 217 | }, |
215 | { 0x000E, "AL-8", { | 218 | { 0x000E, NULL /* AL-8, need DMI string */, { |
216 | { "CPU Core", 0, 0, 10, 1, 0 }, | 219 | { "CPU Core", 0, 0, 10, 1, 0 }, |
217 | { "DDR", 1, 0, 10, 1, 0 }, | 220 | { "DDR", 1, 0, 10, 1, 0 }, |
218 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 221 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -226,14 +229,14 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
226 | { "+3.3V", 10, 0, 20, 1, 0 }, | 229 | { "+3.3V", 10, 0, 20, 1, 0 }, |
227 | { "5VSB", 11, 0, 30, 1, 0 }, | 230 | { "5VSB", 11, 0, 30, 1, 0 }, |
228 | { "CPU", 24, 1, 1, 1, 0 }, | 231 | { "CPU", 24, 1, 1, 1, 0 }, |
229 | { "System ", 25, 1, 1, 1, 0 }, | 232 | { "System", 25, 1, 1, 1, 0 }, |
230 | { "PWM", 26, 1, 1, 1, 0 }, | 233 | { "PWM", 26, 1, 1, 1, 0 }, |
231 | { "CPU Fan", 32, 2, 60, 1, 0 }, | 234 | { "CPU Fan", 32, 2, 60, 1, 0 }, |
232 | { "NB Fan", 33, 2, 60, 1, 0 }, | 235 | { "NB Fan", 33, 2, 60, 1, 0 }, |
233 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 236 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
234 | { NULL, 0, 0, 0, 0, 0 } } | 237 | { NULL, 0, 0, 0, 0, 0 } } |
235 | }, | 238 | }, |
236 | { 0x000F, "unknown", { | 239 | { 0x000F, NULL /* Unknown, need DMI string */, { |
237 | { "CPU Core", 0, 0, 10, 1, 0 }, | 240 | { "CPU Core", 0, 0, 10, 1, 0 }, |
238 | { "DDR", 1, 0, 10, 1, 0 }, | 241 | { "DDR", 1, 0, 10, 1, 0 }, |
239 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 242 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -247,14 +250,14 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
247 | { "+3.3V", 10, 0, 20, 1, 0 }, | 250 | { "+3.3V", 10, 0, 20, 1, 0 }, |
248 | { "5VSB", 11, 0, 30, 1, 0 }, | 251 | { "5VSB", 11, 0, 30, 1, 0 }, |
249 | { "CPU", 24, 1, 1, 1, 0 }, | 252 | { "CPU", 24, 1, 1, 1, 0 }, |
250 | { "System ", 25, 1, 1, 1, 0 }, | 253 | { "System", 25, 1, 1, 1, 0 }, |
251 | { "PWM", 26, 1, 1, 1, 0 }, | 254 | { "PWM", 26, 1, 1, 1, 0 }, |
252 | { "CPU Fan", 32, 2, 60, 1, 0 }, | 255 | { "CPU Fan", 32, 2, 60, 1, 0 }, |
253 | { "NB Fan", 33, 2, 60, 1, 0 }, | 256 | { "NB Fan", 33, 2, 60, 1, 0 }, |
254 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 257 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
255 | { NULL, 0, 0, 0, 0, 0 } } | 258 | { NULL, 0, 0, 0, 0, 0 } } |
256 | }, | 259 | }, |
257 | { 0x0010, "Abit NI8 SLI GR", { | 260 | { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, { |
258 | { "CPU Core", 0, 0, 10, 1, 0 }, | 261 | { "CPU Core", 0, 0, 10, 1, 0 }, |
259 | { "DDR", 1, 0, 10, 1, 0 }, | 262 | { "DDR", 1, 0, 10, 1, 0 }, |
260 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 263 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -276,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
276 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, | 279 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, |
277 | { NULL, 0, 0, 0, 0, 0 } } | 280 | { NULL, 0, 0, 0, 0, 0 } } |
278 | }, | 281 | }, |
279 | { 0x0011, "Abit AT8 32X", { | 282 | { 0x0011, "AT8 32X(ATI RD580-ULI M1575)", { |
280 | { "CPU Core", 0, 0, 10, 1, 0 }, | 283 | { "CPU Core", 0, 0, 10, 1, 0 }, |
281 | { "DDR", 1, 0, 20, 1, 0 }, | 284 | { "DDR", 1, 0, 20, 1, 0 }, |
282 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 285 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -300,9 +303,10 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
300 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 303 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
301 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | 304 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, |
302 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | 305 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, |
306 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
303 | { NULL, 0, 0, 0, 0, 0 } } | 307 | { NULL, 0, 0, 0, 0, 0 } } |
304 | }, | 308 | }, |
305 | { 0x0012, "Abit AN8 32X", { | 309 | { 0x0012, NULL /* Abit AN8 32X, need DMI string */, { |
306 | { "CPU Core", 0, 0, 10, 1, 0 }, | 310 | { "CPU Core", 0, 0, 10, 1, 0 }, |
307 | { "DDR", 1, 0, 20, 1, 0 }, | 311 | { "DDR", 1, 0, 20, 1, 0 }, |
308 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 312 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -324,7 +328,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
324 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, | 328 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, |
325 | { NULL, 0, 0, 0, 0, 0 } } | 329 | { NULL, 0, 0, 0, 0, 0 } } |
326 | }, | 330 | }, |
327 | { 0x0013, "Abit AW8D", { | 331 | { 0x0013, NULL /* Abit AW8D, need DMI string */, { |
328 | { "CPU Core", 0, 0, 10, 1, 0 }, | 332 | { "CPU Core", 0, 0, 10, 1, 0 }, |
329 | { "DDR", 1, 0, 10, 1, 0 }, | 333 | { "DDR", 1, 0, 10, 1, 0 }, |
330 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 334 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -338,7 +342,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
338 | { "+3.3V", 10, 0, 20, 1, 0 }, | 342 | { "+3.3V", 10, 0, 20, 1, 0 }, |
339 | { "5VSB", 11, 0, 30, 1, 0 }, | 343 | { "5VSB", 11, 0, 30, 1, 0 }, |
340 | { "CPU", 24, 1, 1, 1, 0 }, | 344 | { "CPU", 24, 1, 1, 1, 0 }, |
341 | { "System ", 25, 1, 1, 1, 0 }, | 345 | { "System", 25, 1, 1, 1, 0 }, |
342 | { "PWM1", 26, 1, 1, 1, 0 }, | 346 | { "PWM1", 26, 1, 1, 1, 0 }, |
343 | { "PWM2", 27, 1, 1, 1, 0 }, | 347 | { "PWM2", 27, 1, 1, 1, 0 }, |
344 | { "PWM3", 28, 1, 1, 1, 0 }, | 348 | { "PWM3", 28, 1, 1, 1, 0 }, |
@@ -353,7 +357,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
353 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 357 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
354 | { NULL, 0, 0, 0, 0, 0 } } | 358 | { NULL, 0, 0, 0, 0, 0 } } |
355 | }, | 359 | }, |
356 | { 0x0014, "Abit AB9 Pro", { | 360 | { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, { |
357 | { "CPU Core", 0, 0, 10, 1, 0 }, | 361 | { "CPU Core", 0, 0, 10, 1, 0 }, |
358 | { "DDR", 1, 0, 10, 1, 0 }, | 362 | { "DDR", 1, 0, 10, 1, 0 }, |
359 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 363 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -367,14 +371,14 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
367 | { "+3.3V", 10, 0, 20, 1, 0 }, | 371 | { "+3.3V", 10, 0, 20, 1, 0 }, |
368 | { "5VSB", 11, 0, 30, 1, 0 }, | 372 | { "5VSB", 11, 0, 30, 1, 0 }, |
369 | { "CPU", 24, 1, 1, 1, 0 }, | 373 | { "CPU", 24, 1, 1, 1, 0 }, |
370 | { "System ", 25, 1, 1, 1, 0 }, | 374 | { "System", 25, 1, 1, 1, 0 }, |
371 | { "PWM", 26, 1, 1, 1, 0 }, | 375 | { "PWM", 26, 1, 1, 1, 0 }, |
372 | { "CPU Fan", 32, 2, 60, 1, 0 }, | 376 | { "CPU Fan", 32, 2, 60, 1, 0 }, |
373 | { "NB Fan", 33, 2, 60, 1, 0 }, | 377 | { "NB Fan", 33, 2, 60, 1, 0 }, |
374 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 378 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
375 | { NULL, 0, 0, 0, 0, 0 } } | 379 | { NULL, 0, 0, 0, 0, 0 } } |
376 | }, | 380 | }, |
377 | { 0x0015, "unknown", { | 381 | { 0x0015, NULL /* Unknown, need DMI string */, { |
378 | { "CPU Core", 0, 0, 10, 1, 0 }, | 382 | { "CPU Core", 0, 0, 10, 1, 0 }, |
379 | { "DDR", 1, 0, 20, 1, 0 }, | 383 | { "DDR", 1, 0, 20, 1, 0 }, |
380 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 384 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -398,7 +402,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
398 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 402 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
399 | { NULL, 0, 0, 0, 0, 0 } } | 403 | { NULL, 0, 0, 0, 0, 0 } } |
400 | }, | 404 | }, |
401 | { 0x0016, "AW9D-MAX", { | 405 | { 0x0016, "AW9D-MAX (Intel i975-ICH7)", { |
402 | { "CPU Core", 0, 0, 10, 1, 0 }, | 406 | { "CPU Core", 0, 0, 10, 1, 0 }, |
403 | { "DDR2", 1, 0, 20, 1, 0 }, | 407 | { "DDR2", 1, 0, 20, 1, 0 }, |
404 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 408 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -412,7 +416,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
412 | { "+3.3V", 10, 0, 20, 1, 0 }, | 416 | { "+3.3V", 10, 0, 20, 1, 0 }, |
413 | { "5VSB", 11, 0, 30, 1, 0 }, | 417 | { "5VSB", 11, 0, 30, 1, 0 }, |
414 | { "CPU", 24, 1, 1, 1, 0 }, | 418 | { "CPU", 24, 1, 1, 1, 0 }, |
415 | { "System ", 25, 1, 1, 1, 0 }, | 419 | { "System", 25, 1, 1, 1, 0 }, |
416 | { "PWM1", 26, 1, 1, 1, 0 }, | 420 | { "PWM1", 26, 1, 1, 1, 0 }, |
417 | { "PWM2", 27, 1, 1, 1, 0 }, | 421 | { "PWM2", 27, 1, 1, 1, 0 }, |
418 | { "PWM3", 28, 1, 1, 1, 0 }, | 422 | { "PWM3", 28, 1, 1, 1, 0 }, |
@@ -426,7 +430,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
426 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, | 430 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, |
427 | { NULL, 0, 0, 0, 0, 0 } } | 431 | { NULL, 0, 0, 0, 0, 0 } } |
428 | }, | 432 | }, |
429 | { 0x0017, "unknown", { | 433 | { 0x0017, NULL /* Unknown, need DMI string */, { |
430 | { "CPU Core", 0, 0, 10, 1, 0 }, | 434 | { "CPU Core", 0, 0, 10, 1, 0 }, |
431 | { "DDR2", 1, 0, 20, 1, 0 }, | 435 | { "DDR2", 1, 0, 20, 1, 0 }, |
432 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 436 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -442,7 +446,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
442 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, | 446 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, |
443 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, | 447 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, |
444 | { "CPU", 24, 1, 1, 1, 0 }, | 448 | { "CPU", 24, 1, 1, 1, 0 }, |
445 | { "System ", 26, 1, 1, 1, 0 }, | 449 | { "System", 26, 1, 1, 1, 0 }, |
446 | { "PWM", 27, 1, 1, 1, 0 }, | 450 | { "PWM", 27, 1, 1, 1, 0 }, |
447 | { "CPU FAN", 32, 2, 60, 1, 0 }, | 451 | { "CPU FAN", 32, 2, 60, 1, 0 }, |
448 | { "SYS FAN", 34, 2, 60, 1, 0 }, | 452 | { "SYS FAN", 34, 2, 60, 1, 0 }, |
@@ -451,7 +455,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
451 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | 455 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, |
452 | { NULL, 0, 0, 0, 0, 0 } } | 456 | { NULL, 0, 0, 0, 0, 0 } } |
453 | }, | 457 | }, |
454 | { 0x0018, "unknown", { | 458 | { 0x0018, NULL /* Unknown, need DMI string */, { |
455 | { "CPU Core", 0, 0, 10, 1, 0 }, | 459 | { "CPU Core", 0, 0, 10, 1, 0 }, |
456 | { "DDR2", 1, 0, 20, 1, 0 }, | 460 | { "DDR2", 1, 0, 20, 1, 0 }, |
457 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 461 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -465,7 +469,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
465 | { "+3.3V", 10, 0, 20, 1, 0 }, | 469 | { "+3.3V", 10, 0, 20, 1, 0 }, |
466 | { "5VSB", 11, 0, 30, 1, 0 }, | 470 | { "5VSB", 11, 0, 30, 1, 0 }, |
467 | { "CPU", 24, 1, 1, 1, 0 }, | 471 | { "CPU", 24, 1, 1, 1, 0 }, |
468 | { "System ", 25, 1, 1, 1, 0 }, | 472 | { "System", 25, 1, 1, 1, 0 }, |
469 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | 473 | { "PWM Phase1", 26, 1, 1, 1, 0 }, |
470 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | 474 | { "PWM Phase2", 27, 1, 1, 1, 0 }, |
471 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | 475 | { "PWM Phase3", 28, 1, 1, 1, 0 }, |
@@ -478,12 +482,12 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
478 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 482 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
479 | { NULL, 0, 0, 0, 0, 0 } } | 483 | { NULL, 0, 0, 0, 0, 0 } } |
480 | }, | 484 | }, |
481 | { 0x0019, "unknown", { | 485 | { 0x0019, NULL /* Unknown, need DMI string */, { |
482 | { "CPU Core", 7, 0, 10, 1, 0 }, | 486 | { "CPU Core", 7, 0, 10, 1, 0 }, |
483 | { "DDR2", 13, 0, 20, 1, 0 }, | 487 | { "DDR2", 13, 0, 20, 1, 0 }, |
484 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, | 488 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, |
485 | { "CPU VTT", 3, 0, 20, 1, 0 }, | 489 | { "CPU VTT", 3, 0, 20, 1, 0 }, |
486 | { "NB 1.2V ", 4, 0, 10, 1, 0 }, | 490 | { "NB 1.2V", 4, 0, 10, 1, 0 }, |
487 | { "SB 1.5V", 6, 0, 10, 1, 0 }, | 491 | { "SB 1.5V", 6, 0, 10, 1, 0 }, |
488 | { "HyperTransport", 5, 0, 10, 1, 0 }, | 492 | { "HyperTransport", 5, 0, 10, 1, 0 }, |
489 | { "ATX +12V (24-Pin)", 12, 0, 60, 1, 0 }, | 493 | { "ATX +12V (24-Pin)", 12, 0, 60, 1, 0 }, |
@@ -492,7 +496,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
492 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, | 496 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, |
493 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, | 497 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, |
494 | { "CPU", 24, 1, 1, 1, 0 }, | 498 | { "CPU", 24, 1, 1, 1, 0 }, |
495 | { "System ", 25, 1, 1, 1, 0 }, | 499 | { "System", 25, 1, 1, 1, 0 }, |
496 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | 500 | { "PWM Phase1", 26, 1, 1, 1, 0 }, |
497 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | 501 | { "PWM Phase2", 27, 1, 1, 1, 0 }, |
498 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | 502 | { "PWM Phase3", 28, 1, 1, 1, 0 }, |
@@ -505,7 +509,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
505 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, | 509 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, |
506 | { NULL, 0, 0, 0, 0, 0 } } | 510 | { NULL, 0, 0, 0, 0, 0 } } |
507 | }, | 511 | }, |
508 | { 0x001A, "Abit IP35 Pro", { | 512 | { 0x001A, "IP35 Pro(Intel P35-ICH9R)", { |
509 | { "CPU Core", 0, 0, 10, 1, 0 }, | 513 | { "CPU Core", 0, 0, 10, 1, 0 }, |
510 | { "DDR2", 1, 0, 20, 1, 0 }, | 514 | { "DDR2", 1, 0, 20, 1, 0 }, |
511 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 515 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -519,8 +523,8 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
519 | { "+3.3V", 10, 0, 20, 1, 0 }, | 523 | { "+3.3V", 10, 0, 20, 1, 0 }, |
520 | { "5VSB", 11, 0, 30, 1, 0 }, | 524 | { "5VSB", 11, 0, 30, 1, 0 }, |
521 | { "CPU", 24, 1, 1, 1, 0 }, | 525 | { "CPU", 24, 1, 1, 1, 0 }, |
522 | { "System ", 25, 1, 1, 1, 0 }, | 526 | { "System", 25, 1, 1, 1, 0 }, |
523 | { "PWM ", 26, 1, 1, 1, 0 }, | 527 | { "PWM", 26, 1, 1, 1, 0 }, |
524 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | 528 | { "PWM Phase2", 27, 1, 1, 1, 0 }, |
525 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | 529 | { "PWM Phase3", 28, 1, 1, 1, 0 }, |
526 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | 530 | { "PWM Phase4", 29, 1, 1, 1, 0 }, |
@@ -533,7 +537,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
533 | { "AUX4 Fan", 37, 2, 60, 1, 0 }, | 537 | { "AUX4 Fan", 37, 2, 60, 1, 0 }, |
534 | { NULL, 0, 0, 0, 0, 0 } } | 538 | { NULL, 0, 0, 0, 0, 0 } } |
535 | }, | 539 | }, |
536 | { 0x001B, "unknown", { | 540 | { 0x001B, NULL /* Unknown, need DMI string */, { |
537 | { "CPU Core", 0, 0, 10, 1, 0 }, | 541 | { "CPU Core", 0, 0, 10, 1, 0 }, |
538 | { "DDR3", 1, 0, 20, 1, 0 }, | 542 | { "DDR3", 1, 0, 20, 1, 0 }, |
539 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, | 543 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, |
@@ -560,7 +564,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
560 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 564 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
561 | { NULL, 0, 0, 0, 0, 0 } } | 565 | { NULL, 0, 0, 0, 0, 0 } } |
562 | }, | 566 | }, |
563 | { 0x001C, "unknown", { | 567 | { 0x001C, NULL /* Unknown, need DMI string */, { |
564 | { "CPU Core", 0, 0, 10, 1, 0 }, | 568 | { "CPU Core", 0, 0, 10, 1, 0 }, |
565 | { "DDR2", 1, 0, 20, 1, 0 }, | 569 | { "DDR2", 1, 0, 20, 1, 0 }, |
566 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 570 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -935,9 +939,18 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) | |||
935 | goto abituguru3_probe_error; | 939 | goto abituguru3_probe_error; |
936 | } | 940 | } |
937 | data->sensors = abituguru3_motherboards[i].sensors; | 941 | data->sensors = abituguru3_motherboards[i].sensors; |
942 | |||
938 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " | 943 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " |
939 | "ID: %04X (%s)\n", (unsigned int)id, | 944 | "ID: %04X\n", (unsigned int)id); |
940 | abituguru3_motherboards[i].name); | 945 | |
946 | #ifdef CONFIG_DMI | ||
947 | if (!abituguru3_motherboards[i].dmi_name) { | ||
948 | printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " | ||
949 | "not detected using DMI. Please send the output of " | ||
950 | "\"dmidecode\" to the abituguru3 maintainer " | ||
951 | "(see MAINTAINERS)\n"); | ||
952 | } | ||
953 | #endif | ||
941 | 954 | ||
942 | /* Fill the sysfs attr array */ | 955 | /* Fill the sysfs attr array */ |
943 | sysfs_attr_i = 0; | 956 | sysfs_attr_i = 0; |
@@ -1109,6 +1122,46 @@ static struct platform_driver abituguru3_driver = { | |||
1109 | .resume = abituguru3_resume | 1122 | .resume = abituguru3_resume |
1110 | }; | 1123 | }; |
1111 | 1124 | ||
1125 | #ifdef CONFIG_DMI | ||
1126 | |||
1127 | static int __init abituguru3_dmi_detect(void) | ||
1128 | { | ||
1129 | const char *board_vendor, *board_name; | ||
1130 | int i, err = (force) ? 1 : -ENODEV; | ||
1131 | |||
1132 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
1133 | if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/")) | ||
1134 | return err; | ||
1135 | |||
1136 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | ||
1137 | if (!board_name) | ||
1138 | return err; | ||
1139 | |||
1140 | for (i = 0; abituguru3_motherboards[i].id; i++) { | ||
1141 | const char *dmi_name = abituguru3_motherboards[i].dmi_name; | ||
1142 | if (dmi_name && !strcmp(dmi_name, board_name)) | ||
1143 | break; | ||
1144 | } | ||
1145 | |||
1146 | if (!abituguru3_motherboards[i].id) | ||
1147 | return 1; | ||
1148 | |||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | #else /* !CONFIG_DMI */ | ||
1153 | |||
1154 | static inline int abituguru3_dmi_detect(void) | ||
1155 | { | ||
1156 | return -ENODEV; | ||
1157 | } | ||
1158 | |||
1159 | #endif /* CONFIG_DMI */ | ||
1160 | |||
1161 | /* FIXME: Manual detection should die eventually; we need to collect stable | ||
1162 | * DMI model names first before we can rely entirely on CONFIG_DMI. | ||
1163 | */ | ||
1164 | |||
1112 | static int __init abituguru3_detect(void) | 1165 | static int __init abituguru3_detect(void) |
1113 | { | 1166 | { |
1114 | /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or | 1167 | /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or |
@@ -1119,7 +1172,7 @@ static int __init abituguru3_detect(void) | |||
1119 | if (((data_val == 0x00) || (data_val == 0x08)) && | 1172 | if (((data_val == 0x00) || (data_val == 0x08)) && |
1120 | ((cmd_val == 0xAC) || (cmd_val == 0x05) || | 1173 | ((cmd_val == 0xAC) || (cmd_val == 0x05) || |
1121 | (cmd_val == 0x55))) | 1174 | (cmd_val == 0x55))) |
1122 | return ABIT_UGURU3_BASE; | 1175 | return 0; |
1123 | 1176 | ||
1124 | ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " | 1177 | ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " |
1125 | "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); | 1178 | "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); |
@@ -1127,7 +1180,7 @@ static int __init abituguru3_detect(void) | |||
1127 | if (force) { | 1180 | if (force) { |
1128 | printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " | 1181 | printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " |
1129 | "present because of \"force\" parameter\n"); | 1182 | "present because of \"force\" parameter\n"); |
1130 | return ABIT_UGURU3_BASE; | 1183 | return 0; |
1131 | } | 1184 | } |
1132 | 1185 | ||
1133 | /* No uGuru3 found */ | 1186 | /* No uGuru3 found */ |
@@ -1138,27 +1191,29 @@ static struct platform_device *abituguru3_pdev; | |||
1138 | 1191 | ||
1139 | static int __init abituguru3_init(void) | 1192 | static int __init abituguru3_init(void) |
1140 | { | 1193 | { |
1141 | int address, err; | ||
1142 | struct resource res = { .flags = IORESOURCE_IO }; | 1194 | struct resource res = { .flags = IORESOURCE_IO }; |
1143 | 1195 | int err; | |
1144 | #ifdef CONFIG_DMI | 1196 | |
1145 | const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | 1197 | /* Attempt DMI detection first */ |
1146 | 1198 | err = abituguru3_dmi_detect(); | |
1147 | /* safety check, refuse to load on non Abit motherboards */ | 1199 | if (err < 0) |
1148 | if (!force && (!board_vendor || | 1200 | return err; |
1149 | strcmp(board_vendor, "http://www.abit.com.tw/"))) | 1201 | |
1150 | return -ENODEV; | 1202 | /* Fall back to manual detection if there was no exact |
1151 | #endif | 1203 | * board name match, or force was specified. |
1152 | 1204 | */ | |
1153 | address = abituguru3_detect(); | 1205 | if (err > 0) { |
1154 | if (address < 0) | 1206 | err = abituguru3_detect(); |
1155 | return address; | 1207 | if (err) |
1208 | return err; | ||
1209 | } | ||
1156 | 1210 | ||
1157 | err = platform_driver_register(&abituguru3_driver); | 1211 | err = platform_driver_register(&abituguru3_driver); |
1158 | if (err) | 1212 | if (err) |
1159 | goto exit; | 1213 | goto exit; |
1160 | 1214 | ||
1161 | abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, address); | 1215 | abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, |
1216 | ABIT_UGURU3_BASE); | ||
1162 | if (!abituguru3_pdev) { | 1217 | if (!abituguru3_pdev) { |
1163 | printk(KERN_ERR ABIT_UGURU3_NAME | 1218 | printk(KERN_ERR ABIT_UGURU3_NAME |
1164 | ": Device allocation failed\n"); | 1219 | ": Device allocation failed\n"); |
@@ -1166,8 +1221,8 @@ static int __init abituguru3_init(void) | |||
1166 | goto exit_driver_unregister; | 1221 | goto exit_driver_unregister; |
1167 | } | 1222 | } |
1168 | 1223 | ||
1169 | res.start = address; | 1224 | res.start = ABIT_UGURU3_BASE; |
1170 | res.end = address + ABIT_UGURU3_REGION_LENGTH - 1; | 1225 | res.end = ABIT_UGURU3_BASE + ABIT_UGURU3_REGION_LENGTH - 1; |
1171 | res.name = ABIT_UGURU3_NAME; | 1226 | res.name = ABIT_UGURU3_NAME; |
1172 | 1227 | ||
1173 | err = platform_device_add_resources(abituguru3_pdev, &res, 1); | 1228 | err = platform_device_add_resources(abituguru3_pdev, &res, 1); |
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c new file mode 100644 index 000000000000..bfda8c80ef24 --- /dev/null +++ b/drivers/hwmon/ad7414.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * An hwmon driver for the Analog Devices AD7414 | ||
3 | * | ||
4 | * Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering | ||
5 | * | ||
6 | * Copyright (c) 2008 PIKA Technologies | ||
7 | * Sean MacLennan <smaclennan@pikatech.com> | ||
8 | * | ||
9 | * Copyright (c) 2008 Spansion Inc. | ||
10 | * Frank Edelhaeuser <frank.edelhaeuser at spansion.com> | ||
11 | * (converted to "new style" I2C driver model, removed checkpatch.pl warnings) | ||
12 | * | ||
13 | * Based on ad7418.c | ||
14 | * Copyright 2006 Tower Technologies, Alessandro Zummo <a.zummo at towertech.it> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/sysfs.h> | ||
30 | |||
31 | |||
32 | /* AD7414 registers */ | ||
33 | #define AD7414_REG_TEMP 0x00 | ||
34 | #define AD7414_REG_CONF 0x01 | ||
35 | #define AD7414_REG_T_HIGH 0x02 | ||
36 | #define AD7414_REG_T_LOW 0x03 | ||
37 | |||
38 | static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW }; | ||
39 | |||
40 | struct ad7414_data { | ||
41 | struct device *hwmon_dev; | ||
42 | struct mutex lock; /* atomic read data updates */ | ||
43 | char valid; /* !=0 if following fields are valid */ | ||
44 | unsigned long next_update; /* In jiffies */ | ||
45 | s16 temp_input; /* Register values */ | ||
46 | s8 temps[ARRAY_SIZE(AD7414_REG_LIMIT)]; | ||
47 | }; | ||
48 | |||
49 | /* REG: (0.25C/bit, two's complement) << 6 */ | ||
50 | static inline int ad7414_temp_from_reg(s16 reg) | ||
51 | { | ||
52 | /* use integer division instead of equivalent right shift to | ||
53 | * guarantee arithmetic shift and preserve the sign | ||
54 | */ | ||
55 | return ((int)reg / 64) * 250; | ||
56 | } | ||
57 | |||
58 | static inline int ad7414_read(struct i2c_client *client, u8 reg) | ||
59 | { | ||
60 | if (reg == AD7414_REG_TEMP) { | ||
61 | int value = i2c_smbus_read_word_data(client, reg); | ||
62 | return (value < 0) ? value : swab16(value); | ||
63 | } else | ||
64 | return i2c_smbus_read_byte_data(client, reg); | ||
65 | } | ||
66 | |||
67 | static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value) | ||
68 | { | ||
69 | return i2c_smbus_write_byte_data(client, reg, value); | ||
70 | } | ||
71 | |||
72 | static struct ad7414_data *ad7414_update_device(struct device *dev) | ||
73 | { | ||
74 | struct i2c_client *client = to_i2c_client(dev); | ||
75 | struct ad7414_data *data = i2c_get_clientdata(client); | ||
76 | |||
77 | mutex_lock(&data->lock); | ||
78 | |||
79 | if (time_after(jiffies, data->next_update) || !data->valid) { | ||
80 | int value, i; | ||
81 | |||
82 | dev_dbg(&client->dev, "starting ad7414 update\n"); | ||
83 | |||
84 | value = ad7414_read(client, AD7414_REG_TEMP); | ||
85 | if (value < 0) | ||
86 | dev_dbg(&client->dev, "AD7414_REG_TEMP err %d\n", | ||
87 | value); | ||
88 | else | ||
89 | data->temp_input = value; | ||
90 | |||
91 | for (i = 0; i < ARRAY_SIZE(AD7414_REG_LIMIT); ++i) { | ||
92 | value = ad7414_read(client, AD7414_REG_LIMIT[i]); | ||
93 | if (value < 0) | ||
94 | dev_dbg(&client->dev, "AD7414 reg %d err %d\n", | ||
95 | AD7414_REG_LIMIT[i], value); | ||
96 | else | ||
97 | data->temps[i] = value; | ||
98 | } | ||
99 | |||
100 | data->next_update = jiffies + HZ + HZ / 2; | ||
101 | data->valid = 1; | ||
102 | } | ||
103 | |||
104 | mutex_unlock(&data->lock); | ||
105 | |||
106 | return data; | ||
107 | } | ||
108 | |||
109 | static ssize_t show_temp_input(struct device *dev, | ||
110 | struct device_attribute *attr, char *buf) | ||
111 | { | ||
112 | struct ad7414_data *data = ad7414_update_device(dev); | ||
113 | return sprintf(buf, "%d\n", ad7414_temp_from_reg(data->temp_input)); | ||
114 | } | ||
115 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0); | ||
116 | |||
117 | static ssize_t show_max_min(struct device *dev, struct device_attribute *attr, | ||
118 | char *buf) | ||
119 | { | ||
120 | int index = to_sensor_dev_attr(attr)->index; | ||
121 | struct ad7414_data *data = ad7414_update_device(dev); | ||
122 | return sprintf(buf, "%d\n", data->temps[index] * 1000); | ||
123 | } | ||
124 | |||
125 | static ssize_t set_max_min(struct device *dev, | ||
126 | struct device_attribute *attr, | ||
127 | const char *buf, size_t count) | ||
128 | { | ||
129 | struct i2c_client *client = to_i2c_client(dev); | ||
130 | struct ad7414_data *data = i2c_get_clientdata(client); | ||
131 | int index = to_sensor_dev_attr(attr)->index; | ||
132 | u8 reg = AD7414_REG_LIMIT[index]; | ||
133 | long temp = simple_strtol(buf, NULL, 10); | ||
134 | |||
135 | temp = SENSORS_LIMIT(temp, -40000, 85000); | ||
136 | temp = (temp + (temp < 0 ? -500 : 500)) / 1000; | ||
137 | |||
138 | mutex_lock(&data->lock); | ||
139 | data->temps[index] = temp; | ||
140 | ad7414_write(client, reg, temp); | ||
141 | mutex_unlock(&data->lock); | ||
142 | return count; | ||
143 | } | ||
144 | |||
145 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
146 | show_max_min, set_max_min, 0); | ||
147 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | ||
148 | show_max_min, set_max_min, 1); | ||
149 | |||
150 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
151 | char *buf) | ||
152 | { | ||
153 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
154 | struct ad7414_data *data = ad7414_update_device(dev); | ||
155 | int value = (data->temp_input >> bitnr) & 1; | ||
156 | return sprintf(buf, "%d\n", value); | ||
157 | } | ||
158 | |||
159 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
160 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
161 | |||
162 | static struct attribute *ad7414_attributes[] = { | ||
163 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
164 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
165 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
166 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
167 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
168 | NULL | ||
169 | }; | ||
170 | |||
171 | static const struct attribute_group ad7414_group = { | ||
172 | .attrs = ad7414_attributes, | ||
173 | }; | ||
174 | |||
175 | static int ad7414_probe(struct i2c_client *client, | ||
176 | const struct i2c_device_id *dev_id) | ||
177 | { | ||
178 | struct ad7414_data *data; | ||
179 | int conf; | ||
180 | int err = 0; | ||
181 | |||
182 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
183 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | ||
184 | goto exit; | ||
185 | |||
186 | data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); | ||
187 | if (!data) { | ||
188 | err = -ENOMEM; | ||
189 | goto exit; | ||
190 | } | ||
191 | |||
192 | i2c_set_clientdata(client, data); | ||
193 | mutex_init(&data->lock); | ||
194 | |||
195 | dev_info(&client->dev, "chip found\n"); | ||
196 | |||
197 | /* Make sure the chip is powered up. */ | ||
198 | conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF); | ||
199 | if (conf < 0) | ||
200 | dev_warn(&client->dev, | ||
201 | "ad7414_probe unable to read config register.\n"); | ||
202 | else { | ||
203 | conf &= ~(1 << 7); | ||
204 | i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf); | ||
205 | } | ||
206 | |||
207 | /* Register sysfs hooks */ | ||
208 | err = sysfs_create_group(&client->dev.kobj, &ad7414_group); | ||
209 | if (err) | ||
210 | goto exit_free; | ||
211 | |||
212 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
213 | if (IS_ERR(data->hwmon_dev)) { | ||
214 | err = PTR_ERR(data->hwmon_dev); | ||
215 | goto exit_remove; | ||
216 | } | ||
217 | |||
218 | return 0; | ||
219 | |||
220 | exit_remove: | ||
221 | sysfs_remove_group(&client->dev.kobj, &ad7414_group); | ||
222 | exit_free: | ||
223 | kfree(data); | ||
224 | exit: | ||
225 | return err; | ||
226 | } | ||
227 | |||
228 | static int __devexit ad7414_remove(struct i2c_client *client) | ||
229 | { | ||
230 | struct ad7414_data *data = i2c_get_clientdata(client); | ||
231 | |||
232 | hwmon_device_unregister(data->hwmon_dev); | ||
233 | sysfs_remove_group(&client->dev.kobj, &ad7414_group); | ||
234 | kfree(data); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static const struct i2c_device_id ad7414_id[] = { | ||
239 | { "ad7414", 0 }, | ||
240 | {} | ||
241 | }; | ||
242 | |||
243 | static struct i2c_driver ad7414_driver = { | ||
244 | .driver = { | ||
245 | .name = "ad7414", | ||
246 | }, | ||
247 | .probe = ad7414_probe, | ||
248 | .remove = __devexit_p(ad7414_remove), | ||
249 | .id_table = ad7414_id, | ||
250 | }; | ||
251 | |||
252 | static int __init ad7414_init(void) | ||
253 | { | ||
254 | return i2c_add_driver(&ad7414_driver); | ||
255 | } | ||
256 | module_init(ad7414_init); | ||
257 | |||
258 | static void __exit ad7414_exit(void) | ||
259 | { | ||
260 | i2c_del_driver(&ad7414_driver); | ||
261 | } | ||
262 | module_exit(ad7414_exit); | ||
263 | |||
264 | MODULE_AUTHOR("Stefan Roese <sr at denx.de>, " | ||
265 | "Frank Edelhaeuser <frank.edelhaeuser at spansion.com>"); | ||
266 | |||
267 | MODULE_DESCRIPTION("AD7414 driver"); | ||
268 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c new file mode 100644 index 000000000000..242294db3db6 --- /dev/null +++ b/drivers/hwmon/adcxx.c | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | * adcxx.c | ||
3 | * | ||
4 | * The adcxx4s is an AD converter family from National Semiconductor (NS). | ||
5 | * | ||
6 | * Copyright (c) 2008 Marc Pignat <marc.pignat@hevs.ch> | ||
7 | * | ||
8 | * The adcxx4s communicates with a host processor via an SPI/Microwire Bus | ||
9 | * interface. This driver supports the whole family of devices with name | ||
10 | * ADC<bb><c>S<sss>, where | ||
11 | * * bb is the resolution in number of bits (8, 10, 12) | ||
12 | * * c is the number of channels (1, 2, 4, 8) | ||
13 | * * sss is the maximum conversion speed (021 for 200 kSPS, 051 for 500 kSPS | ||
14 | * and 101 for 1 MSPS) | ||
15 | * | ||
16 | * Complete datasheets are available at National's website here: | ||
17 | * http://www.national.com/ds/DC/ADC<bb><c>S<sss>.pdf | ||
18 | * | ||
19 | * Handling of 8, 10 and 12 bits converters are the same, the | ||
20 | * unavailable bits are 0 :) | ||
21 | * | ||
22 | * This program is free software; you can redistribute it and/or modify | ||
23 | * it under the terms of the GNU General Public License as published by | ||
24 | * the Free Software Foundation; either version 2 of the License, or | ||
25 | * (at your option) any later version. | ||
26 | * | ||
27 | * This program is distributed in the hope that it will be useful, | ||
28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
30 | * GNU General Public License for more details. | ||
31 | * | ||
32 | * You should have received a copy of the GNU General Public License | ||
33 | * along with this program; if not, write to the Free Software | ||
34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
35 | */ | ||
36 | |||
37 | #include <linux/init.h> | ||
38 | #include <linux/module.h> | ||
39 | #include <linux/kernel.h> | ||
40 | #include <linux/device.h> | ||
41 | #include <linux/err.h> | ||
42 | #include <linux/sysfs.h> | ||
43 | #include <linux/hwmon.h> | ||
44 | #include <linux/hwmon-sysfs.h> | ||
45 | #include <linux/mutex.h> | ||
46 | #include <linux/spi/spi.h> | ||
47 | |||
48 | #define DRVNAME "adcxx" | ||
49 | |||
50 | struct adcxx { | ||
51 | struct device *hwmon_dev; | ||
52 | struct mutex lock; | ||
53 | u32 channels; | ||
54 | u32 reference; /* in millivolts */ | ||
55 | }; | ||
56 | |||
57 | /* sysfs hook function */ | ||
58 | static ssize_t adcxx_read(struct device *dev, | ||
59 | struct device_attribute *devattr, char *buf) | ||
60 | { | ||
61 | struct spi_device *spi = to_spi_device(dev); | ||
62 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
63 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
64 | u8 tx_buf[2] = { attr->index << 3 }; /* other bits are don't care */ | ||
65 | u8 rx_buf[2]; | ||
66 | int status; | ||
67 | int value; | ||
68 | |||
69 | if (mutex_lock_interruptible(&adc->lock)) | ||
70 | return -ERESTARTSYS; | ||
71 | |||
72 | status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf), | ||
73 | rx_buf, sizeof(rx_buf)); | ||
74 | if (status < 0) { | ||
75 | dev_warn(dev, "spi_write_then_read failed with status %d\n", | ||
76 | status); | ||
77 | goto out; | ||
78 | } | ||
79 | |||
80 | value = (rx_buf[0] << 8) + rx_buf[1]; | ||
81 | dev_dbg(dev, "raw value = 0x%x\n", value); | ||
82 | |||
83 | value = value * adc->reference >> 12; | ||
84 | status = sprintf(buf, "%d\n", value); | ||
85 | out: | ||
86 | mutex_unlock(&adc->lock); | ||
87 | return status; | ||
88 | } | ||
89 | |||
90 | static ssize_t adcxx_show_min(struct device *dev, | ||
91 | struct device_attribute *devattr, char *buf) | ||
92 | { | ||
93 | /* The minimum reference is 0 for this chip family */ | ||
94 | return sprintf(buf, "0\n"); | ||
95 | } | ||
96 | |||
97 | static ssize_t adcxx_show_max(struct device *dev, | ||
98 | struct device_attribute *devattr, char *buf) | ||
99 | { | ||
100 | struct spi_device *spi = to_spi_device(dev); | ||
101 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
102 | u32 reference; | ||
103 | |||
104 | if (mutex_lock_interruptible(&adc->lock)) | ||
105 | return -ERESTARTSYS; | ||
106 | |||
107 | reference = adc->reference; | ||
108 | |||
109 | mutex_unlock(&adc->lock); | ||
110 | |||
111 | return sprintf(buf, "%d\n", reference); | ||
112 | } | ||
113 | |||
114 | static ssize_t adcxx_set_max(struct device *dev, | ||
115 | struct device_attribute *devattr, const char *buf, size_t count) | ||
116 | { | ||
117 | struct spi_device *spi = to_spi_device(dev); | ||
118 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
119 | unsigned long value; | ||
120 | |||
121 | if (strict_strtoul(buf, 10, &value)) | ||
122 | return -EINVAL; | ||
123 | |||
124 | if (mutex_lock_interruptible(&adc->lock)) | ||
125 | return -ERESTARTSYS; | ||
126 | |||
127 | adc->reference = value; | ||
128 | |||
129 | mutex_unlock(&adc->lock); | ||
130 | |||
131 | return count; | ||
132 | } | ||
133 | |||
134 | static ssize_t adcxx_show_name(struct device *dev, struct device_attribute | ||
135 | *devattr, char *buf) | ||
136 | { | ||
137 | struct spi_device *spi = to_spi_device(dev); | ||
138 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
139 | |||
140 | return sprintf(buf, "adcxx%ds\n", adc->channels); | ||
141 | } | ||
142 | |||
143 | static struct sensor_device_attribute ad_input[] = { | ||
144 | SENSOR_ATTR(name, S_IRUGO, adcxx_show_name, NULL, 0), | ||
145 | SENSOR_ATTR(in_min, S_IRUGO, adcxx_show_min, NULL, 0), | ||
146 | SENSOR_ATTR(in_max, S_IWUSR | S_IRUGO, adcxx_show_max, | ||
147 | adcxx_set_max, 0), | ||
148 | SENSOR_ATTR(in0_input, S_IRUGO, adcxx_read, NULL, 0), | ||
149 | SENSOR_ATTR(in1_input, S_IRUGO, adcxx_read, NULL, 1), | ||
150 | SENSOR_ATTR(in2_input, S_IRUGO, adcxx_read, NULL, 2), | ||
151 | SENSOR_ATTR(in3_input, S_IRUGO, adcxx_read, NULL, 3), | ||
152 | SENSOR_ATTR(in4_input, S_IRUGO, adcxx_read, NULL, 4), | ||
153 | SENSOR_ATTR(in5_input, S_IRUGO, adcxx_read, NULL, 5), | ||
154 | SENSOR_ATTR(in6_input, S_IRUGO, adcxx_read, NULL, 6), | ||
155 | SENSOR_ATTR(in7_input, S_IRUGO, adcxx_read, NULL, 7), | ||
156 | }; | ||
157 | |||
158 | /*----------------------------------------------------------------------*/ | ||
159 | |||
160 | static int __devinit adcxx_probe(struct spi_device *spi, int channels) | ||
161 | { | ||
162 | struct adcxx *adc; | ||
163 | int status; | ||
164 | int i; | ||
165 | |||
166 | adc = kzalloc(sizeof *adc, GFP_KERNEL); | ||
167 | if (!adc) | ||
168 | return -ENOMEM; | ||
169 | |||
170 | /* set a default value for the reference */ | ||
171 | adc->reference = 3300; | ||
172 | adc->channels = channels; | ||
173 | mutex_init(&adc->lock); | ||
174 | |||
175 | mutex_lock(&adc->lock); | ||
176 | |||
177 | dev_set_drvdata(&spi->dev, adc); | ||
178 | |||
179 | for (i = 0; i < 3 + adc->channels; i++) { | ||
180 | status = device_create_file(&spi->dev, &ad_input[i].dev_attr); | ||
181 | if (status) { | ||
182 | dev_err(&spi->dev, "device_create_file failed.\n"); | ||
183 | goto out_err; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | adc->hwmon_dev = hwmon_device_register(&spi->dev); | ||
188 | if (IS_ERR(adc->hwmon_dev)) { | ||
189 | dev_err(&spi->dev, "hwmon_device_register failed.\n"); | ||
190 | status = PTR_ERR(adc->hwmon_dev); | ||
191 | goto out_err; | ||
192 | } | ||
193 | |||
194 | mutex_unlock(&adc->lock); | ||
195 | return 0; | ||
196 | |||
197 | out_err: | ||
198 | for (i--; i >= 0; i--) | ||
199 | device_remove_file(&spi->dev, &ad_input[i].dev_attr); | ||
200 | |||
201 | dev_set_drvdata(&spi->dev, NULL); | ||
202 | mutex_unlock(&adc->lock); | ||
203 | kfree(adc); | ||
204 | return status; | ||
205 | } | ||
206 | |||
207 | static int __devinit adcxx1s_probe(struct spi_device *spi) | ||
208 | { | ||
209 | return adcxx_probe(spi, 1); | ||
210 | } | ||
211 | |||
212 | static int __devinit adcxx2s_probe(struct spi_device *spi) | ||
213 | { | ||
214 | return adcxx_probe(spi, 2); | ||
215 | } | ||
216 | |||
217 | static int __devinit adcxx4s_probe(struct spi_device *spi) | ||
218 | { | ||
219 | return adcxx_probe(spi, 4); | ||
220 | } | ||
221 | |||
222 | static int __devinit adcxx8s_probe(struct spi_device *spi) | ||
223 | { | ||
224 | return adcxx_probe(spi, 8); | ||
225 | } | ||
226 | |||
227 | static int __devexit adcxx_remove(struct spi_device *spi) | ||
228 | { | ||
229 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
230 | int i; | ||
231 | |||
232 | mutex_lock(&adc->lock); | ||
233 | hwmon_device_unregister(adc->hwmon_dev); | ||
234 | for (i = 0; i < 3 + adc->channels; i++) | ||
235 | device_remove_file(&spi->dev, &ad_input[i].dev_attr); | ||
236 | |||
237 | dev_set_drvdata(&spi->dev, NULL); | ||
238 | mutex_unlock(&adc->lock); | ||
239 | kfree(adc); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static struct spi_driver adcxx1s_driver = { | ||
245 | .driver = { | ||
246 | .name = "adcxx1s", | ||
247 | .owner = THIS_MODULE, | ||
248 | }, | ||
249 | .probe = adcxx1s_probe, | ||
250 | .remove = __devexit_p(adcxx_remove), | ||
251 | }; | ||
252 | |||
253 | static struct spi_driver adcxx2s_driver = { | ||
254 | .driver = { | ||
255 | .name = "adcxx2s", | ||
256 | .owner = THIS_MODULE, | ||
257 | }, | ||
258 | .probe = adcxx2s_probe, | ||
259 | .remove = __devexit_p(adcxx_remove), | ||
260 | }; | ||
261 | |||
262 | static struct spi_driver adcxx4s_driver = { | ||
263 | .driver = { | ||
264 | .name = "adcxx4s", | ||
265 | .owner = THIS_MODULE, | ||
266 | }, | ||
267 | .probe = adcxx4s_probe, | ||
268 | .remove = __devexit_p(adcxx_remove), | ||
269 | }; | ||
270 | |||
271 | static struct spi_driver adcxx8s_driver = { | ||
272 | .driver = { | ||
273 | .name = "adcxx8s", | ||
274 | .owner = THIS_MODULE, | ||
275 | }, | ||
276 | .probe = adcxx8s_probe, | ||
277 | .remove = __devexit_p(adcxx_remove), | ||
278 | }; | ||
279 | |||
280 | static int __init init_adcxx(void) | ||
281 | { | ||
282 | int status; | ||
283 | status = spi_register_driver(&adcxx1s_driver); | ||
284 | if (status) | ||
285 | goto reg_1_failed; | ||
286 | |||
287 | status = spi_register_driver(&adcxx2s_driver); | ||
288 | if (status) | ||
289 | goto reg_2_failed; | ||
290 | |||
291 | status = spi_register_driver(&adcxx4s_driver); | ||
292 | if (status) | ||
293 | goto reg_4_failed; | ||
294 | |||
295 | status = spi_register_driver(&adcxx8s_driver); | ||
296 | if (status) | ||
297 | goto reg_8_failed; | ||
298 | |||
299 | return status; | ||
300 | |||
301 | reg_8_failed: | ||
302 | spi_unregister_driver(&adcxx4s_driver); | ||
303 | reg_4_failed: | ||
304 | spi_unregister_driver(&adcxx2s_driver); | ||
305 | reg_2_failed: | ||
306 | spi_unregister_driver(&adcxx1s_driver); | ||
307 | reg_1_failed: | ||
308 | return status; | ||
309 | } | ||
310 | |||
311 | static void __exit exit_adcxx(void) | ||
312 | { | ||
313 | spi_unregister_driver(&adcxx1s_driver); | ||
314 | spi_unregister_driver(&adcxx2s_driver); | ||
315 | spi_unregister_driver(&adcxx4s_driver); | ||
316 | spi_unregister_driver(&adcxx8s_driver); | ||
317 | } | ||
318 | |||
319 | module_init(init_adcxx); | ||
320 | module_exit(exit_adcxx); | ||
321 | |||
322 | MODULE_AUTHOR("Marc Pignat"); | ||
323 | MODULE_DESCRIPTION("National Semiconductor adcxx8sxxx Linux driver"); | ||
324 | MODULE_LICENSE("GPL"); | ||
325 | |||
326 | MODULE_ALIAS("adcxx1s"); | ||
327 | MODULE_ALIAS("adcxx2s"); | ||
328 | MODULE_ALIAS("adcxx4s"); | ||
329 | MODULE_ALIAS("adcxx8s"); | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 7fe2441fc845..ff7de40b6e35 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -279,7 +279,6 @@ struct adm1026_data { | |||
279 | u8 fan_min[8]; /* Register value */ | 279 | u8 fan_min[8]; /* Register value */ |
280 | u8 fan_div[8]; /* Decoded value */ | 280 | u8 fan_div[8]; /* Decoded value */ |
281 | struct pwm_data pwm1; /* Pwm control values */ | 281 | struct pwm_data pwm1; /* Pwm control values */ |
282 | int vid; /* Decoded value */ | ||
283 | u8 vrm; /* VRM version */ | 282 | u8 vrm; /* VRM version */ |
284 | u8 analog_out; /* Register value (DAC) */ | 283 | u8 analog_out; /* Register value (DAC) */ |
285 | long alarms; /* Register encoding, combined */ | 284 | long alarms; /* Register encoding, combined */ |
@@ -455,7 +454,7 @@ static void adm1026_print_gpio(struct i2c_client *client) | |||
455 | struct adm1026_data *data = i2c_get_clientdata(client); | 454 | struct adm1026_data *data = i2c_get_clientdata(client); |
456 | int i; | 455 | int i; |
457 | 456 | ||
458 | dev_dbg(&client->dev, "GPIO config is:"); | 457 | dev_dbg(&client->dev, "GPIO config is:\n"); |
459 | for (i = 0;i <= 7;++i) { | 458 | for (i = 0;i <= 7;++i) { |
460 | if (data->config2 & (1 << i)) { | 459 | if (data->config2 & (1 << i)) { |
461 | dev_dbg(&client->dev, "\t%sGP%s%d\n", | 460 | dev_dbg(&client->dev, "\t%sGP%s%d\n", |
@@ -697,8 +696,6 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | |||
697 | data->last_config = jiffies; | 696 | data->last_config = jiffies; |
698 | }; /* last_config */ | 697 | }; /* last_config */ |
699 | 698 | ||
700 | dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n"); | ||
701 | data->vid = (data->gpio >> 11) & 0x1f; | ||
702 | data->valid = 1; | 699 | data->valid = 1; |
703 | mutex_unlock(&data->update_lock); | 700 | mutex_unlock(&data->update_lock); |
704 | return data; | 701 | return data; |
@@ -1215,7 +1212,10 @@ static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, | |||
1215 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | 1212 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1216 | { | 1213 | { |
1217 | struct adm1026_data *data = adm1026_update_device(dev); | 1214 | struct adm1026_data *data = adm1026_update_device(dev); |
1218 | return sprintf(buf, "%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); | 1215 | int vid = (data->gpio >> 11) & 0x1f; |
1216 | |||
1217 | dev_dbg(dev, "Setting VID from GPIO11-15.\n"); | ||
1218 | return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm)); | ||
1219 | } | 1219 | } |
1220 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 1220 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
1221 | 1221 | ||
@@ -1681,17 +1681,16 @@ static int adm1026_detect(struct i2c_client *client, int kind, | |||
1681 | kind = adm1026; | 1681 | kind = adm1026; |
1682 | } else if (company == ADM1026_COMPANY_ANALOG_DEV | 1682 | } else if (company == ADM1026_COMPANY_ANALOG_DEV |
1683 | && (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { | 1683 | && (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { |
1684 | dev_err(&adapter->dev, ": Unrecognized stepping " | 1684 | dev_err(&adapter->dev, "Unrecognized stepping " |
1685 | "0x%02x. Defaulting to ADM1026.\n", verstep); | 1685 | "0x%02x. Defaulting to ADM1026.\n", verstep); |
1686 | kind = adm1026; | 1686 | kind = adm1026; |
1687 | } else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { | 1687 | } else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { |
1688 | dev_err(&adapter->dev, ": Found version/stepping " | 1688 | dev_err(&adapter->dev, "Found version/stepping " |
1689 | "0x%02x. Assuming generic ADM1026.\n", | 1689 | "0x%02x. Assuming generic ADM1026.\n", |
1690 | verstep); | 1690 | verstep); |
1691 | kind = any_chip; | 1691 | kind = any_chip; |
1692 | } else { | 1692 | } else { |
1693 | dev_dbg(&adapter->dev, ": Autodetection " | 1693 | dev_dbg(&adapter->dev, "Autodetection failed\n"); |
1694 | "failed\n"); | ||
1695 | /* Not an ADM1026 ... */ | 1694 | /* Not an ADM1026 ... */ |
1696 | if (kind == 0) { /* User used force=x,y */ | 1695 | if (kind == 0) { /* User used force=x,y */ |
1697 | dev_err(&adapter->dev, "Generic ADM1026 not " | 1696 | dev_err(&adapter->dev, "Generic ADM1026 not " |
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index ba84ca5923f9..36718150b475 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c | |||
@@ -179,7 +179,8 @@ show_fan(struct device *dev, struct device_attribute *devattr, char *buf) | |||
179 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 179 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
180 | struct adm1029_data *data = adm1029_update_device(dev); | 180 | struct adm1029_data *data = adm1029_update_device(dev); |
181 | u16 val; | 181 | u16 val; |
182 | if (data->fan[attr->index] == 0 || data->fan_div[attr->index] == 0 | 182 | if (data->fan[attr->index] == 0 |
183 | || (data->fan_div[attr->index] & 0xC0) == 0 | ||
183 | || data->fan[attr->index] == 255) { | 184 | || data->fan[attr->index] == 255) { |
184 | return sprintf(buf, "0\n"); | 185 | return sprintf(buf, "0\n"); |
185 | } | 186 | } |
@@ -194,7 +195,7 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) | |||
194 | { | 195 | { |
195 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 196 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
196 | struct adm1029_data *data = adm1029_update_device(dev); | 197 | struct adm1029_data *data = adm1029_update_device(dev); |
197 | if (data->fan_div[attr->index] == 0) | 198 | if ((data->fan_div[attr->index] & 0xC0) == 0) |
198 | return sprintf(buf, "0\n"); | 199 | return sprintf(buf, "0\n"); |
199 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); | 200 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); |
200 | } | 201 | } |
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index ce4a7cb5a116..b9a8ea30c99c 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c | |||
@@ -39,32 +39,20 @@ I2C_CLIENT_INSMOD_1(adt7473); | |||
39 | #define ADT7473_REG_BASE_ADDR 0x20 | 39 | #define ADT7473_REG_BASE_ADDR 0x20 |
40 | 40 | ||
41 | #define ADT7473_REG_VOLT_BASE_ADDR 0x21 | 41 | #define ADT7473_REG_VOLT_BASE_ADDR 0x21 |
42 | #define ADT7473_REG_VOLT_MAX_ADDR 0x22 | ||
43 | #define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46 | 42 | #define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46 |
44 | #define ADT7473_REG_VOLT_MIN_MAX_ADDR 0x49 | ||
45 | 43 | ||
46 | #define ADT7473_REG_TEMP_BASE_ADDR 0x25 | 44 | #define ADT7473_REG_TEMP_BASE_ADDR 0x25 |
47 | #define ADT7473_REG_TEMP_MAX_ADDR 0x27 | ||
48 | #define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E | 45 | #define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E |
49 | #define ADT7473_REG_TEMP_LIMITS_MAX_ADDR 0x53 | ||
50 | #define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67 | 46 | #define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67 |
51 | #define ADT7473_REG_TEMP_TMIN_MAX_ADDR 0x69 | ||
52 | #define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A | 47 | #define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A |
53 | #define ADT7473_REG_TEMP_TMAX_MAX_ADDR 0x6C | ||
54 | 48 | ||
55 | #define ADT7473_REG_FAN_BASE_ADDR 0x28 | 49 | #define ADT7473_REG_FAN_BASE_ADDR 0x28 |
56 | #define ADT7473_REG_FAN_MAX_ADDR 0x2F | ||
57 | #define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54 | 50 | #define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54 |
58 | #define ADT7473_REG_FAN_MIN_MAX_ADDR 0x5B | ||
59 | 51 | ||
60 | #define ADT7473_REG_PWM_BASE_ADDR 0x30 | 52 | #define ADT7473_REG_PWM_BASE_ADDR 0x30 |
61 | #define ADT7473_REG_PWM_MAX_ADDR 0x32 | ||
62 | #define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64 | 53 | #define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64 |
63 | #define ADT7473_REG_PWM_MIN_MAX_ADDR 0x66 | ||
64 | #define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38 | 54 | #define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38 |
65 | #define ADT7473_REG_PWM_MAX_MAX_ADDR 0x3A | ||
66 | #define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C | 55 | #define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C |
67 | #define ADT7473_REG_PWM_BHVR_MAX_ADDR 0x5E | ||
68 | #define ADT7473_PWM_BHVR_MASK 0xE0 | 56 | #define ADT7473_PWM_BHVR_MASK 0xE0 |
69 | #define ADT7473_PWM_BHVR_SHIFT 5 | 57 | #define ADT7473_PWM_BHVR_SHIFT 5 |
70 | 58 | ||
@@ -102,7 +90,6 @@ I2C_CLIENT_INSMOD_1(adt7473); | |||
102 | #define ADT7473_FAN4_ALARM 0x20 | 90 | #define ADT7473_FAN4_ALARM 0x20 |
103 | #define ADT7473_R1T_SHORT 0x40 | 91 | #define ADT7473_R1T_SHORT 0x40 |
104 | #define ADT7473_R2T_SHORT 0x80 | 92 | #define ADT7473_R2T_SHORT 0x80 |
105 | #define ADT7473_REG_MAX_ADDR 0x80 | ||
106 | 93 | ||
107 | #define ALARM2(x) ((x) << 8) | 94 | #define ALARM2(x) ((x) << 8) |
108 | 95 | ||
@@ -332,35 +319,24 @@ out: | |||
332 | } | 319 | } |
333 | 320 | ||
334 | /* | 321 | /* |
335 | * On this chip, voltages are given as a count of steps between a minimum | 322 | * Conversions |
336 | * and maximum voltage, not a direct voltage. | ||
337 | */ | 323 | */ |
338 | static const int volt_convert_table[][2] = { | 324 | |
339 | {2997, 3}, | 325 | /* IN are scaled acording to built-in resistors */ |
340 | {4395, 4}, | 326 | static const int adt7473_scaling[] = { /* .001 Volts */ |
327 | 2250, 3300 | ||
341 | }; | 328 | }; |
329 | #define SCALE(val, from, to) (((val) * (to) + ((from) / 2)) / (from)) | ||
342 | 330 | ||
343 | static int decode_volt(int volt_index, u8 raw) | 331 | static int decode_volt(int volt_index, u8 raw) |
344 | { | 332 | { |
345 | int cmax = volt_convert_table[volt_index][0]; | 333 | return SCALE(raw, 192, adt7473_scaling[volt_index]); |
346 | int cmin = volt_convert_table[volt_index][1]; | ||
347 | return ((raw * (cmax - cmin)) / 255) + cmin; | ||
348 | } | 334 | } |
349 | 335 | ||
350 | static u8 encode_volt(int volt_index, int cooked) | 336 | static u8 encode_volt(int volt_index, int cooked) |
351 | { | 337 | { |
352 | int cmax = volt_convert_table[volt_index][0]; | 338 | int raw = SCALE(cooked, adt7473_scaling[volt_index], 192); |
353 | int cmin = volt_convert_table[volt_index][1]; | 339 | return SENSORS_LIMIT(raw, 0, 255); |
354 | u8 x; | ||
355 | |||
356 | if (cooked > cmax) | ||
357 | cooked = cmax; | ||
358 | else if (cooked < cmin) | ||
359 | cooked = cmin; | ||
360 | |||
361 | x = ((cooked - cmin) * 255) / (cmax - cmin); | ||
362 | |||
363 | return x; | ||
364 | } | 340 | } |
365 | 341 | ||
366 | static ssize_t show_volt_min(struct device *dev, | 342 | static ssize_t show_volt_min(struct device *dev, |
@@ -583,10 +559,9 @@ static ssize_t set_max_duty_at_crit(struct device *dev, | |||
583 | struct i2c_client *client = to_i2c_client(dev); | 559 | struct i2c_client *client = to_i2c_client(dev); |
584 | struct adt7473_data *data = i2c_get_clientdata(client); | 560 | struct adt7473_data *data = i2c_get_clientdata(client); |
585 | int temp = simple_strtol(buf, NULL, 10); | 561 | int temp = simple_strtol(buf, NULL, 10); |
586 | temp = temp && 0xFF; | ||
587 | 562 | ||
588 | mutex_lock(&data->lock); | 563 | mutex_lock(&data->lock); |
589 | data->max_duty_at_overheat = temp; | 564 | data->max_duty_at_overheat = !!temp; |
590 | reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4); | 565 | reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4); |
591 | if (temp) | 566 | if (temp) |
592 | reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT; | 567 | reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT; |
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c index fbefa82a015c..6c9ace1b76f6 100644 --- a/drivers/hwmon/ams/ams-core.c +++ b/drivers/hwmon/ams/ams-core.c | |||
@@ -99,39 +99,31 @@ static struct pmf_irq_client ams_shock_client = { | |||
99 | */ | 99 | */ |
100 | static void ams_worker(struct work_struct *work) | 100 | static void ams_worker(struct work_struct *work) |
101 | { | 101 | { |
102 | mutex_lock(&ams_info.lock); | 102 | unsigned long flags; |
103 | 103 | u8 irqs_to_clear; | |
104 | if (ams_info.has_device) { | ||
105 | unsigned long flags; | ||
106 | 104 | ||
107 | spin_lock_irqsave(&ams_info.irq_lock, flags); | 105 | mutex_lock(&ams_info.lock); |
108 | 106 | ||
109 | if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) { | 107 | spin_lock_irqsave(&ams_info.irq_lock, flags); |
110 | if (verbose) | 108 | irqs_to_clear = ams_info.worker_irqs; |
111 | printk(KERN_INFO "ams: freefall detected!\n"); | ||
112 | 109 | ||
113 | ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL; | 110 | if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) { |
111 | if (verbose) | ||
112 | printk(KERN_INFO "ams: freefall detected!\n"); | ||
114 | 113 | ||
115 | /* we must call this with interrupts enabled */ | 114 | ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL; |
116 | spin_unlock_irqrestore(&ams_info.irq_lock, flags); | 115 | } |
117 | ams_info.clear_irq(AMS_IRQ_FREEFALL); | ||
118 | spin_lock_irqsave(&ams_info.irq_lock, flags); | ||
119 | } | ||
120 | 116 | ||
121 | if (ams_info.worker_irqs & AMS_IRQ_SHOCK) { | 117 | if (ams_info.worker_irqs & AMS_IRQ_SHOCK) { |
122 | if (verbose) | 118 | if (verbose) |
123 | printk(KERN_INFO "ams: shock detected!\n"); | 119 | printk(KERN_INFO "ams: shock detected!\n"); |
124 | 120 | ||
125 | ams_info.worker_irqs &= ~AMS_IRQ_SHOCK; | 121 | ams_info.worker_irqs &= ~AMS_IRQ_SHOCK; |
122 | } | ||
126 | 123 | ||
127 | /* we must call this with interrupts enabled */ | 124 | spin_unlock_irqrestore(&ams_info.irq_lock, flags); |
128 | spin_unlock_irqrestore(&ams_info.irq_lock, flags); | ||
129 | ams_info.clear_irq(AMS_IRQ_SHOCK); | ||
130 | spin_lock_irqsave(&ams_info.irq_lock, flags); | ||
131 | } | ||
132 | 125 | ||
133 | spin_unlock_irqrestore(&ams_info.irq_lock, flags); | 126 | ams_info.clear_irq(irqs_to_clear); |
134 | } | ||
135 | 127 | ||
136 | mutex_unlock(&ams_info.lock); | 128 | mutex_unlock(&ams_info.lock); |
137 | } | 129 | } |
@@ -223,34 +215,28 @@ int __init ams_init(void) | |||
223 | 215 | ||
224 | void ams_exit(void) | 216 | void ams_exit(void) |
225 | { | 217 | { |
226 | mutex_lock(&ams_info.lock); | 218 | /* Remove input device */ |
227 | 219 | ams_input_exit(); | |
228 | if (ams_info.has_device) { | ||
229 | /* Remove input device */ | ||
230 | ams_input_exit(); | ||
231 | 220 | ||
232 | /* Shut down implementation */ | 221 | /* Remove attributes */ |
233 | ams_info.exit(); | 222 | device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); |
234 | |||
235 | /* Flush interrupt worker | ||
236 | * | ||
237 | * We do this after ams_info.exit(), because an interrupt might | ||
238 | * have arrived before disabling them. | ||
239 | */ | ||
240 | flush_scheduled_work(); | ||
241 | 223 | ||
242 | /* Remove attributes */ | 224 | /* Shut down implementation */ |
243 | device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); | 225 | ams_info.exit(); |
244 | 226 | ||
245 | /* Remove device */ | 227 | /* Flush interrupt worker |
246 | of_device_unregister(ams_info.of_dev); | 228 | * |
229 | * We do this after ams_info.exit(), because an interrupt might | ||
230 | * have arrived before disabling them. | ||
231 | */ | ||
232 | flush_scheduled_work(); | ||
247 | 233 | ||
248 | /* Remove handler */ | 234 | /* Remove device */ |
249 | pmf_unregister_irq_client(&ams_shock_client); | 235 | of_device_unregister(ams_info.of_dev); |
250 | pmf_unregister_irq_client(&ams_freefall_client); | ||
251 | } | ||
252 | 236 | ||
253 | mutex_unlock(&ams_info.lock); | 237 | /* Remove handler */ |
238 | pmf_unregister_irq_client(&ams_shock_client); | ||
239 | pmf_unregister_irq_client(&ams_freefall_client); | ||
254 | } | 240 | } |
255 | 241 | ||
256 | MODULE_AUTHOR("Stelian Pop, Michael Hanselmann"); | 242 | MODULE_AUTHOR("Stelian Pop, Michael Hanselmann"); |
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c index 957760536a4c..2cbf8a6506c7 100644 --- a/drivers/hwmon/ams/ams-i2c.c +++ b/drivers/hwmon/ams/ams-i2c.c | |||
@@ -60,26 +60,34 @@ enum ams_i2c_cmd { | |||
60 | AMS_CMD_START, | 60 | AMS_CMD_START, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static int ams_i2c_attach(struct i2c_adapter *adapter); | 63 | static int ams_i2c_probe(struct i2c_client *client, |
64 | static int ams_i2c_detach(struct i2c_adapter *adapter); | 64 | const struct i2c_device_id *id); |
65 | static int ams_i2c_remove(struct i2c_client *client); | ||
66 | |||
67 | static const struct i2c_device_id ams_id[] = { | ||
68 | { "ams", 0 }, | ||
69 | { } | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(i2c, ams_id); | ||
65 | 72 | ||
66 | static struct i2c_driver ams_i2c_driver = { | 73 | static struct i2c_driver ams_i2c_driver = { |
67 | .driver = { | 74 | .driver = { |
68 | .name = "ams", | 75 | .name = "ams", |
69 | .owner = THIS_MODULE, | 76 | .owner = THIS_MODULE, |
70 | }, | 77 | }, |
71 | .attach_adapter = ams_i2c_attach, | 78 | .probe = ams_i2c_probe, |
72 | .detach_adapter = ams_i2c_detach, | 79 | .remove = ams_i2c_remove, |
80 | .id_table = ams_id, | ||
73 | }; | 81 | }; |
74 | 82 | ||
75 | static s32 ams_i2c_read(u8 reg) | 83 | static s32 ams_i2c_read(u8 reg) |
76 | { | 84 | { |
77 | return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg); | 85 | return i2c_smbus_read_byte_data(ams_info.i2c_client, reg); |
78 | } | 86 | } |
79 | 87 | ||
80 | static int ams_i2c_write(u8 reg, u8 value) | 88 | static int ams_i2c_write(u8 reg, u8 value) |
81 | { | 89 | { |
82 | return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value); | 90 | return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value); |
83 | } | 91 | } |
84 | 92 | ||
85 | static int ams_i2c_cmd(enum ams_i2c_cmd cmd) | 93 | static int ams_i2c_cmd(enum ams_i2c_cmd cmd) |
@@ -152,9 +160,9 @@ static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z) | |||
152 | *z = ams_i2c_read(AMS_DATAZ); | 160 | *z = ams_i2c_read(AMS_DATAZ); |
153 | } | 161 | } |
154 | 162 | ||
155 | static int ams_i2c_attach(struct i2c_adapter *adapter) | 163 | static int ams_i2c_probe(struct i2c_client *client, |
164 | const struct i2c_device_id *id) | ||
156 | { | 165 | { |
157 | unsigned long bus; | ||
158 | int vmaj, vmin; | 166 | int vmaj, vmin; |
159 | int result; | 167 | int result; |
160 | 168 | ||
@@ -162,17 +170,7 @@ static int ams_i2c_attach(struct i2c_adapter *adapter) | |||
162 | if (unlikely(ams_info.has_device)) | 170 | if (unlikely(ams_info.has_device)) |
163 | return -ENODEV; | 171 | return -ENODEV; |
164 | 172 | ||
165 | if (strncmp(adapter->name, "uni-n", 5)) | 173 | ams_info.i2c_client = client; |
166 | return -ENODEV; | ||
167 | |||
168 | bus = simple_strtoul(adapter->name + 6, NULL, 10); | ||
169 | if (bus != ams_info.i2c_bus) | ||
170 | return -ENODEV; | ||
171 | |||
172 | ams_info.i2c_client.addr = ams_info.i2c_address; | ||
173 | ams_info.i2c_client.adapter = adapter; | ||
174 | ams_info.i2c_client.driver = &ams_i2c_driver; | ||
175 | strcpy(ams_info.i2c_client.name, "Apple Motion Sensor"); | ||
176 | 174 | ||
177 | if (ams_i2c_cmd(AMS_CMD_RESET)) { | 175 | if (ams_i2c_cmd(AMS_CMD_RESET)) { |
178 | printk(KERN_INFO "ams: Failed to reset the device\n"); | 176 | printk(KERN_INFO "ams: Failed to reset the device\n"); |
@@ -237,7 +235,7 @@ static int ams_i2c_attach(struct i2c_adapter *adapter) | |||
237 | return 0; | 235 | return 0; |
238 | } | 236 | } |
239 | 237 | ||
240 | static int ams_i2c_detach(struct i2c_adapter *adapter) | 238 | static int ams_i2c_remove(struct i2c_client *client) |
241 | { | 239 | { |
242 | if (ams_info.has_device) { | 240 | if (ams_info.has_device) { |
243 | /* Disable interrupts */ | 241 | /* Disable interrupts */ |
@@ -261,11 +259,7 @@ static void ams_i2c_exit(void) | |||
261 | 259 | ||
262 | int __init ams_i2c_init(struct device_node *np) | 260 | int __init ams_i2c_init(struct device_node *np) |
263 | { | 261 | { |
264 | char *tmp_bus; | ||
265 | int result; | 262 | int result; |
266 | const u32 *prop; | ||
267 | |||
268 | mutex_lock(&ams_info.lock); | ||
269 | 263 | ||
270 | /* Set implementation stuff */ | 264 | /* Set implementation stuff */ |
271 | ams_info.of_node = np; | 265 | ams_info.of_node = np; |
@@ -275,25 +269,7 @@ int __init ams_i2c_init(struct device_node *np) | |||
275 | ams_info.clear_irq = ams_i2c_clear_irq; | 269 | ams_info.clear_irq = ams_i2c_clear_irq; |
276 | ams_info.bustype = BUS_I2C; | 270 | ams_info.bustype = BUS_I2C; |
277 | 271 | ||
278 | /* look for bus either using "reg" or by path */ | ||
279 | prop = of_get_property(ams_info.of_node, "reg", NULL); | ||
280 | if (!prop) { | ||
281 | result = -ENODEV; | ||
282 | |||
283 | goto exit; | ||
284 | } | ||
285 | |||
286 | tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@"); | ||
287 | if (tmp_bus) | ||
288 | ams_info.i2c_bus = *(tmp_bus + 9) - '0'; | ||
289 | else | ||
290 | ams_info.i2c_bus = ((*prop) >> 8) & 0x0f; | ||
291 | ams_info.i2c_address = ((*prop) & 0xff) >> 1; | ||
292 | |||
293 | result = i2c_add_driver(&ams_i2c_driver); | 272 | result = i2c_add_driver(&ams_i2c_driver); |
294 | 273 | ||
295 | exit: | ||
296 | mutex_unlock(&ams_info.lock); | ||
297 | |||
298 | return result; | 274 | return result; |
299 | } | 275 | } |
diff --git a/drivers/hwmon/ams/ams-input.c b/drivers/hwmon/ams/ams-input.c index 7b81e0c2c2d9..8a712392cd38 100644 --- a/drivers/hwmon/ams/ams-input.c +++ b/drivers/hwmon/ams/ams-input.c | |||
@@ -20,13 +20,15 @@ | |||
20 | #include "ams.h" | 20 | #include "ams.h" |
21 | 21 | ||
22 | static unsigned int joystick; | 22 | static unsigned int joystick; |
23 | module_param(joystick, bool, 0644); | 23 | module_param(joystick, bool, S_IRUGO); |
24 | MODULE_PARM_DESC(joystick, "Enable the input class device on module load"); | 24 | MODULE_PARM_DESC(joystick, "Enable the input class device on module load"); |
25 | 25 | ||
26 | static unsigned int invert; | 26 | static unsigned int invert; |
27 | module_param(invert, bool, 0644); | 27 | module_param(invert, bool, S_IWUSR | S_IRUGO); |
28 | MODULE_PARM_DESC(invert, "Invert input data on X and Y axis"); | 28 | MODULE_PARM_DESC(invert, "Invert input data on X and Y axis"); |
29 | 29 | ||
30 | static DEFINE_MUTEX(ams_input_mutex); | ||
31 | |||
30 | static void ams_idev_poll(struct input_polled_dev *dev) | 32 | static void ams_idev_poll(struct input_polled_dev *dev) |
31 | { | 33 | { |
32 | struct input_dev *idev = dev->input; | 34 | struct input_dev *idev = dev->input; |
@@ -50,13 +52,11 @@ static void ams_idev_poll(struct input_polled_dev *dev) | |||
50 | } | 52 | } |
51 | 53 | ||
52 | /* Call with ams_info.lock held! */ | 54 | /* Call with ams_info.lock held! */ |
53 | static void ams_input_enable(void) | 55 | static int ams_input_enable(void) |
54 | { | 56 | { |
55 | struct input_dev *input; | 57 | struct input_dev *input; |
56 | s8 x, y, z; | 58 | s8 x, y, z; |
57 | 59 | int error; | |
58 | if (ams_info.idev) | ||
59 | return; | ||
60 | 60 | ||
61 | ams_sensors(&x, &y, &z); | 61 | ams_sensors(&x, &y, &z); |
62 | ams_info.xcalib = x; | 62 | ams_info.xcalib = x; |
@@ -65,7 +65,7 @@ static void ams_input_enable(void) | |||
65 | 65 | ||
66 | ams_info.idev = input_allocate_polled_device(); | 66 | ams_info.idev = input_allocate_polled_device(); |
67 | if (!ams_info.idev) | 67 | if (!ams_info.idev) |
68 | return; | 68 | return -ENOMEM; |
69 | 69 | ||
70 | ams_info.idev->poll = ams_idev_poll; | 70 | ams_info.idev->poll = ams_idev_poll; |
71 | ams_info.idev->poll_interval = 25; | 71 | ams_info.idev->poll_interval = 25; |
@@ -84,14 +84,18 @@ static void ams_input_enable(void) | |||
84 | set_bit(EV_KEY, input->evbit); | 84 | set_bit(EV_KEY, input->evbit); |
85 | set_bit(BTN_TOUCH, input->keybit); | 85 | set_bit(BTN_TOUCH, input->keybit); |
86 | 86 | ||
87 | if (input_register_polled_device(ams_info.idev)) { | 87 | error = input_register_polled_device(ams_info.idev); |
88 | if (error) { | ||
88 | input_free_polled_device(ams_info.idev); | 89 | input_free_polled_device(ams_info.idev); |
89 | ams_info.idev = NULL; | 90 | ams_info.idev = NULL; |
90 | return; | 91 | return error; |
91 | } | 92 | } |
93 | |||
94 | joystick = 1; | ||
95 | |||
96 | return 0; | ||
92 | } | 97 | } |
93 | 98 | ||
94 | /* Call with ams_info.lock held! */ | ||
95 | static void ams_input_disable(void) | 99 | static void ams_input_disable(void) |
96 | { | 100 | { |
97 | if (ams_info.idev) { | 101 | if (ams_info.idev) { |
@@ -99,6 +103,8 @@ static void ams_input_disable(void) | |||
99 | input_free_polled_device(ams_info.idev); | 103 | input_free_polled_device(ams_info.idev); |
100 | ams_info.idev = NULL; | 104 | ams_info.idev = NULL; |
101 | } | 105 | } |
106 | |||
107 | joystick = 0; | ||
102 | } | 108 | } |
103 | 109 | ||
104 | static ssize_t ams_input_show_joystick(struct device *dev, | 110 | static ssize_t ams_input_show_joystick(struct device *dev, |
@@ -110,39 +116,42 @@ static ssize_t ams_input_show_joystick(struct device *dev, | |||
110 | static ssize_t ams_input_store_joystick(struct device *dev, | 116 | static ssize_t ams_input_store_joystick(struct device *dev, |
111 | struct device_attribute *attr, const char *buf, size_t count) | 117 | struct device_attribute *attr, const char *buf, size_t count) |
112 | { | 118 | { |
113 | if (sscanf(buf, "%d\n", &joystick) != 1) | 119 | unsigned long enable; |
120 | int error = 0; | ||
121 | |||
122 | if (strict_strtoul(buf, 0, &enable) || enable > 1) | ||
114 | return -EINVAL; | 123 | return -EINVAL; |
115 | 124 | ||
116 | mutex_lock(&ams_info.lock); | 125 | mutex_lock(&ams_input_mutex); |
117 | 126 | ||
118 | if (joystick) | 127 | if (enable != joystick) { |
119 | ams_input_enable(); | 128 | if (enable) |
120 | else | 129 | error = ams_input_enable(); |
121 | ams_input_disable(); | 130 | else |
131 | ams_input_disable(); | ||
132 | } | ||
122 | 133 | ||
123 | mutex_unlock(&ams_info.lock); | 134 | mutex_unlock(&ams_input_mutex); |
124 | 135 | ||
125 | return count; | 136 | return error ? error : count; |
126 | } | 137 | } |
127 | 138 | ||
128 | static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR, | 139 | static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR, |
129 | ams_input_show_joystick, ams_input_store_joystick); | 140 | ams_input_show_joystick, ams_input_store_joystick); |
130 | 141 | ||
131 | /* Call with ams_info.lock held! */ | ||
132 | int ams_input_init(void) | 142 | int ams_input_init(void) |
133 | { | 143 | { |
134 | int result; | 144 | if (joystick) |
135 | |||
136 | result = device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick); | ||
137 | |||
138 | if (!result && joystick) | ||
139 | ams_input_enable(); | 145 | ams_input_enable(); |
140 | return result; | 146 | |
147 | return device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick); | ||
141 | } | 148 | } |
142 | 149 | ||
143 | /* Call with ams_info.lock held! */ | ||
144 | void ams_input_exit(void) | 150 | void ams_input_exit(void) |
145 | { | 151 | { |
146 | ams_input_disable(); | ||
147 | device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick); | 152 | device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick); |
153 | |||
154 | mutex_lock(&ams_input_mutex); | ||
155 | ams_input_disable(); | ||
156 | mutex_unlock(&ams_input_mutex); | ||
148 | } | 157 | } |
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c index 9463e9768f6f..fb18b3d3162b 100644 --- a/drivers/hwmon/ams/ams-pmu.c +++ b/drivers/hwmon/ams/ams-pmu.c | |||
@@ -149,8 +149,6 @@ int __init ams_pmu_init(struct device_node *np) | |||
149 | const u32 *prop; | 149 | const u32 *prop; |
150 | int result; | 150 | int result; |
151 | 151 | ||
152 | mutex_lock(&ams_info.lock); | ||
153 | |||
154 | /* Set implementation stuff */ | 152 | /* Set implementation stuff */ |
155 | ams_info.of_node = np; | 153 | ams_info.of_node = np; |
156 | ams_info.exit = ams_pmu_exit; | 154 | ams_info.exit = ams_pmu_exit; |
@@ -161,10 +159,9 @@ int __init ams_pmu_init(struct device_node *np) | |||
161 | 159 | ||
162 | /* Get PMU command, should be 0x4e, but we can never know */ | 160 | /* Get PMU command, should be 0x4e, but we can never know */ |
163 | prop = of_get_property(ams_info.of_node, "reg", NULL); | 161 | prop = of_get_property(ams_info.of_node, "reg", NULL); |
164 | if (!prop) { | 162 | if (!prop) |
165 | result = -ENODEV; | 163 | return -ENODEV; |
166 | goto exit; | 164 | |
167 | } | ||
168 | ams_pmu_cmd = ((*prop) >> 8) & 0xff; | 165 | ams_pmu_cmd = ((*prop) >> 8) & 0xff; |
169 | 166 | ||
170 | /* Disable interrupts */ | 167 | /* Disable interrupts */ |
@@ -175,7 +172,7 @@ int __init ams_pmu_init(struct device_node *np) | |||
175 | 172 | ||
176 | result = ams_sensor_attach(); | 173 | result = ams_sensor_attach(); |
177 | if (result < 0) | 174 | if (result < 0) |
178 | goto exit; | 175 | return result; |
179 | 176 | ||
180 | /* Set default values */ | 177 | /* Set default values */ |
181 | ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15); | 178 | ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15); |
@@ -198,10 +195,5 @@ int __init ams_pmu_init(struct device_node *np) | |||
198 | 195 | ||
199 | printk(KERN_INFO "ams: Found PMU based motion sensor\n"); | 196 | printk(KERN_INFO "ams: Found PMU based motion sensor\n"); |
200 | 197 | ||
201 | result = 0; | 198 | return 0; |
202 | |||
203 | exit: | ||
204 | mutex_unlock(&ams_info.lock); | ||
205 | |||
206 | return result; | ||
207 | } | 199 | } |
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h index a6221e5dd984..5ed387b0bd9a 100644 --- a/drivers/hwmon/ams/ams.h +++ b/drivers/hwmon/ams/ams.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/mutex.h> | 4 | #include <linux/mutex.h> |
5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <asm/of_device.h> | 7 | #include <linux/of_device.h> |
8 | 8 | ||
9 | enum ams_irq { | 9 | enum ams_irq { |
10 | AMS_IRQ_FREEFALL = 0x01, | 10 | AMS_IRQ_FREEFALL = 0x01, |
@@ -46,9 +46,7 @@ struct ams { | |||
46 | 46 | ||
47 | #ifdef CONFIG_SENSORS_AMS_I2C | 47 | #ifdef CONFIG_SENSORS_AMS_I2C |
48 | /* I2C properties */ | 48 | /* I2C properties */ |
49 | int i2c_bus; | 49 | struct i2c_client *i2c_client; |
50 | int i2c_address; | ||
51 | struct i2c_client i2c_client; | ||
52 | #endif | 50 | #endif |
53 | 51 | ||
54 | /* Joystick emulation */ | 52 | /* Joystick emulation */ |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index aacc0c4b809c..bc011da79e14 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -49,6 +49,9 @@ | |||
49 | 49 | ||
50 | #define APPLESMC_MAX_DATA_LENGTH 32 | 50 | #define APPLESMC_MAX_DATA_LENGTH 32 |
51 | 51 | ||
52 | #define APPLESMC_MIN_WAIT 0x0040 | ||
53 | #define APPLESMC_MAX_WAIT 0x8000 | ||
54 | |||
52 | #define APPLESMC_STATUS_MASK 0x0f | 55 | #define APPLESMC_STATUS_MASK 0x0f |
53 | #define APPLESMC_READ_CMD 0x10 | 56 | #define APPLESMC_READ_CMD 0x10 |
54 | #define APPLESMC_WRITE_CMD 0x11 | 57 | #define APPLESMC_WRITE_CMD 0x11 |
@@ -57,8 +60,8 @@ | |||
57 | 60 | ||
58 | #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ | 61 | #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ |
59 | 62 | ||
60 | #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */ | 63 | #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6-10 bytes) */ |
61 | #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */ | 64 | #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6-10 bytes) */ |
62 | #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ | 65 | #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ |
63 | 66 | ||
64 | #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ | 67 | #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ |
@@ -98,6 +101,21 @@ static const char* temperature_sensors_sets[][36] = { | |||
98 | "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", | 101 | "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", |
99 | "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", | 102 | "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", |
100 | "TM9S", "TN0H", "TS0C", NULL }, | 103 | "TM9S", "TN0H", "TS0C", NULL }, |
104 | /* Set 5: iMac */ | ||
105 | { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P", | ||
106 | "Tp0C", NULL }, | ||
107 | /* Set 6: Macbook3 set */ | ||
108 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H", | ||
109 | "Th0S", "Th1H", NULL }, | ||
110 | /* Set 7: Macbook Air */ | ||
111 | { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP", | ||
112 | "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL }, | ||
113 | /* Set 8: Macbook Pro 4,1 (Penryn) */ | ||
114 | { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H", | ||
115 | "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, | ||
116 | /* Set 9: Macbook Pro 3,1 (Santa Rosa) */ | ||
117 | { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", | ||
118 | "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, | ||
101 | }; | 119 | }; |
102 | 120 | ||
103 | /* List of keys used to read/write fan speeds */ | 121 | /* List of keys used to read/write fan speeds */ |
@@ -157,25 +175,25 @@ static unsigned int key_at_index; | |||
157 | static struct workqueue_struct *applesmc_led_wq; | 175 | static struct workqueue_struct *applesmc_led_wq; |
158 | 176 | ||
159 | /* | 177 | /* |
160 | * __wait_status - Wait up to 2ms for the status port to get a certain value | 178 | * __wait_status - Wait up to 32ms for the status port to get a certain value |
161 | * (masked with 0x0f), returning zero if the value is obtained. Callers must | 179 | * (masked with 0x0f), returning zero if the value is obtained. Callers must |
162 | * hold applesmc_lock. | 180 | * hold applesmc_lock. |
163 | */ | 181 | */ |
164 | static int __wait_status(u8 val) | 182 | static int __wait_status(u8 val) |
165 | { | 183 | { |
166 | unsigned int i; | 184 | int us; |
167 | 185 | ||
168 | val = val & APPLESMC_STATUS_MASK; | 186 | val = val & APPLESMC_STATUS_MASK; |
169 | 187 | ||
170 | for (i = 0; i < 200; i++) { | 188 | for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { |
189 | udelay(us); | ||
171 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { | 190 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { |
172 | if (debug) | 191 | if (debug) |
173 | printk(KERN_DEBUG | 192 | printk(KERN_DEBUG |
174 | "Waited %d us for status %x\n", | 193 | "Waited %d us for status %x\n", |
175 | i*10, val); | 194 | 2 * us - APPLESMC_MIN_WAIT, val); |
176 | return 0; | 195 | return 0; |
177 | } | 196 | } |
178 | udelay(10); | ||
179 | } | 197 | } |
180 | 198 | ||
181 | printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", | 199 | printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", |
@@ -185,6 +203,25 @@ static int __wait_status(u8 val) | |||
185 | } | 203 | } |
186 | 204 | ||
187 | /* | 205 | /* |
206 | * special treatment of command port - on newer macbooks, it seems necessary | ||
207 | * to resend the command byte before polling the status again. Callers must | ||
208 | * hold applesmc_lock. | ||
209 | */ | ||
210 | static int send_command(u8 cmd) | ||
211 | { | ||
212 | int us; | ||
213 | for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { | ||
214 | outb(cmd, APPLESMC_CMD_PORT); | ||
215 | udelay(us); | ||
216 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) | ||
217 | return 0; | ||
218 | } | ||
219 | printk(KERN_WARNING "applesmc: command failed: %x -> %x\n", | ||
220 | cmd, inb(APPLESMC_CMD_PORT)); | ||
221 | return -EIO; | ||
222 | } | ||
223 | |||
224 | /* | ||
188 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. | 225 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. |
189 | * Returns zero on success or a negative error on failure. Callers must | 226 | * Returns zero on success or a negative error on failure. Callers must |
190 | * hold applesmc_lock. | 227 | * hold applesmc_lock. |
@@ -199,8 +236,7 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len) | |||
199 | return -EINVAL; | 236 | return -EINVAL; |
200 | } | 237 | } |
201 | 238 | ||
202 | outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); | 239 | if (send_command(APPLESMC_READ_CMD)) |
203 | if (__wait_status(0x0c)) | ||
204 | return -EIO; | 240 | return -EIO; |
205 | 241 | ||
206 | for (i = 0; i < 4; i++) { | 242 | for (i = 0; i < 4; i++) { |
@@ -243,8 +279,7 @@ static int applesmc_write_key(const char* key, u8* buffer, u8 len) | |||
243 | return -EINVAL; | 279 | return -EINVAL; |
244 | } | 280 | } |
245 | 281 | ||
246 | outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT); | 282 | if (send_command(APPLESMC_WRITE_CMD)) |
247 | if (__wait_status(0x0c)) | ||
248 | return -EIO; | 283 | return -EIO; |
249 | 284 | ||
250 | for (i = 0; i < 4; i++) { | 285 | for (i = 0; i < 4; i++) { |
@@ -278,8 +313,7 @@ static int applesmc_get_key_at_index(int index, char* key) | |||
278 | readkey[2] = index >> 8; | 313 | readkey[2] = index >> 8; |
279 | readkey[3] = index; | 314 | readkey[3] = index; |
280 | 315 | ||
281 | outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT); | 316 | if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD)) |
282 | if (__wait_status(0x0c)) | ||
283 | return -EIO; | 317 | return -EIO; |
284 | 318 | ||
285 | for (i = 0; i < 4; i++) { | 319 | for (i = 0; i < 4; i++) { |
@@ -309,8 +343,7 @@ static int applesmc_get_key_type(char* key, char* type) | |||
309 | { | 343 | { |
310 | int i; | 344 | int i; |
311 | 345 | ||
312 | outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT); | 346 | if (send_command(APPLESMC_GET_KEY_TYPE_CMD)) |
313 | if (__wait_status(0x0c)) | ||
314 | return -EIO; | 347 | return -EIO; |
315 | 348 | ||
316 | for (i = 0; i < 4; i++) { | 349 | for (i = 0; i < 4; i++) { |
@@ -319,7 +352,7 @@ static int applesmc_get_key_type(char* key, char* type) | |||
319 | return -EIO; | 352 | return -EIO; |
320 | } | 353 | } |
321 | 354 | ||
322 | outb(5, APPLESMC_DATA_PORT); | 355 | outb(6, APPLESMC_DATA_PORT); |
323 | 356 | ||
324 | for (i = 0; i < 6; i++) { | 357 | for (i = 0; i < 6; i++) { |
325 | if (__wait_status(0x05)) | 358 | if (__wait_status(0x05)) |
@@ -521,17 +554,27 @@ out: | |||
521 | static ssize_t applesmc_light_show(struct device *dev, | 554 | static ssize_t applesmc_light_show(struct device *dev, |
522 | struct device_attribute *attr, char *sysfsbuf) | 555 | struct device_attribute *attr, char *sysfsbuf) |
523 | { | 556 | { |
557 | static int data_length; | ||
524 | int ret; | 558 | int ret; |
525 | u8 left = 0, right = 0; | 559 | u8 left = 0, right = 0; |
526 | u8 buffer[6]; | 560 | u8 buffer[10], query[6]; |
527 | 561 | ||
528 | mutex_lock(&applesmc_lock); | 562 | mutex_lock(&applesmc_lock); |
529 | 563 | ||
530 | ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6); | 564 | if (!data_length) { |
565 | ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query); | ||
566 | if (ret) | ||
567 | goto out; | ||
568 | data_length = clamp_val(query[0], 0, 10); | ||
569 | printk(KERN_INFO "applesmc: light sensor data length set to " | ||
570 | "%d\n", data_length); | ||
571 | } | ||
572 | |||
573 | ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); | ||
531 | left = buffer[2]; | 574 | left = buffer[2]; |
532 | if (ret) | 575 | if (ret) |
533 | goto out; | 576 | goto out; |
534 | ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6); | 577 | ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); |
535 | right = buffer[2]; | 578 | right = buffer[2]; |
536 | 579 | ||
537 | out: | 580 | out: |
@@ -1223,31 +1266,61 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1223 | { .accelerometer = 0, .light = 0, .temperature_set = 3 }, | 1266 | { .accelerometer = 0, .light = 0, .temperature_set = 3 }, |
1224 | /* MacPro: temperature set 4 */ | 1267 | /* MacPro: temperature set 4 */ |
1225 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, | 1268 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, |
1269 | /* iMac: temperature set 5 */ | ||
1270 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, | ||
1271 | /* MacBook3: accelerometer and temperature set 6 */ | ||
1272 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, | ||
1273 | /* MacBook Air: accelerometer, backlight and temperature set 7 */ | ||
1274 | { .accelerometer = 1, .light = 1, .temperature_set = 7 }, | ||
1275 | /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */ | ||
1276 | { .accelerometer = 1, .light = 1, .temperature_set = 8 }, | ||
1277 | /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ | ||
1278 | { .accelerometer = 1, .light = 1, .temperature_set = 9 }, | ||
1226 | }; | 1279 | }; |
1227 | 1280 | ||
1228 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1281 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
1229 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ | 1282 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ |
1230 | static __initdata struct dmi_system_id applesmc_whitelist[] = { | 1283 | static __initdata struct dmi_system_id applesmc_whitelist[] = { |
1284 | { applesmc_dmi_match, "Apple MacBook Air", { | ||
1285 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1286 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, | ||
1287 | &applesmc_dmi_data[7]}, | ||
1288 | { applesmc_dmi_match, "Apple MacBook Pro 4", { | ||
1289 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1290 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, | ||
1291 | &applesmc_dmi_data[8]}, | ||
1292 | { applesmc_dmi_match, "Apple MacBook Pro 3", { | ||
1293 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1294 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, | ||
1295 | &applesmc_dmi_data[9]}, | ||
1231 | { applesmc_dmi_match, "Apple MacBook Pro", { | 1296 | { applesmc_dmi_match, "Apple MacBook Pro", { |
1232 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1297 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1233 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, | 1298 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, |
1234 | (void*)&applesmc_dmi_data[0]}, | 1299 | &applesmc_dmi_data[0]}, |
1235 | { applesmc_dmi_match, "Apple MacBook", { | 1300 | { applesmc_dmi_match, "Apple MacBook (v2)", { |
1236 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1301 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1237 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, | 1302 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, |
1238 | (void*)&applesmc_dmi_data[1]}, | 1303 | &applesmc_dmi_data[1]}, |
1304 | { applesmc_dmi_match, "Apple MacBook (v3)", { | ||
1305 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
1306 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, | ||
1307 | &applesmc_dmi_data[6]}, | ||
1239 | { applesmc_dmi_match, "Apple MacBook", { | 1308 | { applesmc_dmi_match, "Apple MacBook", { |
1240 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1309 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1241 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, | 1310 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, |
1242 | (void*)&applesmc_dmi_data[2]}, | 1311 | &applesmc_dmi_data[2]}, |
1243 | { applesmc_dmi_match, "Apple Macmini", { | 1312 | { applesmc_dmi_match, "Apple Macmini", { |
1244 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1313 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1245 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, | 1314 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, |
1246 | (void*)&applesmc_dmi_data[3]}, | 1315 | &applesmc_dmi_data[3]}, |
1247 | { applesmc_dmi_match, "Apple MacPro2", { | 1316 | { applesmc_dmi_match, "Apple MacPro2", { |
1248 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1317 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1249 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, | 1318 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, |
1250 | (void*)&applesmc_dmi_data[4]}, | 1319 | &applesmc_dmi_data[4]}, |
1320 | { applesmc_dmi_match, "Apple iMac", { | ||
1321 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
1322 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, | ||
1323 | &applesmc_dmi_data[5]}, | ||
1251 | { .ident = NULL } | 1324 | { .ident = NULL } |
1252 | }; | 1325 | }; |
1253 | 1326 | ||
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index d191118ba0cb..d6b490d3e36f 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); | 33 | MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); |
34 | MODULE_VERSION("0.6.2"); | 34 | MODULE_VERSION("0.6.3"); |
35 | MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>"); | 35 | MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>"); |
36 | 36 | ||
37 | #define ATXP1_VID 0x00 | 37 | #define ATXP1_VID 0x00 |
@@ -289,16 +289,16 @@ static int atxp1_detect(struct i2c_client *new_client, int kind, | |||
289 | if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && | 289 | if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && |
290 | (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) && | 290 | (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) && |
291 | (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) && | 291 | (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) && |
292 | (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) { | 292 | (i2c_smbus_read_byte_data(new_client, 0xff) == 0))) |
293 | return -ENODEV; | ||
293 | 294 | ||
294 | /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) | 295 | /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) |
295 | * showing the same as register 0x00 */ | 296 | * showing the same as register 0x00 */ |
296 | temp = i2c_smbus_read_byte_data(new_client, 0x00); | 297 | temp = i2c_smbus_read_byte_data(new_client, 0x00); |
297 | 298 | ||
298 | if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && | 299 | if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && |
299 | (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) | 300 | (i2c_smbus_read_byte_data(new_client, 0x11) == temp))) |
300 | return -ENODEV; | 301 | return -ENODEV; |
301 | } | ||
302 | 302 | ||
303 | /* Get VRM */ | 303 | /* Get VRM */ |
304 | temp = vid_which_vrm(); | 304 | temp = vid_which_vrm(); |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 70239acecc8e..93c17223b527 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -413,10 +413,11 @@ static int __init coretemp_init(void) | |||
413 | for_each_online_cpu(i) { | 413 | for_each_online_cpu(i) { |
414 | struct cpuinfo_x86 *c = &cpu_data(i); | 414 | struct cpuinfo_x86 *c = &cpu_data(i); |
415 | 415 | ||
416 | /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */ | 416 | /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A */ |
417 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || | 417 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || |
418 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || | 418 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || |
419 | (c->x86_model == 0x16) || (c->x86_model == 0x17))) { | 419 | (c->x86_model == 0x16) || (c->x86_model == 0x17) || |
420 | (c->x86_model == 0x1A))) { | ||
420 | 421 | ||
421 | /* supported CPU not found, but report the unknown | 422 | /* supported CPU not found, but report the unknown |
422 | family 6 CPU */ | 423 | family 6 CPU */ |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 7673f65877e1..27a5d397f9a1 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, and SMSC SCH311x | 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and |
3 | * Super-I/O chips integrated hardware monitoring features. | 3 | * SCH5027 Super-I/O chips integrated hardware monitoring features. |
4 | * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> | 4 | * Copyright (c) 2007, 2008 Juerg Haefliger <juergh@gmail.com> |
5 | * | 5 | * |
6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access | 6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access |
7 | * the chip registers if a DME1737 (or A8000) is found and the ISA bus if a | 7 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus |
8 | * SCH311x chip is found. Both types of chips have very similar hardware | 8 | * if a SCH311x chip is found. Both types of chips have very similar hardware |
9 | * monitoring capabilities but differ in the way they can be accessed. | 9 | * monitoring capabilities but differ in the way they can be accessed. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -48,11 +48,19 @@ static unsigned short force_id; | |||
48 | module_param(force_id, ushort, 0); | 48 | module_param(force_id, ushort, 0); |
49 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 49 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
50 | 50 | ||
51 | static int probe_all_addr; | ||
52 | module_param(probe_all_addr, bool, 0); | ||
53 | MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " | ||
54 | "addresses"); | ||
55 | |||
51 | /* Addresses to scan */ | 56 | /* Addresses to scan */ |
52 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 57 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; |
53 | 58 | ||
54 | /* Insmod parameters */ | 59 | /* Insmod parameters */ |
55 | I2C_CLIENT_INSMOD_1(dme1737); | 60 | I2C_CLIENT_INSMOD_2(dme1737, sch5027); |
61 | |||
62 | /* ISA chip types */ | ||
63 | enum isa_chips { sch311x = sch5027 + 1 }; | ||
56 | 64 | ||
57 | /* --------------------------------------------------------------------- | 65 | /* --------------------------------------------------------------------- |
58 | * Registers | 66 | * Registers |
@@ -158,6 +166,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
158 | #define DME1737_VERSTEP 0x88 | 166 | #define DME1737_VERSTEP 0x88 |
159 | #define DME1737_VERSTEP_MASK 0xf8 | 167 | #define DME1737_VERSTEP_MASK 0xf8 |
160 | #define SCH311X_DEVICE 0x8c | 168 | #define SCH311X_DEVICE 0x8c |
169 | #define SCH5027_VERSTEP 0x69 | ||
161 | 170 | ||
162 | /* Length of ISA address segment */ | 171 | /* Length of ISA address segment */ |
163 | #define DME1737_EXTENT 2 | 172 | #define DME1737_EXTENT 2 |
@@ -166,16 +175,18 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
166 | * Data structures and manipulation thereof | 175 | * Data structures and manipulation thereof |
167 | * --------------------------------------------------------------------- */ | 176 | * --------------------------------------------------------------------- */ |
168 | 177 | ||
169 | /* For ISA chips, we abuse the i2c_client addr and name fields. We also use | ||
170 | the driver field to differentiate between I2C and ISA chips. */ | ||
171 | struct dme1737_data { | 178 | struct dme1737_data { |
172 | struct i2c_client client; | 179 | struct i2c_client *client; /* for I2C devices only */ |
173 | struct device *hwmon_dev; | 180 | struct device *hwmon_dev; |
181 | const char *name; | ||
182 | unsigned int addr; /* for ISA devices only */ | ||
174 | 183 | ||
175 | struct mutex update_lock; | 184 | struct mutex update_lock; |
176 | int valid; /* !=0 if following fields are valid */ | 185 | int valid; /* !=0 if following fields are valid */ |
177 | unsigned long last_update; /* in jiffies */ | 186 | unsigned long last_update; /* in jiffies */ |
178 | unsigned long last_vbat; /* in jiffies */ | 187 | unsigned long last_vbat; /* in jiffies */ |
188 | enum chips type; | ||
189 | const int *in_nominal; /* pointer to IN_NOMINAL array */ | ||
179 | 190 | ||
180 | u8 vid; | 191 | u8 vid; |
181 | u8 pwm_rr_en; | 192 | u8 pwm_rr_en; |
@@ -210,20 +221,27 @@ struct dme1737_data { | |||
210 | }; | 221 | }; |
211 | 222 | ||
212 | /* Nominal voltage values */ | 223 | /* Nominal voltage values */ |
213 | static const int IN_NOMINAL[] = {5000, 2250, 3300, 5000, 12000, 3300, 3300}; | 224 | static const int IN_NOMINAL_DME1737[] = {5000, 2250, 3300, 5000, 12000, 3300, |
225 | 3300}; | ||
226 | static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, | ||
227 | 3300}; | ||
228 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, | ||
229 | 3300}; | ||
230 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ | ||
231 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ | ||
232 | IN_NOMINAL_DME1737) | ||
214 | 233 | ||
215 | /* Voltage input | 234 | /* Voltage input |
216 | * Voltage inputs have 16 bits resolution, limit values have 8 bits | 235 | * Voltage inputs have 16 bits resolution, limit values have 8 bits |
217 | * resolution. */ | 236 | * resolution. */ |
218 | static inline int IN_FROM_REG(int reg, int ix, int res) | 237 | static inline int IN_FROM_REG(int reg, int nominal, int res) |
219 | { | 238 | { |
220 | return (reg * IN_NOMINAL[ix] + (3 << (res - 3))) / (3 << (res - 2)); | 239 | return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2)); |
221 | } | 240 | } |
222 | 241 | ||
223 | static inline int IN_TO_REG(int val, int ix) | 242 | static inline int IN_TO_REG(int val, int nominal) |
224 | { | 243 | { |
225 | return SENSORS_LIMIT((val * 192 + IN_NOMINAL[ix] / 2) / | 244 | return SENSORS_LIMIT((val * 192 + nominal / 2) / nominal, 0, 255); |
226 | IN_NOMINAL[ix], 0, 255); | ||
227 | } | 245 | } |
228 | 246 | ||
229 | /* Temperature input | 247 | /* Temperature input |
@@ -494,11 +512,12 @@ static inline int PWM_OFF_TO_REG(int val, int ix, int reg) | |||
494 | * before calling dme1737_read or dme1737_write. | 512 | * before calling dme1737_read or dme1737_write. |
495 | * --------------------------------------------------------------------- */ | 513 | * --------------------------------------------------------------------- */ |
496 | 514 | ||
497 | static u8 dme1737_read(struct i2c_client *client, u8 reg) | 515 | static u8 dme1737_read(const struct dme1737_data *data, u8 reg) |
498 | { | 516 | { |
517 | struct i2c_client *client = data->client; | ||
499 | s32 val; | 518 | s32 val; |
500 | 519 | ||
501 | if (client->driver) { /* I2C device */ | 520 | if (client) { /* I2C device */ |
502 | val = i2c_smbus_read_byte_data(client, reg); | 521 | val = i2c_smbus_read_byte_data(client, reg); |
503 | 522 | ||
504 | if (val < 0) { | 523 | if (val < 0) { |
@@ -507,18 +526,19 @@ static u8 dme1737_read(struct i2c_client *client, u8 reg) | |||
507 | "maintainer.\n", reg); | 526 | "maintainer.\n", reg); |
508 | } | 527 | } |
509 | } else { /* ISA device */ | 528 | } else { /* ISA device */ |
510 | outb(reg, client->addr); | 529 | outb(reg, data->addr); |
511 | val = inb(client->addr + 1); | 530 | val = inb(data->addr + 1); |
512 | } | 531 | } |
513 | 532 | ||
514 | return val; | 533 | return val; |
515 | } | 534 | } |
516 | 535 | ||
517 | static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) | 536 | static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val) |
518 | { | 537 | { |
538 | struct i2c_client *client = data->client; | ||
519 | s32 res = 0; | 539 | s32 res = 0; |
520 | 540 | ||
521 | if (client->driver) { /* I2C device */ | 541 | if (client) { /* I2C device */ |
522 | res = i2c_smbus_write_byte_data(client, reg, val); | 542 | res = i2c_smbus_write_byte_data(client, reg, val); |
523 | 543 | ||
524 | if (res < 0) { | 544 | if (res < 0) { |
@@ -527,8 +547,8 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) | |||
527 | "maintainer.\n", reg); | 547 | "maintainer.\n", reg); |
528 | } | 548 | } |
529 | } else { /* ISA device */ | 549 | } else { /* ISA device */ |
530 | outb(reg, client->addr); | 550 | outb(reg, data->addr); |
531 | outb(val, client->addr + 1); | 551 | outb(val, data->addr + 1); |
532 | } | 552 | } |
533 | 553 | ||
534 | return res; | 554 | return res; |
@@ -537,7 +557,6 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) | |||
537 | static struct dme1737_data *dme1737_update_device(struct device *dev) | 557 | static struct dme1737_data *dme1737_update_device(struct device *dev) |
538 | { | 558 | { |
539 | struct dme1737_data *data = dev_get_drvdata(dev); | 559 | struct dme1737_data *data = dev_get_drvdata(dev); |
540 | struct i2c_client *client = &data->client; | ||
541 | int ix; | 560 | int ix; |
542 | u8 lsb[5]; | 561 | u8 lsb[5]; |
543 | 562 | ||
@@ -545,25 +564,28 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
545 | 564 | ||
546 | /* Enable a Vbat monitoring cycle every 10 mins */ | 565 | /* Enable a Vbat monitoring cycle every 10 mins */ |
547 | if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) { | 566 | if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) { |
548 | dme1737_write(client, DME1737_REG_CONFIG, dme1737_read(client, | 567 | dme1737_write(data, DME1737_REG_CONFIG, dme1737_read(data, |
549 | DME1737_REG_CONFIG) | 0x10); | 568 | DME1737_REG_CONFIG) | 0x10); |
550 | data->last_vbat = jiffies; | 569 | data->last_vbat = jiffies; |
551 | } | 570 | } |
552 | 571 | ||
553 | /* Sample register contents every 1 sec */ | 572 | /* Sample register contents every 1 sec */ |
554 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | 573 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { |
555 | data->vid = dme1737_read(client, DME1737_REG_VID) & 0x3f; | 574 | if (data->type != sch5027) { |
575 | data->vid = dme1737_read(data, DME1737_REG_VID) & | ||
576 | 0x3f; | ||
577 | } | ||
556 | 578 | ||
557 | /* In (voltage) registers */ | 579 | /* In (voltage) registers */ |
558 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | 580 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { |
559 | /* Voltage inputs are stored as 16 bit values even | 581 | /* Voltage inputs are stored as 16 bit values even |
560 | * though they have only 12 bits resolution. This is | 582 | * though they have only 12 bits resolution. This is |
561 | * to make it consistent with the temp inputs. */ | 583 | * to make it consistent with the temp inputs. */ |
562 | data->in[ix] = dme1737_read(client, | 584 | data->in[ix] = dme1737_read(data, |
563 | DME1737_REG_IN(ix)) << 8; | 585 | DME1737_REG_IN(ix)) << 8; |
564 | data->in_min[ix] = dme1737_read(client, | 586 | data->in_min[ix] = dme1737_read(data, |
565 | DME1737_REG_IN_MIN(ix)); | 587 | DME1737_REG_IN_MIN(ix)); |
566 | data->in_max[ix] = dme1737_read(client, | 588 | data->in_max[ix] = dme1737_read(data, |
567 | DME1737_REG_IN_MAX(ix)); | 589 | DME1737_REG_IN_MAX(ix)); |
568 | } | 590 | } |
569 | 591 | ||
@@ -574,14 +596,16 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
574 | * to take advantage of implicit conversions between | 596 | * to take advantage of implicit conversions between |
575 | * register values (2's complement) and temp values | 597 | * register values (2's complement) and temp values |
576 | * (signed decimal). */ | 598 | * (signed decimal). */ |
577 | data->temp[ix] = dme1737_read(client, | 599 | data->temp[ix] = dme1737_read(data, |
578 | DME1737_REG_TEMP(ix)) << 8; | 600 | DME1737_REG_TEMP(ix)) << 8; |
579 | data->temp_min[ix] = dme1737_read(client, | 601 | data->temp_min[ix] = dme1737_read(data, |
580 | DME1737_REG_TEMP_MIN(ix)); | 602 | DME1737_REG_TEMP_MIN(ix)); |
581 | data->temp_max[ix] = dme1737_read(client, | 603 | data->temp_max[ix] = dme1737_read(data, |
582 | DME1737_REG_TEMP_MAX(ix)); | 604 | DME1737_REG_TEMP_MAX(ix)); |
583 | data->temp_offset[ix] = dme1737_read(client, | 605 | if (data->type != sch5027) { |
584 | DME1737_REG_TEMP_OFFSET(ix)); | 606 | data->temp_offset[ix] = dme1737_read(data, |
607 | DME1737_REG_TEMP_OFFSET(ix)); | ||
608 | } | ||
585 | } | 609 | } |
586 | 610 | ||
587 | /* In and temp LSB registers | 611 | /* In and temp LSB registers |
@@ -589,7 +613,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
589 | * which the registers are read (MSB first, then LSB) is | 613 | * which the registers are read (MSB first, then LSB) is |
590 | * important! */ | 614 | * important! */ |
591 | for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { | 615 | for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { |
592 | lsb[ix] = dme1737_read(client, | 616 | lsb[ix] = dme1737_read(data, |
593 | DME1737_REG_IN_TEMP_LSB(ix)); | 617 | DME1737_REG_IN_TEMP_LSB(ix)); |
594 | } | 618 | } |
595 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | 619 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { |
@@ -608,19 +632,19 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
608 | if (!(data->has_fan & (1 << ix))) { | 632 | if (!(data->has_fan & (1 << ix))) { |
609 | continue; | 633 | continue; |
610 | } | 634 | } |
611 | data->fan[ix] = dme1737_read(client, | 635 | data->fan[ix] = dme1737_read(data, |
612 | DME1737_REG_FAN(ix)); | 636 | DME1737_REG_FAN(ix)); |
613 | data->fan[ix] |= dme1737_read(client, | 637 | data->fan[ix] |= dme1737_read(data, |
614 | DME1737_REG_FAN(ix) + 1) << 8; | 638 | DME1737_REG_FAN(ix) + 1) << 8; |
615 | data->fan_min[ix] = dme1737_read(client, | 639 | data->fan_min[ix] = dme1737_read(data, |
616 | DME1737_REG_FAN_MIN(ix)); | 640 | DME1737_REG_FAN_MIN(ix)); |
617 | data->fan_min[ix] |= dme1737_read(client, | 641 | data->fan_min[ix] |= dme1737_read(data, |
618 | DME1737_REG_FAN_MIN(ix) + 1) << 8; | 642 | DME1737_REG_FAN_MIN(ix) + 1) << 8; |
619 | data->fan_opt[ix] = dme1737_read(client, | 643 | data->fan_opt[ix] = dme1737_read(data, |
620 | DME1737_REG_FAN_OPT(ix)); | 644 | DME1737_REG_FAN_OPT(ix)); |
621 | /* fan_max exists only for fan[5-6] */ | 645 | /* fan_max exists only for fan[5-6] */ |
622 | if (ix > 3) { | 646 | if (ix > 3) { |
623 | data->fan_max[ix - 4] = dme1737_read(client, | 647 | data->fan_max[ix - 4] = dme1737_read(data, |
624 | DME1737_REG_FAN_MAX(ix)); | 648 | DME1737_REG_FAN_MAX(ix)); |
625 | } | 649 | } |
626 | } | 650 | } |
@@ -632,61 +656,63 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
632 | if (!(data->has_pwm & (1 << ix))) { | 656 | if (!(data->has_pwm & (1 << ix))) { |
633 | continue; | 657 | continue; |
634 | } | 658 | } |
635 | data->pwm[ix] = dme1737_read(client, | 659 | data->pwm[ix] = dme1737_read(data, |
636 | DME1737_REG_PWM(ix)); | 660 | DME1737_REG_PWM(ix)); |
637 | data->pwm_freq[ix] = dme1737_read(client, | 661 | data->pwm_freq[ix] = dme1737_read(data, |
638 | DME1737_REG_PWM_FREQ(ix)); | 662 | DME1737_REG_PWM_FREQ(ix)); |
639 | /* pwm_config and pwm_min exist only for pwm[1-3] */ | 663 | /* pwm_config and pwm_min exist only for pwm[1-3] */ |
640 | if (ix < 3) { | 664 | if (ix < 3) { |
641 | data->pwm_config[ix] = dme1737_read(client, | 665 | data->pwm_config[ix] = dme1737_read(data, |
642 | DME1737_REG_PWM_CONFIG(ix)); | 666 | DME1737_REG_PWM_CONFIG(ix)); |
643 | data->pwm_min[ix] = dme1737_read(client, | 667 | data->pwm_min[ix] = dme1737_read(data, |
644 | DME1737_REG_PWM_MIN(ix)); | 668 | DME1737_REG_PWM_MIN(ix)); |
645 | } | 669 | } |
646 | } | 670 | } |
647 | for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) { | 671 | for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) { |
648 | data->pwm_rr[ix] = dme1737_read(client, | 672 | data->pwm_rr[ix] = dme1737_read(data, |
649 | DME1737_REG_PWM_RR(ix)); | 673 | DME1737_REG_PWM_RR(ix)); |
650 | } | 674 | } |
651 | 675 | ||
652 | /* Thermal zone registers */ | 676 | /* Thermal zone registers */ |
653 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { | 677 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { |
654 | data->zone_low[ix] = dme1737_read(client, | 678 | data->zone_low[ix] = dme1737_read(data, |
655 | DME1737_REG_ZONE_LOW(ix)); | 679 | DME1737_REG_ZONE_LOW(ix)); |
656 | data->zone_abs[ix] = dme1737_read(client, | 680 | data->zone_abs[ix] = dme1737_read(data, |
657 | DME1737_REG_ZONE_ABS(ix)); | 681 | DME1737_REG_ZONE_ABS(ix)); |
658 | } | 682 | } |
659 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | 683 | if (data->type != sch5027) { |
660 | data->zone_hyst[ix] = dme1737_read(client, | 684 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { |
685 | data->zone_hyst[ix] = dme1737_read(data, | ||
661 | DME1737_REG_ZONE_HYST(ix)); | 686 | DME1737_REG_ZONE_HYST(ix)); |
687 | } | ||
662 | } | 688 | } |
663 | 689 | ||
664 | /* Alarm registers */ | 690 | /* Alarm registers */ |
665 | data->alarms = dme1737_read(client, | 691 | data->alarms = dme1737_read(data, |
666 | DME1737_REG_ALARM1); | 692 | DME1737_REG_ALARM1); |
667 | /* Bit 7 tells us if the other alarm registers are non-zero and | 693 | /* Bit 7 tells us if the other alarm registers are non-zero and |
668 | * therefore also need to be read */ | 694 | * therefore also need to be read */ |
669 | if (data->alarms & 0x80) { | 695 | if (data->alarms & 0x80) { |
670 | data->alarms |= dme1737_read(client, | 696 | data->alarms |= dme1737_read(data, |
671 | DME1737_REG_ALARM2) << 8; | 697 | DME1737_REG_ALARM2) << 8; |
672 | data->alarms |= dme1737_read(client, | 698 | data->alarms |= dme1737_read(data, |
673 | DME1737_REG_ALARM3) << 16; | 699 | DME1737_REG_ALARM3) << 16; |
674 | } | 700 | } |
675 | 701 | ||
676 | /* The ISA chips require explicit clearing of alarm bits. | 702 | /* The ISA chips require explicit clearing of alarm bits. |
677 | * Don't worry, an alarm will come back if the condition | 703 | * Don't worry, an alarm will come back if the condition |
678 | * that causes it still exists */ | 704 | * that causes it still exists */ |
679 | if (!client->driver) { | 705 | if (!data->client) { |
680 | if (data->alarms & 0xff0000) { | 706 | if (data->alarms & 0xff0000) { |
681 | dme1737_write(client, DME1737_REG_ALARM3, | 707 | dme1737_write(data, DME1737_REG_ALARM3, |
682 | 0xff); | 708 | 0xff); |
683 | } | 709 | } |
684 | if (data->alarms & 0xff00) { | 710 | if (data->alarms & 0xff00) { |
685 | dme1737_write(client, DME1737_REG_ALARM2, | 711 | dme1737_write(data, DME1737_REG_ALARM2, |
686 | 0xff); | 712 | 0xff); |
687 | } | 713 | } |
688 | if (data->alarms & 0xff) { | 714 | if (data->alarms & 0xff) { |
689 | dme1737_write(client, DME1737_REG_ALARM1, | 715 | dme1737_write(data, DME1737_REG_ALARM1, |
690 | 0xff); | 716 | 0xff); |
691 | } | 717 | } |
692 | } | 718 | } |
@@ -722,13 +748,13 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, | |||
722 | 748 | ||
723 | switch (fn) { | 749 | switch (fn) { |
724 | case SYS_IN_INPUT: | 750 | case SYS_IN_INPUT: |
725 | res = IN_FROM_REG(data->in[ix], ix, 16); | 751 | res = IN_FROM_REG(data->in[ix], data->in_nominal[ix], 16); |
726 | break; | 752 | break; |
727 | case SYS_IN_MIN: | 753 | case SYS_IN_MIN: |
728 | res = IN_FROM_REG(data->in_min[ix], ix, 8); | 754 | res = IN_FROM_REG(data->in_min[ix], data->in_nominal[ix], 8); |
729 | break; | 755 | break; |
730 | case SYS_IN_MAX: | 756 | case SYS_IN_MAX: |
731 | res = IN_FROM_REG(data->in_max[ix], ix, 8); | 757 | res = IN_FROM_REG(data->in_max[ix], data->in_nominal[ix], 8); |
732 | break; | 758 | break; |
733 | case SYS_IN_ALARM: | 759 | case SYS_IN_ALARM: |
734 | res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; | 760 | res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; |
@@ -745,7 +771,6 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, | |||
745 | const char *buf, size_t count) | 771 | const char *buf, size_t count) |
746 | { | 772 | { |
747 | struct dme1737_data *data = dev_get_drvdata(dev); | 773 | struct dme1737_data *data = dev_get_drvdata(dev); |
748 | struct i2c_client *client = &data->client; | ||
749 | struct sensor_device_attribute_2 | 774 | struct sensor_device_attribute_2 |
750 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 775 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
751 | int ix = sensor_attr_2->index; | 776 | int ix = sensor_attr_2->index; |
@@ -755,13 +780,13 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, | |||
755 | mutex_lock(&data->update_lock); | 780 | mutex_lock(&data->update_lock); |
756 | switch (fn) { | 781 | switch (fn) { |
757 | case SYS_IN_MIN: | 782 | case SYS_IN_MIN: |
758 | data->in_min[ix] = IN_TO_REG(val, ix); | 783 | data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]); |
759 | dme1737_write(client, DME1737_REG_IN_MIN(ix), | 784 | dme1737_write(data, DME1737_REG_IN_MIN(ix), |
760 | data->in_min[ix]); | 785 | data->in_min[ix]); |
761 | break; | 786 | break; |
762 | case SYS_IN_MAX: | 787 | case SYS_IN_MAX: |
763 | data->in_max[ix] = IN_TO_REG(val, ix); | 788 | data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]); |
764 | dme1737_write(client, DME1737_REG_IN_MAX(ix), | 789 | dme1737_write(data, DME1737_REG_IN_MAX(ix), |
765 | data->in_max[ix]); | 790 | data->in_max[ix]); |
766 | break; | 791 | break; |
767 | default: | 792 | default: |
@@ -825,7 +850,6 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
825 | const char *buf, size_t count) | 850 | const char *buf, size_t count) |
826 | { | 851 | { |
827 | struct dme1737_data *data = dev_get_drvdata(dev); | 852 | struct dme1737_data *data = dev_get_drvdata(dev); |
828 | struct i2c_client *client = &data->client; | ||
829 | struct sensor_device_attribute_2 | 853 | struct sensor_device_attribute_2 |
830 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 854 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
831 | int ix = sensor_attr_2->index; | 855 | int ix = sensor_attr_2->index; |
@@ -836,17 +860,17 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
836 | switch (fn) { | 860 | switch (fn) { |
837 | case SYS_TEMP_MIN: | 861 | case SYS_TEMP_MIN: |
838 | data->temp_min[ix] = TEMP_TO_REG(val); | 862 | data->temp_min[ix] = TEMP_TO_REG(val); |
839 | dme1737_write(client, DME1737_REG_TEMP_MIN(ix), | 863 | dme1737_write(data, DME1737_REG_TEMP_MIN(ix), |
840 | data->temp_min[ix]); | 864 | data->temp_min[ix]); |
841 | break; | 865 | break; |
842 | case SYS_TEMP_MAX: | 866 | case SYS_TEMP_MAX: |
843 | data->temp_max[ix] = TEMP_TO_REG(val); | 867 | data->temp_max[ix] = TEMP_TO_REG(val); |
844 | dme1737_write(client, DME1737_REG_TEMP_MAX(ix), | 868 | dme1737_write(data, DME1737_REG_TEMP_MAX(ix), |
845 | data->temp_max[ix]); | 869 | data->temp_max[ix]); |
846 | break; | 870 | break; |
847 | case SYS_TEMP_OFFSET: | 871 | case SYS_TEMP_OFFSET: |
848 | data->temp_offset[ix] = TEMP_TO_REG(val); | 872 | data->temp_offset[ix] = TEMP_TO_REG(val); |
849 | dme1737_write(client, DME1737_REG_TEMP_OFFSET(ix), | 873 | dme1737_write(data, DME1737_REG_TEMP_OFFSET(ix), |
850 | data->temp_offset[ix]); | 874 | data->temp_offset[ix]); |
851 | break; | 875 | break; |
852 | default: | 876 | default: |
@@ -914,7 +938,6 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, | |||
914 | const char *buf, size_t count) | 938 | const char *buf, size_t count) |
915 | { | 939 | { |
916 | struct dme1737_data *data = dev_get_drvdata(dev); | 940 | struct dme1737_data *data = dev_get_drvdata(dev); |
917 | struct i2c_client *client = &data->client; | ||
918 | struct sensor_device_attribute_2 | 941 | struct sensor_device_attribute_2 |
919 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 942 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
920 | int ix = sensor_attr_2->index; | 943 | int ix = sensor_attr_2->index; |
@@ -925,37 +948,37 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, | |||
925 | switch (fn) { | 948 | switch (fn) { |
926 | case SYS_ZONE_AUTO_POINT1_TEMP_HYST: | 949 | case SYS_ZONE_AUTO_POINT1_TEMP_HYST: |
927 | /* Refresh the cache */ | 950 | /* Refresh the cache */ |
928 | data->zone_low[ix] = dme1737_read(client, | 951 | data->zone_low[ix] = dme1737_read(data, |
929 | DME1737_REG_ZONE_LOW(ix)); | 952 | DME1737_REG_ZONE_LOW(ix)); |
930 | /* Modify the temp hyst value */ | 953 | /* Modify the temp hyst value */ |
931 | data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG( | 954 | data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG( |
932 | TEMP_FROM_REG(data->zone_low[ix], 8) - | 955 | TEMP_FROM_REG(data->zone_low[ix], 8) - |
933 | val, ix, dme1737_read(client, | 956 | val, ix, dme1737_read(data, |
934 | DME1737_REG_ZONE_HYST(ix == 2))); | 957 | DME1737_REG_ZONE_HYST(ix == 2))); |
935 | dme1737_write(client, DME1737_REG_ZONE_HYST(ix == 2), | 958 | dme1737_write(data, DME1737_REG_ZONE_HYST(ix == 2), |
936 | data->zone_hyst[ix == 2]); | 959 | data->zone_hyst[ix == 2]); |
937 | break; | 960 | break; |
938 | case SYS_ZONE_AUTO_POINT1_TEMP: | 961 | case SYS_ZONE_AUTO_POINT1_TEMP: |
939 | data->zone_low[ix] = TEMP_TO_REG(val); | 962 | data->zone_low[ix] = TEMP_TO_REG(val); |
940 | dme1737_write(client, DME1737_REG_ZONE_LOW(ix), | 963 | dme1737_write(data, DME1737_REG_ZONE_LOW(ix), |
941 | data->zone_low[ix]); | 964 | data->zone_low[ix]); |
942 | break; | 965 | break; |
943 | case SYS_ZONE_AUTO_POINT2_TEMP: | 966 | case SYS_ZONE_AUTO_POINT2_TEMP: |
944 | /* Refresh the cache */ | 967 | /* Refresh the cache */ |
945 | data->zone_low[ix] = dme1737_read(client, | 968 | data->zone_low[ix] = dme1737_read(data, |
946 | DME1737_REG_ZONE_LOW(ix)); | 969 | DME1737_REG_ZONE_LOW(ix)); |
947 | /* Modify the temp range value (which is stored in the upper | 970 | /* Modify the temp range value (which is stored in the upper |
948 | * nibble of the pwm_freq register) */ | 971 | * nibble of the pwm_freq register) */ |
949 | data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - | 972 | data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - |
950 | TEMP_FROM_REG(data->zone_low[ix], 8), | 973 | TEMP_FROM_REG(data->zone_low[ix], 8), |
951 | dme1737_read(client, | 974 | dme1737_read(data, |
952 | DME1737_REG_PWM_FREQ(ix))); | 975 | DME1737_REG_PWM_FREQ(ix))); |
953 | dme1737_write(client, DME1737_REG_PWM_FREQ(ix), | 976 | dme1737_write(data, DME1737_REG_PWM_FREQ(ix), |
954 | data->pwm_freq[ix]); | 977 | data->pwm_freq[ix]); |
955 | break; | 978 | break; |
956 | case SYS_ZONE_AUTO_POINT3_TEMP: | 979 | case SYS_ZONE_AUTO_POINT3_TEMP: |
957 | data->zone_abs[ix] = TEMP_TO_REG(val); | 980 | data->zone_abs[ix] = TEMP_TO_REG(val); |
958 | dme1737_write(client, DME1737_REG_ZONE_ABS(ix), | 981 | dme1737_write(data, DME1737_REG_ZONE_ABS(ix), |
959 | data->zone_abs[ix]); | 982 | data->zone_abs[ix]); |
960 | break; | 983 | break; |
961 | default: | 984 | default: |
@@ -1021,7 +1044,6 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
1021 | const char *buf, size_t count) | 1044 | const char *buf, size_t count) |
1022 | { | 1045 | { |
1023 | struct dme1737_data *data = dev_get_drvdata(dev); | 1046 | struct dme1737_data *data = dev_get_drvdata(dev); |
1024 | struct i2c_client *client = &data->client; | ||
1025 | struct sensor_device_attribute_2 | 1047 | struct sensor_device_attribute_2 |
1026 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 1048 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
1027 | int ix = sensor_attr_2->index; | 1049 | int ix = sensor_attr_2->index; |
@@ -1035,21 +1057,21 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
1035 | data->fan_min[ix] = FAN_TO_REG(val, 0); | 1057 | data->fan_min[ix] = FAN_TO_REG(val, 0); |
1036 | } else { | 1058 | } else { |
1037 | /* Refresh the cache */ | 1059 | /* Refresh the cache */ |
1038 | data->fan_opt[ix] = dme1737_read(client, | 1060 | data->fan_opt[ix] = dme1737_read(data, |
1039 | DME1737_REG_FAN_OPT(ix)); | 1061 | DME1737_REG_FAN_OPT(ix)); |
1040 | /* Modify the fan min value */ | 1062 | /* Modify the fan min value */ |
1041 | data->fan_min[ix] = FAN_TO_REG(val, | 1063 | data->fan_min[ix] = FAN_TO_REG(val, |
1042 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | 1064 | FAN_TPC_FROM_REG(data->fan_opt[ix])); |
1043 | } | 1065 | } |
1044 | dme1737_write(client, DME1737_REG_FAN_MIN(ix), | 1066 | dme1737_write(data, DME1737_REG_FAN_MIN(ix), |
1045 | data->fan_min[ix] & 0xff); | 1067 | data->fan_min[ix] & 0xff); |
1046 | dme1737_write(client, DME1737_REG_FAN_MIN(ix) + 1, | 1068 | dme1737_write(data, DME1737_REG_FAN_MIN(ix) + 1, |
1047 | data->fan_min[ix] >> 8); | 1069 | data->fan_min[ix] >> 8); |
1048 | break; | 1070 | break; |
1049 | case SYS_FAN_MAX: | 1071 | case SYS_FAN_MAX: |
1050 | /* Only valid for fan[5-6] */ | 1072 | /* Only valid for fan[5-6] */ |
1051 | data->fan_max[ix - 4] = FAN_MAX_TO_REG(val); | 1073 | data->fan_max[ix - 4] = FAN_MAX_TO_REG(val); |
1052 | dme1737_write(client, DME1737_REG_FAN_MAX(ix), | 1074 | dme1737_write(data, DME1737_REG_FAN_MAX(ix), |
1053 | data->fan_max[ix - 4]); | 1075 | data->fan_max[ix - 4]); |
1054 | break; | 1076 | break; |
1055 | case SYS_FAN_TYPE: | 1077 | case SYS_FAN_TYPE: |
@@ -1061,9 +1083,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | |||
1061 | val); | 1083 | val); |
1062 | goto exit; | 1084 | goto exit; |
1063 | } | 1085 | } |
1064 | data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(client, | 1086 | data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(data, |
1065 | DME1737_REG_FAN_OPT(ix))); | 1087 | DME1737_REG_FAN_OPT(ix))); |
1066 | dme1737_write(client, DME1737_REG_FAN_OPT(ix), | 1088 | dme1737_write(data, DME1737_REG_FAN_OPT(ix), |
1067 | data->fan_opt[ix]); | 1089 | data->fan_opt[ix]); |
1068 | break; | 1090 | break; |
1069 | default: | 1091 | default: |
@@ -1153,14 +1175,13 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | |||
1153 | return sprintf(buf, "%d\n", res); | 1175 | return sprintf(buf, "%d\n", res); |
1154 | } | 1176 | } |
1155 | 1177 | ||
1156 | static struct attribute *dme1737_attr_pwm[]; | 1178 | static struct attribute *dme1737_pwm_chmod_attr[]; |
1157 | static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); | 1179 | static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); |
1158 | 1180 | ||
1159 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | 1181 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
1160 | const char *buf, size_t count) | 1182 | const char *buf, size_t count) |
1161 | { | 1183 | { |
1162 | struct dme1737_data *data = dev_get_drvdata(dev); | 1184 | struct dme1737_data *data = dev_get_drvdata(dev); |
1163 | struct i2c_client *client = &data->client; | ||
1164 | struct sensor_device_attribute_2 | 1185 | struct sensor_device_attribute_2 |
1165 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | 1186 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); |
1166 | int ix = sensor_attr_2->index; | 1187 | int ix = sensor_attr_2->index; |
@@ -1171,12 +1192,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1171 | switch (fn) { | 1192 | switch (fn) { |
1172 | case SYS_PWM: | 1193 | case SYS_PWM: |
1173 | data->pwm[ix] = SENSORS_LIMIT(val, 0, 255); | 1194 | data->pwm[ix] = SENSORS_LIMIT(val, 0, 255); |
1174 | dme1737_write(client, DME1737_REG_PWM(ix), data->pwm[ix]); | 1195 | dme1737_write(data, DME1737_REG_PWM(ix), data->pwm[ix]); |
1175 | break; | 1196 | break; |
1176 | case SYS_PWM_FREQ: | 1197 | case SYS_PWM_FREQ: |
1177 | data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(client, | 1198 | data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(data, |
1178 | DME1737_REG_PWM_FREQ(ix))); | 1199 | DME1737_REG_PWM_FREQ(ix))); |
1179 | dme1737_write(client, DME1737_REG_PWM_FREQ(ix), | 1200 | dme1737_write(data, DME1737_REG_PWM_FREQ(ix), |
1180 | data->pwm_freq[ix]); | 1201 | data->pwm_freq[ix]); |
1181 | break; | 1202 | break; |
1182 | case SYS_PWM_ENABLE: | 1203 | case SYS_PWM_ENABLE: |
@@ -1189,7 +1210,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1189 | goto exit; | 1210 | goto exit; |
1190 | } | 1211 | } |
1191 | /* Refresh the cache */ | 1212 | /* Refresh the cache */ |
1192 | data->pwm_config[ix] = dme1737_read(client, | 1213 | data->pwm_config[ix] = dme1737_read(data, |
1193 | DME1737_REG_PWM_CONFIG(ix)); | 1214 | DME1737_REG_PWM_CONFIG(ix)); |
1194 | if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) { | 1215 | if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) { |
1195 | /* Bail out if no change */ | 1216 | /* Bail out if no change */ |
@@ -1201,14 +1222,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1201 | data->pwm_acz[ix] = PWM_ACZ_FROM_REG( | 1222 | data->pwm_acz[ix] = PWM_ACZ_FROM_REG( |
1202 | data->pwm_config[ix]); | 1223 | data->pwm_config[ix]); |
1203 | /* Save the current ramp rate state and disable it */ | 1224 | /* Save the current ramp rate state and disable it */ |
1204 | data->pwm_rr[ix > 0] = dme1737_read(client, | 1225 | data->pwm_rr[ix > 0] = dme1737_read(data, |
1205 | DME1737_REG_PWM_RR(ix > 0)); | 1226 | DME1737_REG_PWM_RR(ix > 0)); |
1206 | data->pwm_rr_en &= ~(1 << ix); | 1227 | data->pwm_rr_en &= ~(1 << ix); |
1207 | if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) { | 1228 | if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) { |
1208 | data->pwm_rr_en |= (1 << ix); | 1229 | data->pwm_rr_en |= (1 << ix); |
1209 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix, | 1230 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix, |
1210 | data->pwm_rr[ix > 0]); | 1231 | data->pwm_rr[ix > 0]); |
1211 | dme1737_write(client, | 1232 | dme1737_write(data, |
1212 | DME1737_REG_PWM_RR(ix > 0), | 1233 | DME1737_REG_PWM_RR(ix > 0), |
1213 | data->pwm_rr[ix > 0]); | 1234 | data->pwm_rr[ix > 0]); |
1214 | } | 1235 | } |
@@ -1217,41 +1238,41 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1217 | switch (val) { | 1238 | switch (val) { |
1218 | case 0: | 1239 | case 0: |
1219 | /* Change permissions of pwm[ix] to read-only */ | 1240 | /* Change permissions of pwm[ix] to read-only */ |
1220 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], | 1241 | dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], |
1221 | S_IRUGO); | 1242 | S_IRUGO); |
1222 | /* Turn fan fully on */ | 1243 | /* Turn fan fully on */ |
1223 | data->pwm_config[ix] = PWM_EN_TO_REG(0, | 1244 | data->pwm_config[ix] = PWM_EN_TO_REG(0, |
1224 | data->pwm_config[ix]); | 1245 | data->pwm_config[ix]); |
1225 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | 1246 | dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), |
1226 | data->pwm_config[ix]); | 1247 | data->pwm_config[ix]); |
1227 | break; | 1248 | break; |
1228 | case 1: | 1249 | case 1: |
1229 | /* Turn on manual mode */ | 1250 | /* Turn on manual mode */ |
1230 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | 1251 | data->pwm_config[ix] = PWM_EN_TO_REG(1, |
1231 | data->pwm_config[ix]); | 1252 | data->pwm_config[ix]); |
1232 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | 1253 | dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), |
1233 | data->pwm_config[ix]); | 1254 | data->pwm_config[ix]); |
1234 | /* Change permissions of pwm[ix] to read-writeable */ | 1255 | /* Change permissions of pwm[ix] to read-writeable */ |
1235 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], | 1256 | dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], |
1236 | S_IRUGO | S_IWUSR); | 1257 | S_IRUGO | S_IWUSR); |
1237 | break; | 1258 | break; |
1238 | case 2: | 1259 | case 2: |
1239 | /* Change permissions of pwm[ix] to read-only */ | 1260 | /* Change permissions of pwm[ix] to read-only */ |
1240 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], | 1261 | dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], |
1241 | S_IRUGO); | 1262 | S_IRUGO); |
1242 | /* Turn on auto mode using the saved zone channel | 1263 | /* Turn on auto mode using the saved zone channel |
1243 | * assignment */ | 1264 | * assignment */ |
1244 | data->pwm_config[ix] = PWM_ACZ_TO_REG( | 1265 | data->pwm_config[ix] = PWM_ACZ_TO_REG( |
1245 | data->pwm_acz[ix], | 1266 | data->pwm_acz[ix], |
1246 | data->pwm_config[ix]); | 1267 | data->pwm_config[ix]); |
1247 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | 1268 | dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), |
1248 | data->pwm_config[ix]); | 1269 | data->pwm_config[ix]); |
1249 | /* Enable PWM ramp rate if previously enabled */ | 1270 | /* Enable PWM ramp rate if previously enabled */ |
1250 | if (data->pwm_rr_en & (1 << ix)) { | 1271 | if (data->pwm_rr_en & (1 << ix)) { |
1251 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix, | 1272 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix, |
1252 | dme1737_read(client, | 1273 | dme1737_read(data, |
1253 | DME1737_REG_PWM_RR(ix > 0))); | 1274 | DME1737_REG_PWM_RR(ix > 0))); |
1254 | dme1737_write(client, | 1275 | dme1737_write(data, |
1255 | DME1737_REG_PWM_RR(ix > 0), | 1276 | DME1737_REG_PWM_RR(ix > 0), |
1256 | data->pwm_rr[ix > 0]); | 1277 | data->pwm_rr[ix > 0]); |
1257 | } | 1278 | } |
@@ -1261,9 +1282,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1261 | case SYS_PWM_RAMP_RATE: | 1282 | case SYS_PWM_RAMP_RATE: |
1262 | /* Only valid for pwm[1-3] */ | 1283 | /* Only valid for pwm[1-3] */ |
1263 | /* Refresh the cache */ | 1284 | /* Refresh the cache */ |
1264 | data->pwm_config[ix] = dme1737_read(client, | 1285 | data->pwm_config[ix] = dme1737_read(data, |
1265 | DME1737_REG_PWM_CONFIG(ix)); | 1286 | DME1737_REG_PWM_CONFIG(ix)); |
1266 | data->pwm_rr[ix > 0] = dme1737_read(client, | 1287 | data->pwm_rr[ix > 0] = dme1737_read(data, |
1267 | DME1737_REG_PWM_RR(ix > 0)); | 1288 | DME1737_REG_PWM_RR(ix > 0)); |
1268 | /* Set the ramp rate value */ | 1289 | /* Set the ramp rate value */ |
1269 | if (val > 0) { | 1290 | if (val > 0) { |
@@ -1276,7 +1297,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1276 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, | 1297 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, |
1277 | data->pwm_rr[ix > 0]); | 1298 | data->pwm_rr[ix > 0]); |
1278 | } | 1299 | } |
1279 | dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), | 1300 | dme1737_write(data, DME1737_REG_PWM_RR(ix > 0), |
1280 | data->pwm_rr[ix > 0]); | 1301 | data->pwm_rr[ix > 0]); |
1281 | break; | 1302 | break; |
1282 | case SYS_PWM_AUTO_CHANNELS_ZONE: | 1303 | case SYS_PWM_AUTO_CHANNELS_ZONE: |
@@ -1290,14 +1311,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1290 | goto exit; | 1311 | goto exit; |
1291 | } | 1312 | } |
1292 | /* Refresh the cache */ | 1313 | /* Refresh the cache */ |
1293 | data->pwm_config[ix] = dme1737_read(client, | 1314 | data->pwm_config[ix] = dme1737_read(data, |
1294 | DME1737_REG_PWM_CONFIG(ix)); | 1315 | DME1737_REG_PWM_CONFIG(ix)); |
1295 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | 1316 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { |
1296 | /* PWM is already in auto mode so update the temp | 1317 | /* PWM is already in auto mode so update the temp |
1297 | * channel assignment */ | 1318 | * channel assignment */ |
1298 | data->pwm_config[ix] = PWM_ACZ_TO_REG(val, | 1319 | data->pwm_config[ix] = PWM_ACZ_TO_REG(val, |
1299 | data->pwm_config[ix]); | 1320 | data->pwm_config[ix]); |
1300 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | 1321 | dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), |
1301 | data->pwm_config[ix]); | 1322 | data->pwm_config[ix]); |
1302 | } else { | 1323 | } else { |
1303 | /* PWM is not in auto mode so we save the temp | 1324 | /* PWM is not in auto mode so we save the temp |
@@ -1308,7 +1329,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1308 | case SYS_PWM_AUTO_PWM_MIN: | 1329 | case SYS_PWM_AUTO_PWM_MIN: |
1309 | /* Only valid for pwm[1-3] */ | 1330 | /* Only valid for pwm[1-3] */ |
1310 | /* Refresh the cache */ | 1331 | /* Refresh the cache */ |
1311 | data->pwm_min[ix] = dme1737_read(client, | 1332 | data->pwm_min[ix] = dme1737_read(data, |
1312 | DME1737_REG_PWM_MIN(ix)); | 1333 | DME1737_REG_PWM_MIN(ix)); |
1313 | /* There are only 2 values supported for the auto_pwm_min | 1334 | /* There are only 2 values supported for the auto_pwm_min |
1314 | * value: 0 or auto_point1_pwm. So if the temperature drops | 1335 | * value: 0 or auto_point1_pwm. So if the temperature drops |
@@ -1316,20 +1337,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
1316 | * off or runs at auto_point1_pwm duty-cycle. */ | 1337 | * off or runs at auto_point1_pwm duty-cycle. */ |
1317 | if (val > ((data->pwm_min[ix] + 1) / 2)) { | 1338 | if (val > ((data->pwm_min[ix] + 1) / 2)) { |
1318 | data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, | 1339 | data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, |
1319 | dme1737_read(client, | 1340 | dme1737_read(data, |
1320 | DME1737_REG_PWM_RR(0))); | 1341 | DME1737_REG_PWM_RR(0))); |
1321 | } else { | 1342 | } else { |
1322 | data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, | 1343 | data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, |
1323 | dme1737_read(client, | 1344 | dme1737_read(data, |
1324 | DME1737_REG_PWM_RR(0))); | 1345 | DME1737_REG_PWM_RR(0))); |
1325 | } | 1346 | } |
1326 | dme1737_write(client, DME1737_REG_PWM_RR(0), | 1347 | dme1737_write(data, DME1737_REG_PWM_RR(0), |
1327 | data->pwm_rr[0]); | 1348 | data->pwm_rr[0]); |
1328 | break; | 1349 | break; |
1329 | case SYS_PWM_AUTO_POINT1_PWM: | 1350 | case SYS_PWM_AUTO_POINT1_PWM: |
1330 | /* Only valid for pwm[1-3] */ | 1351 | /* Only valid for pwm[1-3] */ |
1331 | data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255); | 1352 | data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255); |
1332 | dme1737_write(client, DME1737_REG_PWM_MIN(ix), | 1353 | dme1737_write(data, DME1737_REG_PWM_MIN(ix), |
1333 | data->pwm_min[ix]); | 1354 | data->pwm_min[ix]); |
1334 | break; | 1355 | break; |
1335 | default: | 1356 | default: |
@@ -1377,7 +1398,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, | |||
1377 | { | 1398 | { |
1378 | struct dme1737_data *data = dev_get_drvdata(dev); | 1399 | struct dme1737_data *data = dev_get_drvdata(dev); |
1379 | 1400 | ||
1380 | return sprintf(buf, "%s\n", data->client.name); | 1401 | return sprintf(buf, "%s\n", data->name); |
1381 | } | 1402 | } |
1382 | 1403 | ||
1383 | /* --------------------------------------------------------------------- | 1404 | /* --------------------------------------------------------------------- |
@@ -1501,9 +1522,9 @@ SENSOR_DEVICE_ATTR_PWM_1TO3(3); | |||
1501 | /* PWMs 5-6 */ | 1522 | /* PWMs 5-6 */ |
1502 | 1523 | ||
1503 | #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ | 1524 | #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ |
1504 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO | S_IWUSR, \ | 1525 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \ |
1505 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | 1526 | show_pwm, set_pwm, SYS_PWM, ix-1); \ |
1506 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \ | 1527 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \ |
1507 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | 1528 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ |
1508 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | 1529 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ |
1509 | show_pwm, NULL, SYS_PWM_ENABLE, ix-1) | 1530 | show_pwm, NULL, SYS_PWM_ENABLE, ix-1) |
@@ -1517,225 +1538,286 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); | |||
1517 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | 1538 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); |
1518 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */ | 1539 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */ |
1519 | 1540 | ||
1520 | #define SENSOR_DEV_ATTR_IN(ix) \ | ||
1521 | &sensor_dev_attr_in##ix##_input.dev_attr.attr, \ | ||
1522 | &sensor_dev_attr_in##ix##_min.dev_attr.attr, \ | ||
1523 | &sensor_dev_attr_in##ix##_max.dev_attr.attr, \ | ||
1524 | &sensor_dev_attr_in##ix##_alarm.dev_attr.attr | ||
1525 | |||
1526 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1527 | #define SENSOR_DEV_ATTR_TEMP_LOCK(ix) \ | ||
1528 | &sensor_dev_attr_temp##ix##_offset.dev_attr.attr | ||
1529 | |||
1530 | #define SENSOR_DEV_ATTR_TEMP(ix) \ | ||
1531 | SENSOR_DEV_ATTR_TEMP_LOCK(ix), \ | ||
1532 | &sensor_dev_attr_temp##ix##_input.dev_attr.attr, \ | ||
1533 | &sensor_dev_attr_temp##ix##_min.dev_attr.attr, \ | ||
1534 | &sensor_dev_attr_temp##ix##_max.dev_attr.attr, \ | ||
1535 | &sensor_dev_attr_temp##ix##_alarm.dev_attr.attr, \ | ||
1536 | &sensor_dev_attr_temp##ix##_fault.dev_attr.attr | ||
1537 | |||
1538 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1539 | #define SENSOR_DEV_ATTR_ZONE_LOCK(ix) \ | ||
1540 | &sensor_dev_attr_zone##ix##_auto_point1_temp_hyst.dev_attr.attr, \ | ||
1541 | &sensor_dev_attr_zone##ix##_auto_point1_temp.dev_attr.attr, \ | ||
1542 | &sensor_dev_attr_zone##ix##_auto_point2_temp.dev_attr.attr, \ | ||
1543 | &sensor_dev_attr_zone##ix##_auto_point3_temp.dev_attr.attr | ||
1544 | |||
1545 | #define SENSOR_DEV_ATTR_ZONE(ix) \ | ||
1546 | SENSOR_DEV_ATTR_ZONE_LOCK(ix), \ | ||
1547 | &sensor_dev_attr_zone##ix##_auto_channels_temp.dev_attr.attr | ||
1548 | |||
1549 | #define SENSOR_DEV_ATTR_FAN_1TO4(ix) \ | ||
1550 | &sensor_dev_attr_fan##ix##_input.dev_attr.attr, \ | ||
1551 | &sensor_dev_attr_fan##ix##_min.dev_attr.attr, \ | ||
1552 | &sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \ | ||
1553 | &sensor_dev_attr_fan##ix##_type.dev_attr.attr | ||
1554 | |||
1555 | #define SENSOR_DEV_ATTR_FAN_5TO6(ix) \ | ||
1556 | &sensor_dev_attr_fan##ix##_input.dev_attr.attr, \ | ||
1557 | &sensor_dev_attr_fan##ix##_min.dev_attr.attr, \ | ||
1558 | &sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \ | ||
1559 | &sensor_dev_attr_fan##ix##_max.dev_attr.attr | ||
1560 | |||
1561 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1562 | #define SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix) \ | ||
1563 | &sensor_dev_attr_pwm##ix##_freq.dev_attr.attr, \ | ||
1564 | &sensor_dev_attr_pwm##ix##_enable.dev_attr.attr, \ | ||
1565 | &sensor_dev_attr_pwm##ix##_ramp_rate.dev_attr.attr, \ | ||
1566 | &sensor_dev_attr_pwm##ix##_auto_channels_zone.dev_attr.attr, \ | ||
1567 | &sensor_dev_attr_pwm##ix##_auto_pwm_min.dev_attr.attr, \ | ||
1568 | &sensor_dev_attr_pwm##ix##_auto_point1_pwm.dev_attr.attr | ||
1569 | |||
1570 | #define SENSOR_DEV_ATTR_PWM_1TO3(ix) \ | ||
1571 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix), \ | ||
1572 | &sensor_dev_attr_pwm##ix.dev_attr.attr, \ | ||
1573 | &sensor_dev_attr_pwm##ix##_auto_point2_pwm.dev_attr.attr | ||
1574 | |||
1575 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
1576 | #define SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix) \ | ||
1577 | &sensor_dev_attr_pwm##ix.dev_attr.attr, \ | ||
1578 | &sensor_dev_attr_pwm##ix##_freq.dev_attr.attr | ||
1579 | |||
1580 | #define SENSOR_DEV_ATTR_PWM_5TO6(ix) \ | ||
1581 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix), \ | ||
1582 | &sensor_dev_attr_pwm##ix##_enable.dev_attr.attr | ||
1583 | |||
1584 | /* This struct holds all the attributes that are always present and need to be | 1541 | /* This struct holds all the attributes that are always present and need to be |
1585 | * created unconditionally. The attributes that need modification of their | 1542 | * created unconditionally. The attributes that need modification of their |
1586 | * permissions are created read-only and write permissions are added or removed | 1543 | * permissions are created read-only and write permissions are added or removed |
1587 | * on the fly when required */ | 1544 | * on the fly when required */ |
1588 | static struct attribute *dme1737_attr[] ={ | 1545 | static struct attribute *dme1737_attr[] ={ |
1589 | /* Voltages */ | 1546 | /* Voltages */ |
1590 | SENSOR_DEV_ATTR_IN(0), | 1547 | &sensor_dev_attr_in0_input.dev_attr.attr, |
1591 | SENSOR_DEV_ATTR_IN(1), | 1548 | &sensor_dev_attr_in0_min.dev_attr.attr, |
1592 | SENSOR_DEV_ATTR_IN(2), | 1549 | &sensor_dev_attr_in0_max.dev_attr.attr, |
1593 | SENSOR_DEV_ATTR_IN(3), | 1550 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
1594 | SENSOR_DEV_ATTR_IN(4), | 1551 | &sensor_dev_attr_in1_input.dev_attr.attr, |
1595 | SENSOR_DEV_ATTR_IN(5), | 1552 | &sensor_dev_attr_in1_min.dev_attr.attr, |
1596 | SENSOR_DEV_ATTR_IN(6), | 1553 | &sensor_dev_attr_in1_max.dev_attr.attr, |
1554 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
1555 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
1556 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
1557 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
1558 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
1559 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
1560 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
1561 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
1562 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1563 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
1564 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
1565 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
1566 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1567 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
1568 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
1569 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
1570 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1571 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
1572 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
1573 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
1574 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1597 | /* Temperatures */ | 1575 | /* Temperatures */ |
1598 | SENSOR_DEV_ATTR_TEMP(1), | 1576 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
1599 | SENSOR_DEV_ATTR_TEMP(2), | 1577 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
1600 | SENSOR_DEV_ATTR_TEMP(3), | 1578 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
1579 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
1580 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | ||
1581 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1582 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
1583 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
1584 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
1585 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
1586 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1587 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
1588 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
1589 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1590 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
1601 | /* Zones */ | 1591 | /* Zones */ |
1602 | SENSOR_DEV_ATTR_ZONE(1), | 1592 | &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, |
1603 | SENSOR_DEV_ATTR_ZONE(2), | 1593 | &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, |
1604 | SENSOR_DEV_ATTR_ZONE(3), | 1594 | &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, |
1595 | &sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr, | ||
1596 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, | ||
1597 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | ||
1598 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | ||
1599 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, | ||
1600 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
1601 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
1602 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
1603 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
1604 | NULL | ||
1605 | }; | ||
1606 | |||
1607 | static const struct attribute_group dme1737_group = { | ||
1608 | .attrs = dme1737_attr, | ||
1609 | }; | ||
1610 | |||
1611 | /* The following struct holds misc attributes, which are not available in all | ||
1612 | * chips. Their creation depends on the chip type which is determined during | ||
1613 | * module load. */ | ||
1614 | static struct attribute *dme1737_misc_attr[] = { | ||
1615 | /* Temperatures */ | ||
1616 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
1617 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
1618 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
1619 | /* Zones */ | ||
1620 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
1621 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
1622 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
1605 | /* Misc */ | 1623 | /* Misc */ |
1606 | &dev_attr_vrm.attr, | 1624 | &dev_attr_vrm.attr, |
1607 | &dev_attr_cpu0_vid.attr, | 1625 | &dev_attr_cpu0_vid.attr, |
1608 | NULL | 1626 | NULL |
1609 | }; | 1627 | }; |
1610 | 1628 | ||
1611 | static const struct attribute_group dme1737_group = { | 1629 | static const struct attribute_group dme1737_misc_group = { |
1612 | .attrs = dme1737_attr, | 1630 | .attrs = dme1737_misc_attr, |
1613 | }; | 1631 | }; |
1614 | 1632 | ||
1615 | /* The following structs hold the PWM attributes, some of which are optional. | 1633 | /* The following structs hold the PWM attributes, some of which are optional. |
1616 | * Their creation depends on the chip configuration which is determined during | 1634 | * Their creation depends on the chip configuration which is determined during |
1617 | * module load. */ | 1635 | * module load. */ |
1618 | static struct attribute *dme1737_attr_pwm1[] = { | 1636 | static struct attribute *dme1737_pwm1_attr[] = { |
1619 | SENSOR_DEV_ATTR_PWM_1TO3(1), | 1637 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1638 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | ||
1639 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
1640 | &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, | ||
1641 | &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, | ||
1642 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
1643 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
1620 | NULL | 1644 | NULL |
1621 | }; | 1645 | }; |
1622 | static struct attribute *dme1737_attr_pwm2[] = { | 1646 | static struct attribute *dme1737_pwm2_attr[] = { |
1623 | SENSOR_DEV_ATTR_PWM_1TO3(2), | 1647 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1648 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | ||
1649 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
1650 | &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, | ||
1651 | &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, | ||
1652 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | ||
1653 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | ||
1624 | NULL | 1654 | NULL |
1625 | }; | 1655 | }; |
1626 | static struct attribute *dme1737_attr_pwm3[] = { | 1656 | static struct attribute *dme1737_pwm3_attr[] = { |
1627 | SENSOR_DEV_ATTR_PWM_1TO3(3), | 1657 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1658 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | ||
1659 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
1660 | &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, | ||
1661 | &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, | ||
1662 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | ||
1663 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | ||
1628 | NULL | 1664 | NULL |
1629 | }; | 1665 | }; |
1630 | static struct attribute *dme1737_attr_pwm5[] = { | 1666 | static struct attribute *dme1737_pwm5_attr[] = { |
1631 | SENSOR_DEV_ATTR_PWM_5TO6(5), | 1667 | &sensor_dev_attr_pwm5.dev_attr.attr, |
1668 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, | ||
1669 | &sensor_dev_attr_pwm5_enable.dev_attr.attr, | ||
1632 | NULL | 1670 | NULL |
1633 | }; | 1671 | }; |
1634 | static struct attribute *dme1737_attr_pwm6[] = { | 1672 | static struct attribute *dme1737_pwm6_attr[] = { |
1635 | SENSOR_DEV_ATTR_PWM_5TO6(6), | 1673 | &sensor_dev_attr_pwm6.dev_attr.attr, |
1674 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, | ||
1675 | &sensor_dev_attr_pwm6_enable.dev_attr.attr, | ||
1636 | NULL | 1676 | NULL |
1637 | }; | 1677 | }; |
1638 | 1678 | ||
1639 | static const struct attribute_group dme1737_pwm_group[] = { | 1679 | static const struct attribute_group dme1737_pwm_group[] = { |
1640 | { .attrs = dme1737_attr_pwm1 }, | 1680 | { .attrs = dme1737_pwm1_attr }, |
1641 | { .attrs = dme1737_attr_pwm2 }, | 1681 | { .attrs = dme1737_pwm2_attr }, |
1642 | { .attrs = dme1737_attr_pwm3 }, | 1682 | { .attrs = dme1737_pwm3_attr }, |
1643 | { .attrs = NULL }, | 1683 | { .attrs = NULL }, |
1644 | { .attrs = dme1737_attr_pwm5 }, | 1684 | { .attrs = dme1737_pwm5_attr }, |
1645 | { .attrs = dme1737_attr_pwm6 }, | 1685 | { .attrs = dme1737_pwm6_attr }, |
1686 | }; | ||
1687 | |||
1688 | /* The following struct holds misc PWM attributes, which are not available in | ||
1689 | * all chips. Their creation depends on the chip type which is determined | ||
1690 | * during module load. */ | ||
1691 | static struct attribute *dme1737_pwm_misc_attr[] = { | ||
1692 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | ||
1693 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | ||
1694 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | ||
1646 | }; | 1695 | }; |
1647 | 1696 | ||
1648 | /* The following structs hold the fan attributes, some of which are optional. | 1697 | /* The following structs hold the fan attributes, some of which are optional. |
1649 | * Their creation depends on the chip configuration which is determined during | 1698 | * Their creation depends on the chip configuration which is determined during |
1650 | * module load. */ | 1699 | * module load. */ |
1651 | static struct attribute *dme1737_attr_fan1[] = { | 1700 | static struct attribute *dme1737_fan1_attr[] = { |
1652 | SENSOR_DEV_ATTR_FAN_1TO4(1), | 1701 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1702 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
1703 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
1704 | &sensor_dev_attr_fan1_type.dev_attr.attr, | ||
1653 | NULL | 1705 | NULL |
1654 | }; | 1706 | }; |
1655 | static struct attribute *dme1737_attr_fan2[] = { | 1707 | static struct attribute *dme1737_fan2_attr[] = { |
1656 | SENSOR_DEV_ATTR_FAN_1TO4(2), | 1708 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1709 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
1710 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
1711 | &sensor_dev_attr_fan2_type.dev_attr.attr, | ||
1657 | NULL | 1712 | NULL |
1658 | }; | 1713 | }; |
1659 | static struct attribute *dme1737_attr_fan3[] = { | 1714 | static struct attribute *dme1737_fan3_attr[] = { |
1660 | SENSOR_DEV_ATTR_FAN_1TO4(3), | 1715 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1716 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
1717 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
1718 | &sensor_dev_attr_fan3_type.dev_attr.attr, | ||
1661 | NULL | 1719 | NULL |
1662 | }; | 1720 | }; |
1663 | static struct attribute *dme1737_attr_fan4[] = { | 1721 | static struct attribute *dme1737_fan4_attr[] = { |
1664 | SENSOR_DEV_ATTR_FAN_1TO4(4), | 1722 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1723 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
1724 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | ||
1725 | &sensor_dev_attr_fan4_type.dev_attr.attr, | ||
1665 | NULL | 1726 | NULL |
1666 | }; | 1727 | }; |
1667 | static struct attribute *dme1737_attr_fan5[] = { | 1728 | static struct attribute *dme1737_fan5_attr[] = { |
1668 | SENSOR_DEV_ATTR_FAN_5TO6(5), | 1729 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
1730 | &sensor_dev_attr_fan5_min.dev_attr.attr, | ||
1731 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | ||
1732 | &sensor_dev_attr_fan5_max.dev_attr.attr, | ||
1669 | NULL | 1733 | NULL |
1670 | }; | 1734 | }; |
1671 | static struct attribute *dme1737_attr_fan6[] = { | 1735 | static struct attribute *dme1737_fan6_attr[] = { |
1672 | SENSOR_DEV_ATTR_FAN_5TO6(6), | 1736 | &sensor_dev_attr_fan6_input.dev_attr.attr, |
1737 | &sensor_dev_attr_fan6_min.dev_attr.attr, | ||
1738 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | ||
1739 | &sensor_dev_attr_fan6_max.dev_attr.attr, | ||
1673 | NULL | 1740 | NULL |
1674 | }; | 1741 | }; |
1675 | 1742 | ||
1676 | static const struct attribute_group dme1737_fan_group[] = { | 1743 | static const struct attribute_group dme1737_fan_group[] = { |
1677 | { .attrs = dme1737_attr_fan1 }, | 1744 | { .attrs = dme1737_fan1_attr }, |
1678 | { .attrs = dme1737_attr_fan2 }, | 1745 | { .attrs = dme1737_fan2_attr }, |
1679 | { .attrs = dme1737_attr_fan3 }, | 1746 | { .attrs = dme1737_fan3_attr }, |
1680 | { .attrs = dme1737_attr_fan4 }, | 1747 | { .attrs = dme1737_fan4_attr }, |
1681 | { .attrs = dme1737_attr_fan5 }, | 1748 | { .attrs = dme1737_fan5_attr }, |
1682 | { .attrs = dme1737_attr_fan6 }, | 1749 | { .attrs = dme1737_fan6_attr }, |
1683 | }; | 1750 | }; |
1684 | 1751 | ||
1685 | /* The permissions of all of the following attributes are changed to read- | 1752 | /* The permissions of the following zone attributes are changed to read- |
1686 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | 1753 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ |
1687 | static struct attribute *dme1737_attr_lock[] = { | 1754 | static struct attribute *dme1737_zone_chmod_attr[] = { |
1688 | /* Temperatures */ | 1755 | &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, |
1689 | SENSOR_DEV_ATTR_TEMP_LOCK(1), | 1756 | &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, |
1690 | SENSOR_DEV_ATTR_TEMP_LOCK(2), | 1757 | &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, |
1691 | SENSOR_DEV_ATTR_TEMP_LOCK(3), | 1758 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, |
1692 | /* Zones */ | 1759 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
1693 | SENSOR_DEV_ATTR_ZONE_LOCK(1), | 1760 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
1694 | SENSOR_DEV_ATTR_ZONE_LOCK(2), | 1761 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, |
1695 | SENSOR_DEV_ATTR_ZONE_LOCK(3), | 1762 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, |
1763 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
1696 | NULL | 1764 | NULL |
1697 | }; | 1765 | }; |
1698 | 1766 | ||
1699 | static const struct attribute_group dme1737_lock_group = { | 1767 | static const struct attribute_group dme1737_zone_chmod_group = { |
1700 | .attrs = dme1737_attr_lock, | 1768 | .attrs = dme1737_zone_chmod_attr, |
1701 | }; | 1769 | }; |
1702 | 1770 | ||
1703 | /* The permissions of the following PWM attributes are changed to read- | 1771 | /* The permissions of the following PWM attributes are changed to read- |
1704 | * writeable if the chip is *not* locked and the respective PWM is available. | 1772 | * writeable if the chip is *not* locked and the respective PWM is available. |
1705 | * Otherwise they stay read-only. */ | 1773 | * Otherwise they stay read-only. */ |
1706 | static struct attribute *dme1737_attr_pwm1_lock[] = { | 1774 | static struct attribute *dme1737_pwm1_chmod_attr[] = { |
1707 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(1), | 1775 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
1776 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
1777 | &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, | ||
1778 | &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, | ||
1779 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
1708 | NULL | 1780 | NULL |
1709 | }; | 1781 | }; |
1710 | static struct attribute *dme1737_attr_pwm2_lock[] = { | 1782 | static struct attribute *dme1737_pwm2_chmod_attr[] = { |
1711 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(2), | 1783 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
1784 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
1785 | &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, | ||
1786 | &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, | ||
1787 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | ||
1712 | NULL | 1788 | NULL |
1713 | }; | 1789 | }; |
1714 | static struct attribute *dme1737_attr_pwm3_lock[] = { | 1790 | static struct attribute *dme1737_pwm3_chmod_attr[] = { |
1715 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(3), | 1791 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
1792 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
1793 | &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, | ||
1794 | &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, | ||
1795 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | ||
1716 | NULL | 1796 | NULL |
1717 | }; | 1797 | }; |
1718 | static struct attribute *dme1737_attr_pwm5_lock[] = { | 1798 | static struct attribute *dme1737_pwm5_chmod_attr[] = { |
1719 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(5), | 1799 | &sensor_dev_attr_pwm5.dev_attr.attr, |
1800 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, | ||
1720 | NULL | 1801 | NULL |
1721 | }; | 1802 | }; |
1722 | static struct attribute *dme1737_attr_pwm6_lock[] = { | 1803 | static struct attribute *dme1737_pwm6_chmod_attr[] = { |
1723 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(6), | 1804 | &sensor_dev_attr_pwm6.dev_attr.attr, |
1805 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, | ||
1724 | NULL | 1806 | NULL |
1725 | }; | 1807 | }; |
1726 | 1808 | ||
1727 | static const struct attribute_group dme1737_pwm_lock_group[] = { | 1809 | static const struct attribute_group dme1737_pwm_chmod_group[] = { |
1728 | { .attrs = dme1737_attr_pwm1_lock }, | 1810 | { .attrs = dme1737_pwm1_chmod_attr }, |
1729 | { .attrs = dme1737_attr_pwm2_lock }, | 1811 | { .attrs = dme1737_pwm2_chmod_attr }, |
1730 | { .attrs = dme1737_attr_pwm3_lock }, | 1812 | { .attrs = dme1737_pwm3_chmod_attr }, |
1731 | { .attrs = NULL }, | 1813 | { .attrs = NULL }, |
1732 | { .attrs = dme1737_attr_pwm5_lock }, | 1814 | { .attrs = dme1737_pwm5_chmod_attr }, |
1733 | { .attrs = dme1737_attr_pwm6_lock }, | 1815 | { .attrs = dme1737_pwm6_chmod_attr }, |
1734 | }; | 1816 | }; |
1735 | 1817 | ||
1736 | /* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the | 1818 | /* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the |
1737 | * chip is not locked. Otherwise they are read-only. */ | 1819 | * chip is not locked. Otherwise they are read-only. */ |
1738 | static struct attribute *dme1737_attr_pwm[] = { | 1820 | static struct attribute *dme1737_pwm_chmod_attr[] = { |
1739 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1821 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1740 | &sensor_dev_attr_pwm2.dev_attr.attr, | 1822 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1741 | &sensor_dev_attr_pwm3.dev_attr.attr, | 1823 | &sensor_dev_attr_pwm3.dev_attr.attr, |
@@ -1809,12 +1891,20 @@ static void dme1737_remove_files(struct device *dev) | |||
1809 | if (data->has_pwm & (1 << ix)) { | 1891 | if (data->has_pwm & (1 << ix)) { |
1810 | sysfs_remove_group(&dev->kobj, | 1892 | sysfs_remove_group(&dev->kobj, |
1811 | &dme1737_pwm_group[ix]); | 1893 | &dme1737_pwm_group[ix]); |
1894 | if (data->type != sch5027 && ix < 3) { | ||
1895 | sysfs_remove_file(&dev->kobj, | ||
1896 | dme1737_pwm_misc_attr[ix]); | ||
1897 | } | ||
1812 | } | 1898 | } |
1813 | } | 1899 | } |
1814 | 1900 | ||
1901 | if (data->type != sch5027) { | ||
1902 | sysfs_remove_group(&dev->kobj, &dme1737_misc_group); | ||
1903 | } | ||
1904 | |||
1815 | sysfs_remove_group(&dev->kobj, &dme1737_group); | 1905 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
1816 | 1906 | ||
1817 | if (!data->client.driver) { | 1907 | if (!data->client) { |
1818 | sysfs_remove_file(&dev->kobj, &dev_attr_name.attr); | 1908 | sysfs_remove_file(&dev->kobj, &dev_attr_name.attr); |
1819 | } | 1909 | } |
1820 | } | 1910 | } |
@@ -1825,7 +1915,7 @@ static int dme1737_create_files(struct device *dev) | |||
1825 | int err, ix; | 1915 | int err, ix; |
1826 | 1916 | ||
1827 | /* Create a name attribute for ISA devices */ | 1917 | /* Create a name attribute for ISA devices */ |
1828 | if (!data->client.driver && | 1918 | if (!data->client && |
1829 | (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) { | 1919 | (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) { |
1830 | goto exit; | 1920 | goto exit; |
1831 | } | 1921 | } |
@@ -1835,6 +1925,13 @@ static int dme1737_create_files(struct device *dev) | |||
1835 | goto exit_remove; | 1925 | goto exit_remove; |
1836 | } | 1926 | } |
1837 | 1927 | ||
1928 | /* Create misc sysfs attributes */ | ||
1929 | if ((data->type != sch5027) && | ||
1930 | (err = sysfs_create_group(&dev->kobj, | ||
1931 | &dme1737_misc_group))) { | ||
1932 | goto exit_remove; | ||
1933 | } | ||
1934 | |||
1838 | /* Create fan sysfs attributes */ | 1935 | /* Create fan sysfs attributes */ |
1839 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 1936 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
1840 | if (data->has_fan & (1 << ix)) { | 1937 | if (data->has_fan & (1 << ix)) { |
@@ -1852,6 +1949,11 @@ static int dme1737_create_files(struct device *dev) | |||
1852 | &dme1737_pwm_group[ix]))) { | 1949 | &dme1737_pwm_group[ix]))) { |
1853 | goto exit_remove; | 1950 | goto exit_remove; |
1854 | } | 1951 | } |
1952 | if (data->type != sch5027 && ix < 3 && | ||
1953 | (err = sysfs_create_file(&dev->kobj, | ||
1954 | dme1737_pwm_misc_attr[ix]))) { | ||
1955 | goto exit_remove; | ||
1956 | } | ||
1855 | } | 1957 | } |
1856 | } | 1958 | } |
1857 | 1959 | ||
@@ -1861,16 +1963,27 @@ static int dme1737_create_files(struct device *dev) | |||
1861 | dev_info(dev, "Device is locked. Some attributes " | 1963 | dev_info(dev, "Device is locked. Some attributes " |
1862 | "will be read-only.\n"); | 1964 | "will be read-only.\n"); |
1863 | } else { | 1965 | } else { |
1864 | /* Change permissions of standard attributes */ | 1966 | /* Change permissions of zone sysfs attributes */ |
1865 | dme1737_chmod_group(dev, &dme1737_lock_group, | 1967 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, |
1866 | S_IRUGO | S_IWUSR); | 1968 | S_IRUGO | S_IWUSR); |
1867 | 1969 | ||
1868 | /* Change permissions of PWM attributes */ | 1970 | /* Change permissions of misc sysfs attributes */ |
1869 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_lock_group); ix++) { | 1971 | if (data->type != sch5027) { |
1972 | dme1737_chmod_group(dev, &dme1737_misc_group, | ||
1973 | S_IRUGO | S_IWUSR); | ||
1974 | } | ||
1975 | |||
1976 | /* Change permissions of PWM sysfs attributes */ | ||
1977 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { | ||
1870 | if (data->has_pwm & (1 << ix)) { | 1978 | if (data->has_pwm & (1 << ix)) { |
1871 | dme1737_chmod_group(dev, | 1979 | dme1737_chmod_group(dev, |
1872 | &dme1737_pwm_lock_group[ix], | 1980 | &dme1737_pwm_chmod_group[ix], |
1981 | S_IRUGO | S_IWUSR); | ||
1982 | if (data->type != sch5027 && ix < 3) { | ||
1983 | dme1737_chmod_file(dev, | ||
1984 | dme1737_pwm_misc_attr[ix], | ||
1873 | S_IRUGO | S_IWUSR); | 1985 | S_IRUGO | S_IWUSR); |
1986 | } | ||
1874 | } | 1987 | } |
1875 | } | 1988 | } |
1876 | 1989 | ||
@@ -1879,7 +1992,7 @@ static int dme1737_create_files(struct device *dev) | |||
1879 | if ((data->has_pwm & (1 << ix)) && | 1992 | if ((data->has_pwm & (1 << ix)) && |
1880 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | 1993 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { |
1881 | dme1737_chmod_file(dev, | 1994 | dme1737_chmod_file(dev, |
1882 | dme1737_attr_pwm[ix], | 1995 | dme1737_pwm_chmod_attr[ix], |
1883 | S_IRUGO | S_IWUSR); | 1996 | S_IRUGO | S_IWUSR); |
1884 | } | 1997 | } |
1885 | } | 1998 | } |
@@ -1896,11 +2009,14 @@ exit: | |||
1896 | static int dme1737_init_device(struct device *dev) | 2009 | static int dme1737_init_device(struct device *dev) |
1897 | { | 2010 | { |
1898 | struct dme1737_data *data = dev_get_drvdata(dev); | 2011 | struct dme1737_data *data = dev_get_drvdata(dev); |
1899 | struct i2c_client *client = &data->client; | 2012 | struct i2c_client *client = data->client; |
1900 | int ix; | 2013 | int ix; |
1901 | u8 reg; | 2014 | u8 reg; |
1902 | 2015 | ||
1903 | data->config = dme1737_read(client, DME1737_REG_CONFIG); | 2016 | /* Point to the right nominal voltages array */ |
2017 | data->in_nominal = IN_NOMINAL(data->type); | ||
2018 | |||
2019 | data->config = dme1737_read(data, DME1737_REG_CONFIG); | ||
1904 | /* Inform if part is not monitoring/started */ | 2020 | /* Inform if part is not monitoring/started */ |
1905 | if (!(data->config & 0x01)) { | 2021 | if (!(data->config & 0x01)) { |
1906 | if (!force_start) { | 2022 | if (!force_start) { |
@@ -1912,7 +2028,7 @@ static int dme1737_init_device(struct device *dev) | |||
1912 | 2028 | ||
1913 | /* Force monitoring */ | 2029 | /* Force monitoring */ |
1914 | data->config |= 0x01; | 2030 | data->config |= 0x01; |
1915 | dme1737_write(client, DME1737_REG_CONFIG, data->config); | 2031 | dme1737_write(data, DME1737_REG_CONFIG, data->config); |
1916 | } | 2032 | } |
1917 | /* Inform if part is not ready */ | 2033 | /* Inform if part is not ready */ |
1918 | if (!(data->config & 0x04)) { | 2034 | if (!(data->config & 0x04)) { |
@@ -1921,8 +2037,8 @@ static int dme1737_init_device(struct device *dev) | |||
1921 | } | 2037 | } |
1922 | 2038 | ||
1923 | /* Determine which optional fan and pwm features are enabled/present */ | 2039 | /* Determine which optional fan and pwm features are enabled/present */ |
1924 | if (client->driver) { /* I2C chip */ | 2040 | if (client) { /* I2C chip */ |
1925 | data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); | 2041 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); |
1926 | /* Check if optional fan3 input is enabled */ | 2042 | /* Check if optional fan3 input is enabled */ |
1927 | if (data->config2 & 0x04) { | 2043 | if (data->config2 & 0x04) { |
1928 | data->has_fan |= (1 << 2); | 2044 | data->has_fan |= (1 << 2); |
@@ -1931,7 +2047,7 @@ static int dme1737_init_device(struct device *dev) | |||
1931 | /* Fan4 and pwm3 are only available if the client's I2C address | 2047 | /* Fan4 and pwm3 are only available if the client's I2C address |
1932 | * is the default 0x2e. Otherwise the I/Os associated with | 2048 | * is the default 0x2e. Otherwise the I/Os associated with |
1933 | * these functions are used for addr enable/select. */ | 2049 | * these functions are used for addr enable/select. */ |
1934 | if (data->client.addr == 0x2e) { | 2050 | if (client->addr == 0x2e) { |
1935 | data->has_fan |= (1 << 3); | 2051 | data->has_fan |= (1 << 3); |
1936 | data->has_pwm |= (1 << 2); | 2052 | data->has_pwm |= (1 << 2); |
1937 | } | 2053 | } |
@@ -1966,16 +2082,16 @@ static int dme1737_init_device(struct device *dev) | |||
1966 | (data->has_fan & (1 << 4)) ? "yes" : "no", | 2082 | (data->has_fan & (1 << 4)) ? "yes" : "no", |
1967 | (data->has_fan & (1 << 5)) ? "yes" : "no"); | 2083 | (data->has_fan & (1 << 5)) ? "yes" : "no"); |
1968 | 2084 | ||
1969 | reg = dme1737_read(client, DME1737_REG_TACH_PWM); | 2085 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); |
1970 | /* Inform if fan-to-pwm mapping differs from the default */ | 2086 | /* Inform if fan-to-pwm mapping differs from the default */ |
1971 | if (client->driver && reg != 0xa4) { /* I2C chip */ | 2087 | if (client && reg != 0xa4) { /* I2C chip */ |
1972 | dev_warn(dev, "Non-standard fan to pwm mapping: " | 2088 | dev_warn(dev, "Non-standard fan to pwm mapping: " |
1973 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " | 2089 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " |
1974 | "fan4->pwm%d. Please report to the driver " | 2090 | "fan4->pwm%d. Please report to the driver " |
1975 | "maintainer.\n", | 2091 | "maintainer.\n", |
1976 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | 2092 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, |
1977 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); | 2093 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); |
1978 | } else if (!client->driver && reg != 0x24) { /* ISA chip */ | 2094 | } else if (!client && reg != 0x24) { /* ISA chip */ |
1979 | dev_warn(dev, "Non-standard fan to pwm mapping: " | 2095 | dev_warn(dev, "Non-standard fan to pwm mapping: " |
1980 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " | 2096 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " |
1981 | "Please report to the driver maintainer.\n", | 2097 | "Please report to the driver maintainer.\n", |
@@ -1988,7 +2104,7 @@ static int dme1737_init_device(struct device *dev) | |||
1988 | * disabled). */ | 2104 | * disabled). */ |
1989 | if (!(data->config & 0x02)) { | 2105 | if (!(data->config & 0x02)) { |
1990 | for (ix = 0; ix < 3; ix++) { | 2106 | for (ix = 0; ix < 3; ix++) { |
1991 | data->pwm_config[ix] = dme1737_read(client, | 2107 | data->pwm_config[ix] = dme1737_read(data, |
1992 | DME1737_REG_PWM_CONFIG(ix)); | 2108 | DME1737_REG_PWM_CONFIG(ix)); |
1993 | if ((data->has_pwm & (1 << ix)) && | 2109 | if ((data->has_pwm & (1 << ix)) && |
1994 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | 2110 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { |
@@ -1996,8 +2112,8 @@ static int dme1737_init_device(struct device *dev) | |||
1996 | "manual mode.\n", ix + 1); | 2112 | "manual mode.\n", ix + 1); |
1997 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | 2113 | data->pwm_config[ix] = PWM_EN_TO_REG(1, |
1998 | data->pwm_config[ix]); | 2114 | data->pwm_config[ix]); |
1999 | dme1737_write(client, DME1737_REG_PWM(ix), 0); | 2115 | dme1737_write(data, DME1737_REG_PWM(ix), 0); |
2000 | dme1737_write(client, | 2116 | dme1737_write(data, |
2001 | DME1737_REG_PWM_CONFIG(ix), | 2117 | DME1737_REG_PWM_CONFIG(ix), |
2002 | data->pwm_config[ix]); | 2118 | data->pwm_config[ix]); |
2003 | } | 2119 | } |
@@ -2010,7 +2126,9 @@ static int dme1737_init_device(struct device *dev) | |||
2010 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | 2126 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ |
2011 | 2127 | ||
2012 | /* Set VRM */ | 2128 | /* Set VRM */ |
2013 | data->vrm = vid_which_vrm(); | 2129 | if (data->type != sch5027) { |
2130 | data->vrm = vid_which_vrm(); | ||
2131 | } | ||
2014 | 2132 | ||
2015 | return 0; | 2133 | return 0; |
2016 | } | 2134 | } |
@@ -2029,9 +2147,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
2029 | dme1737_sio_enter(sio_cip); | 2147 | dme1737_sio_enter(sio_cip); |
2030 | 2148 | ||
2031 | /* Check device ID | 2149 | /* Check device ID |
2032 | * The DME1737 can return either 0x78 or 0x77 as its device ID. */ | 2150 | * The DME1737 can return either 0x78 or 0x77 as its device ID. |
2151 | * The SCH5027 returns 0x89 as its device ID. */ | ||
2033 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2152 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
2034 | if (!(reg == 0x77 || reg == 0x78)) { | 2153 | if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) { |
2035 | err = -ENODEV; | 2154 | err = -ENODEV; |
2036 | goto exit; | 2155 | goto exit; |
2037 | } | 2156 | } |
@@ -2068,71 +2187,80 @@ exit: | |||
2068 | return err; | 2187 | return err; |
2069 | } | 2188 | } |
2070 | 2189 | ||
2071 | static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | 2190 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
2072 | int kind) | 2191 | static int dme1737_i2c_detect(struct i2c_client *client, int kind, |
2192 | struct i2c_board_info *info) | ||
2073 | { | 2193 | { |
2194 | struct i2c_adapter *adapter = client->adapter; | ||
2195 | struct device *dev = &adapter->dev; | ||
2074 | u8 company, verstep = 0; | 2196 | u8 company, verstep = 0; |
2075 | struct i2c_client *client; | ||
2076 | struct dme1737_data *data; | ||
2077 | struct device *dev; | ||
2078 | int err = 0; | ||
2079 | const char *name; | 2197 | const char *name; |
2080 | 2198 | ||
2081 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 2199 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
2082 | goto exit; | 2200 | return -ENODEV; |
2083 | } | ||
2084 | |||
2085 | if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { | ||
2086 | err = -ENOMEM; | ||
2087 | goto exit; | ||
2088 | } | 2201 | } |
2089 | 2202 | ||
2090 | client = &data->client; | ||
2091 | i2c_set_clientdata(client, data); | ||
2092 | client->addr = address; | ||
2093 | client->adapter = adapter; | ||
2094 | client->driver = &dme1737_i2c_driver; | ||
2095 | dev = &client->dev; | ||
2096 | |||
2097 | /* A negative kind means that the driver was loaded with no force | 2203 | /* A negative kind means that the driver was loaded with no force |
2098 | * parameter (default), so we must identify the chip. */ | 2204 | * parameter (default), so we must identify the chip. */ |
2099 | if (kind < 0) { | 2205 | if (kind < 0) { |
2100 | company = dme1737_read(client, DME1737_REG_COMPANY); | 2206 | company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY); |
2101 | verstep = dme1737_read(client, DME1737_REG_VERSTEP); | 2207 | verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP); |
2102 | 2208 | ||
2103 | if (!((company == DME1737_COMPANY_SMSC) && | 2209 | if (company == DME1737_COMPANY_SMSC && |
2104 | ((verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP))) { | 2210 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { |
2105 | err = -ENODEV; | 2211 | kind = dme1737; |
2106 | goto exit_kfree; | 2212 | } else if (company == DME1737_COMPANY_SMSC && |
2213 | verstep == SCH5027_VERSTEP) { | ||
2214 | kind = sch5027; | ||
2215 | } else { | ||
2216 | return -ENODEV; | ||
2107 | } | 2217 | } |
2108 | } | 2218 | } |
2109 | 2219 | ||
2110 | kind = dme1737; | 2220 | if (kind == sch5027) { |
2111 | name = "dme1737"; | 2221 | name = "sch5027"; |
2222 | } else { | ||
2223 | kind = dme1737; | ||
2224 | name = "dme1737"; | ||
2225 | } | ||
2112 | 2226 | ||
2113 | /* Fill in the remaining client fields and put it into the global | 2227 | dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", |
2114 | * list */ | 2228 | kind == sch5027 ? "SCH5027" : "DME1737", client->addr, |
2115 | strlcpy(client->name, name, I2C_NAME_SIZE); | 2229 | verstep); |
2116 | mutex_init(&data->update_lock); | 2230 | strlcpy(info->type, name, I2C_NAME_SIZE); |
2117 | 2231 | ||
2118 | /* Tell the I2C layer a new client has arrived */ | 2232 | return 0; |
2119 | if ((err = i2c_attach_client(client))) { | 2233 | } |
2120 | goto exit_kfree; | 2234 | |
2235 | static int dme1737_i2c_probe(struct i2c_client *client, | ||
2236 | const struct i2c_device_id *id) | ||
2237 | { | ||
2238 | struct dme1737_data *data; | ||
2239 | struct device *dev = &client->dev; | ||
2240 | int err; | ||
2241 | |||
2242 | data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL); | ||
2243 | if (!data) { | ||
2244 | err = -ENOMEM; | ||
2245 | goto exit; | ||
2121 | } | 2246 | } |
2122 | 2247 | ||
2123 | dev_info(dev, "Found a DME1737 chip at 0x%02x (rev 0x%02x).\n", | 2248 | i2c_set_clientdata(client, data); |
2124 | client->addr, verstep); | 2249 | data->type = id->driver_data; |
2250 | data->client = client; | ||
2251 | data->name = client->name; | ||
2252 | mutex_init(&data->update_lock); | ||
2125 | 2253 | ||
2126 | /* Initialize the DME1737 chip */ | 2254 | /* Initialize the DME1737 chip */ |
2127 | if ((err = dme1737_init_device(dev))) { | 2255 | if ((err = dme1737_init_device(dev))) { |
2128 | dev_err(dev, "Failed to initialize device.\n"); | 2256 | dev_err(dev, "Failed to initialize device.\n"); |
2129 | goto exit_detach; | 2257 | goto exit_kfree; |
2130 | } | 2258 | } |
2131 | 2259 | ||
2132 | /* Create sysfs files */ | 2260 | /* Create sysfs files */ |
2133 | if ((err = dme1737_create_files(dev))) { | 2261 | if ((err = dme1737_create_files(dev))) { |
2134 | dev_err(dev, "Failed to create sysfs files.\n"); | 2262 | dev_err(dev, "Failed to create sysfs files.\n"); |
2135 | goto exit_detach; | 2263 | goto exit_kfree; |
2136 | } | 2264 | } |
2137 | 2265 | ||
2138 | /* Register device */ | 2266 | /* Register device */ |
@@ -2147,45 +2275,40 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
2147 | 2275 | ||
2148 | exit_remove: | 2276 | exit_remove: |
2149 | dme1737_remove_files(dev); | 2277 | dme1737_remove_files(dev); |
2150 | exit_detach: | ||
2151 | i2c_detach_client(client); | ||
2152 | exit_kfree: | 2278 | exit_kfree: |
2153 | kfree(data); | 2279 | kfree(data); |
2154 | exit: | 2280 | exit: |
2155 | return err; | 2281 | return err; |
2156 | } | 2282 | } |
2157 | 2283 | ||
2158 | static int dme1737_i2c_attach_adapter(struct i2c_adapter *adapter) | 2284 | static int dme1737_i2c_remove(struct i2c_client *client) |
2159 | { | ||
2160 | if (!(adapter->class & I2C_CLASS_HWMON)) { | ||
2161 | return 0; | ||
2162 | } | ||
2163 | |||
2164 | return i2c_probe(adapter, &addr_data, dme1737_i2c_detect); | ||
2165 | } | ||
2166 | |||
2167 | static int dme1737_i2c_detach_client(struct i2c_client *client) | ||
2168 | { | 2285 | { |
2169 | struct dme1737_data *data = i2c_get_clientdata(client); | 2286 | struct dme1737_data *data = i2c_get_clientdata(client); |
2170 | int err; | ||
2171 | 2287 | ||
2172 | hwmon_device_unregister(data->hwmon_dev); | 2288 | hwmon_device_unregister(data->hwmon_dev); |
2173 | dme1737_remove_files(&client->dev); | 2289 | dme1737_remove_files(&client->dev); |
2174 | 2290 | ||
2175 | if ((err = i2c_detach_client(client))) { | ||
2176 | return err; | ||
2177 | } | ||
2178 | |||
2179 | kfree(data); | 2291 | kfree(data); |
2180 | return 0; | 2292 | return 0; |
2181 | } | 2293 | } |
2182 | 2294 | ||
2295 | static const struct i2c_device_id dme1737_id[] = { | ||
2296 | { "dme1737", dme1737 }, | ||
2297 | { "sch5027", sch5027 }, | ||
2298 | { } | ||
2299 | }; | ||
2300 | MODULE_DEVICE_TABLE(i2c, dme1737_id); | ||
2301 | |||
2183 | static struct i2c_driver dme1737_i2c_driver = { | 2302 | static struct i2c_driver dme1737_i2c_driver = { |
2303 | .class = I2C_CLASS_HWMON, | ||
2184 | .driver = { | 2304 | .driver = { |
2185 | .name = "dme1737", | 2305 | .name = "dme1737", |
2186 | }, | 2306 | }, |
2187 | .attach_adapter = dme1737_i2c_attach_adapter, | 2307 | .probe = dme1737_i2c_probe, |
2188 | .detach_client = dme1737_i2c_detach_client, | 2308 | .remove = dme1737_i2c_remove, |
2309 | .id_table = dme1737_id, | ||
2310 | .detect = dme1737_i2c_detect, | ||
2311 | .address_data = &addr_data, | ||
2189 | }; | 2312 | }; |
2190 | 2313 | ||
2191 | /* --------------------------------------------------------------------- | 2314 | /* --------------------------------------------------------------------- |
@@ -2269,7 +2392,6 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
2269 | { | 2392 | { |
2270 | u8 company, device; | 2393 | u8 company, device; |
2271 | struct resource *res; | 2394 | struct resource *res; |
2272 | struct i2c_client *client; | ||
2273 | struct dme1737_data *data; | 2395 | struct dme1737_data *data; |
2274 | struct device *dev = &pdev->dev; | 2396 | struct device *dev = &pdev->dev; |
2275 | int err; | 2397 | int err; |
@@ -2288,25 +2410,27 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
2288 | goto exit_release_region; | 2410 | goto exit_release_region; |
2289 | } | 2411 | } |
2290 | 2412 | ||
2291 | client = &data->client; | 2413 | data->addr = res->start; |
2292 | i2c_set_clientdata(client, data); | ||
2293 | client->addr = res->start; | ||
2294 | platform_set_drvdata(pdev, data); | 2414 | platform_set_drvdata(pdev, data); |
2295 | 2415 | ||
2296 | company = dme1737_read(client, DME1737_REG_COMPANY); | 2416 | /* Skip chip detection if module is loaded with force_id parameter */ |
2297 | device = dme1737_read(client, DME1737_REG_DEVICE); | 2417 | if (!force_id) { |
2418 | company = dme1737_read(data, DME1737_REG_COMPANY); | ||
2419 | device = dme1737_read(data, DME1737_REG_DEVICE); | ||
2298 | 2420 | ||
2299 | if (!((company == DME1737_COMPANY_SMSC) && | 2421 | if (!((company == DME1737_COMPANY_SMSC) && |
2300 | (device == SCH311X_DEVICE))) { | 2422 | (device == SCH311X_DEVICE))) { |
2301 | err = -ENODEV; | 2423 | err = -ENODEV; |
2302 | goto exit_kfree; | 2424 | goto exit_kfree; |
2425 | } | ||
2303 | } | 2426 | } |
2427 | data->type = sch311x; | ||
2304 | 2428 | ||
2305 | /* Fill in the remaining client fields and initialize the mutex */ | 2429 | /* Fill in the remaining client fields and initialize the mutex */ |
2306 | strlcpy(client->name, "sch311x", I2C_NAME_SIZE); | 2430 | data->name = "sch311x"; |
2307 | mutex_init(&data->update_lock); | 2431 | mutex_init(&data->update_lock); |
2308 | 2432 | ||
2309 | dev_info(dev, "Found a SCH311x chip at 0x%04x\n", client->addr); | 2433 | dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr); |
2310 | 2434 | ||
2311 | /* Initialize the chip */ | 2435 | /* Initialize the chip */ |
2312 | if ((err = dme1737_init_device(dev))) { | 2436 | if ((err = dme1737_init_device(dev))) { |
@@ -2347,7 +2471,7 @@ static int __devexit dme1737_isa_remove(struct platform_device *pdev) | |||
2347 | 2471 | ||
2348 | hwmon_device_unregister(data->hwmon_dev); | 2472 | hwmon_device_unregister(data->hwmon_dev); |
2349 | dme1737_remove_files(&pdev->dev); | 2473 | dme1737_remove_files(&pdev->dev); |
2350 | release_region(data->client.addr, DME1737_EXTENT); | 2474 | release_region(data->addr, DME1737_EXTENT); |
2351 | platform_set_drvdata(pdev, NULL); | 2475 | platform_set_drvdata(pdev, NULL); |
2352 | kfree(data); | 2476 | kfree(data); |
2353 | 2477 | ||
@@ -2377,7 +2501,10 @@ static int __init dme1737_init(void) | |||
2377 | } | 2501 | } |
2378 | 2502 | ||
2379 | if (dme1737_isa_detect(0x2e, &addr) && | 2503 | if (dme1737_isa_detect(0x2e, &addr) && |
2380 | dme1737_isa_detect(0x4e, &addr)) { | 2504 | dme1737_isa_detect(0x4e, &addr) && |
2505 | (!probe_all_addr || | ||
2506 | (dme1737_isa_detect(0x162e, &addr) && | ||
2507 | dme1737_isa_detect(0x164e, &addr)))) { | ||
2381 | /* Return 0 if we didn't find an ISA device */ | 2508 | /* Return 0 if we didn't find an ISA device */ |
2382 | return 0; | 2509 | return 0; |
2383 | } | 2510 | } |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index cbeb4984b5c7..67067e9a323e 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -87,8 +87,6 @@ static inline void superio_enter(int base); | |||
87 | static inline void superio_select(int base, int ld); | 87 | static inline void superio_select(int base, int ld); |
88 | static inline void superio_exit(int base); | 88 | static inline void superio_exit(int base); |
89 | 89 | ||
90 | static inline u16 fan_from_reg ( u16 reg ); | ||
91 | |||
92 | struct f71882fg_data { | 90 | struct f71882fg_data { |
93 | unsigned short addr; | 91 | unsigned short addr; |
94 | struct device *hwmon_dev; | 92 | struct device *hwmon_dev; |
@@ -116,10 +114,6 @@ struct f71882fg_data { | |||
116 | u8 temp_diode_open; | 114 | u8 temp_diode_open; |
117 | }; | 115 | }; |
118 | 116 | ||
119 | static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg); | ||
120 | static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg); | ||
121 | static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val); | ||
122 | |||
123 | /* Sysfs in*/ | 117 | /* Sysfs in*/ |
124 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | 118 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, |
125 | char *buf); | 119 | char *buf); |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 50f22690d611..a4d92d246d52 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -581,6 +581,8 @@ static int __init hdaps_init(void) | |||
581 | /* initialize the input class */ | 581 | /* initialize the input class */ |
582 | idev = hdaps_idev->input; | 582 | idev = hdaps_idev->input; |
583 | idev->name = "hdaps"; | 583 | idev->name = "hdaps"; |
584 | idev->phys = "isa1600/input0"; | ||
585 | idev->id.bustype = BUS_ISA; | ||
584 | idev->dev.parent = &pdev->dev; | 586 | idev->dev.parent = &pdev->dev; |
585 | idev->evbit[0] = BIT_MASK(EV_ABS); | 587 | idev->evbit[0] = BIT_MASK(EV_ABS); |
586 | input_set_abs_params(idev, ABS_X, | 588 | input_set_abs_params(idev, ABS_X, |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 3330667280b9..bfc296145bba 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -1,76 +1,82 @@ | |||
1 | /* | 1 | /* |
2 | hwmon-vid.c - VID/VRM/VRD voltage conversions | 2 | * hwmon-vid.c - VID/VRM/VRD voltage conversions |
3 | 3 | * | |
4 | Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> | 4 | * Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> |
5 | 5 | * | |
6 | Partly imported from i2c-vid.h of the lm_sensors project | 6 | * Partly imported from i2c-vid.h of the lm_sensors project |
7 | Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | 7 | * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> |
8 | With assistance from Trent Piepho <xyzzy@speakeasy.org> | 8 | * With assistance from Trent Piepho <xyzzy@speakeasy.org> |
9 | 9 | * | |
10 | This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | (at your option) any later version. | 13 | * (at your option) any later version. |
14 | 14 | * | |
15 | This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | 19 | * | |
20 | You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/hwmon-vid.h> | 27 | #include <linux/hwmon-vid.h> |
28 | 28 | ||
29 | /* | 29 | /* |
30 | Common code for decoding VID pins. | 30 | * Common code for decoding VID pins. |
31 | 31 | * | |
32 | References: | 32 | * References: |
33 | 33 | * | |
34 | For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines", | 34 | * For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines", |
35 | available at http://developer.intel.com/. | 35 | * available at http://developer.intel.com/. |
36 | 36 | * | |
37 | For VRD 10.0 and up, "VRD x.y Design Guide", | 37 | * For VRD 10.0 and up, "VRD x.y Design Guide", |
38 | available at http://developer.intel.com/. | 38 | * available at http://developer.intel.com/. |
39 | 39 | * | |
40 | AMD Opteron processors don't follow the Intel specifications. | 40 | * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094, |
41 | I'm going to "make up" 2.4 as the spec number for the Opterons. | 41 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26094.PDF |
42 | No good reason just a mnemonic for the 24x Opteron processor | 42 | * Table 74. VID Code Voltages |
43 | series. | 43 | * This corresponds to an arbitrary VRM code of 24 in the functions below. |
44 | 44 | * These CPU models (K8 revision <= E) have 5 VID pins. See also: | |
45 | Opteron VID encoding is: | 45 | * Revision Guide for AMD Athlon 64 and AMD Opteron Processors, AMD Publication 25759, |
46 | 00000 = 1.550 V | 46 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf |
47 | 00001 = 1.525 V | 47 | * |
48 | . . . . | 48 | * AMD NPT Family 0Fh Processors, AMD Publication 32559, |
49 | 11110 = 0.800 V | 49 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf |
50 | 11111 = 0.000 V (off) | 50 | * Table 71. VID Code Voltages |
51 | 51 | * This corresponds to an arbitrary VRM code of 25 in the functions below. | |
52 | The 17 specification is in fact Intel Mobile Voltage Positioning - | 52 | * These CPU models (K8 revision >= F) have 6 VID pins. See also: |
53 | (IMVP-II). You can find more information in the datasheet of Max1718 | 53 | * Revision Guide for AMD NPT Family 0Fh Processors, AMD Publication 33610, |
54 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 | 54 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf |
55 | 55 | * | |
56 | The 13 specification corresponds to the Intel Pentium M series. There | 56 | * The 17 specification is in fact Intel Mobile Voltage Positioning - |
57 | doesn't seem to be any named specification for these. The conversion | 57 | * (IMVP-II). You can find more information in the datasheet of Max1718 |
58 | tables are detailed directly in the various Pentium M datasheets: | 58 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 |
59 | http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm | 59 | * |
60 | 60 | * The 13 specification corresponds to the Intel Pentium M series. There | |
61 | The 14 specification corresponds to Intel Core series. There | 61 | * doesn't seem to be any named specification for these. The conversion |
62 | doesn't seem to be any named specification for these. The conversion | 62 | * tables are detailed directly in the various Pentium M datasheets: |
63 | tables are detailed directly in the various Pentium Core datasheets: | 63 | * http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm |
64 | http://www.intel.com/design/mobile/datashts/309221.htm | 64 | * |
65 | 65 | * The 14 specification corresponds to Intel Core series. There | |
66 | The 110 (VRM 11) specification corresponds to Intel Conroe based series. | 66 | * doesn't seem to be any named specification for these. The conversion |
67 | http://www.intel.com/design/processor/applnots/313214.htm | 67 | * tables are detailed directly in the various Pentium Core datasheets: |
68 | */ | 68 | * http://www.intel.com/design/mobile/datashts/309221.htm |
69 | 69 | * | |
70 | /* vrm is the VRM/VRD document version multiplied by 10. | 70 | * The 110 (VRM 11) specification corresponds to Intel Conroe based series. |
71 | val is the 4-bit or more VID code. | 71 | * http://www.intel.com/design/processor/applnots/313214.htm |
72 | Returned value is in mV to avoid floating point in the kernel. | 72 | */ |
73 | Some VID have some bits in uV scale, this is rounded to mV */ | 73 | |
74 | /* | ||
75 | * vrm is the VRM/VRD document version multiplied by 10. | ||
76 | * val is the 4-bit or more VID code. | ||
77 | * Returned value is in mV to avoid floating point in the kernel. | ||
78 | * Some VID have some bits in uV scale, this is rounded to mV. | ||
79 | */ | ||
74 | int vid_from_reg(int val, u8 vrm) | 80 | int vid_from_reg(int val, u8 vrm) |
75 | { | 81 | { |
76 | int vid; | 82 | int vid; |
@@ -96,9 +102,16 @@ int vid_from_reg(int val, u8 vrm) | |||
96 | if (val < 0x02 || val > 0xb2) | 102 | if (val < 0x02 || val > 0xb2) |
97 | return 0; | 103 | return 0; |
98 | return((1600000 - (val - 2) * 6250 + 500) / 1000); | 104 | return((1600000 - (val - 2) * 6250 + 500) / 1000); |
99 | case 24: /* Opteron processor */ | 105 | |
106 | case 24: /* Athlon64 & Opteron */ | ||
100 | val &= 0x1f; | 107 | val &= 0x1f; |
101 | return(val == 0x1f ? 0 : 1550 - val * 25); | 108 | if (val == 0x1f) |
109 | return 0; | ||
110 | /* fall through */ | ||
111 | case 25: /* AMD NPT 0Fh */ | ||
112 | val &= 0x3f; | ||
113 | return (val < 32) ? 1550 - 25 * val | ||
114 | : 775 - (25 * (val - 31)) / 2; | ||
102 | 115 | ||
103 | case 91: /* VRM 9.1 */ | 116 | case 91: /* VRM 9.1 */ |
104 | case 90: /* VRM 9.0 */ | 117 | case 90: /* VRM 9.0 */ |
@@ -141,9 +154,9 @@ int vid_from_reg(int val, u8 vrm) | |||
141 | 154 | ||
142 | 155 | ||
143 | /* | 156 | /* |
144 | After this point is the code to automatically determine which | 157 | * After this point is the code to automatically determine which |
145 | VRM/VRD specification should be used depending on the CPU. | 158 | * VRM/VRD specification should be used depending on the CPU. |
146 | */ | 159 | */ |
147 | 160 | ||
148 | struct vrm_model { | 161 | struct vrm_model { |
149 | u8 vendor; | 162 | u8 vendor; |
@@ -157,11 +170,17 @@ struct vrm_model { | |||
157 | 170 | ||
158 | #ifdef CONFIG_X86 | 171 | #ifdef CONFIG_X86 |
159 | 172 | ||
160 | /* the stepping parameter is highest acceptable stepping for current line */ | 173 | /* |
174 | * The stepping parameter is highest acceptable stepping for current line. | ||
175 | * The model match must be exact for 4-bit values. For model values 0x10 | ||
176 | * and above (extended model), all models below the parameter will match. | ||
177 | */ | ||
161 | 178 | ||
162 | static struct vrm_model vrm_models[] = { | 179 | static struct vrm_model vrm_models[] = { |
163 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ | 180 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ |
164 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */ | 181 | {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ |
182 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */ | ||
183 | {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ | ||
165 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ | 184 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ |
166 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ | 185 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ |
167 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ | 186 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ |
@@ -189,6 +208,8 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) | |||
189 | if (vrm_models[i].vendor==vendor) | 208 | if (vrm_models[i].vendor==vendor) |
190 | if ((vrm_models[i].eff_family==eff_family) | 209 | if ((vrm_models[i].eff_family==eff_family) |
191 | && ((vrm_models[i].eff_model==eff_model) || | 210 | && ((vrm_models[i].eff_model==eff_model) || |
211 | (vrm_models[i].eff_model >= 0x10 && | ||
212 | eff_model <= vrm_models[i].eff_model) || | ||
192 | (vrm_models[i].eff_model==ANY)) && | 213 | (vrm_models[i].eff_model==ANY)) && |
193 | (eff_stepping <= vrm_models[i].eff_stepping)) | 214 | (eff_stepping <= vrm_models[i].eff_stepping)) |
194 | return vrm_models[i].vrm_type; | 215 | return vrm_models[i].vrm_type; |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 3db28450a3b3..076a59cdabe9 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -55,7 +55,8 @@ again: | |||
55 | return ERR_PTR(err); | 55 | return ERR_PTR(err); |
56 | 56 | ||
57 | id = id & MAX_ID_MASK; | 57 | id = id & MAX_ID_MASK; |
58 | hwdev = device_create(hwmon_class, dev, MKDEV(0,0), HWMON_ID_FORMAT, id); | 58 | hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, |
59 | HWMON_ID_FORMAT, id); | ||
59 | 60 | ||
60 | if (IS_ERR(hwdev)) { | 61 | if (IS_ERR(hwdev)) { |
61 | spin_lock(&idr_lock); | 62 | spin_lock(&idr_lock); |
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index f9e2ed621f7b..2ede9388096b 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c | |||
@@ -81,6 +81,8 @@ static unsigned long amb_reg_temp(unsigned int amb) | |||
81 | #define MAX_AMBS_PER_CHANNEL 16 | 81 | #define MAX_AMBS_PER_CHANNEL 16 |
82 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ | 82 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ |
83 | MAX_AMBS_PER_CHANNEL) | 83 | MAX_AMBS_PER_CHANNEL) |
84 | #define CHANNEL_SHIFT 4 | ||
85 | #define DIMM_MASK 0xF | ||
84 | /* | 86 | /* |
85 | * Ugly hack: For some reason the highest bit is set if there | 87 | * Ugly hack: For some reason the highest bit is set if there |
86 | * are _any_ DIMMs in the channel. Attempting to read from | 88 | * are _any_ DIMMs in the channel. Attempting to read from |
@@ -89,7 +91,7 @@ static unsigned long amb_reg_temp(unsigned int amb) | |||
89 | * might prevent us from seeing the 16th DIMM in the channel. | 91 | * might prevent us from seeing the 16th DIMM in the channel. |
90 | */ | 92 | */ |
91 | #define REAL_MAX_AMBS_PER_CHANNEL 15 | 93 | #define REAL_MAX_AMBS_PER_CHANNEL 15 |
92 | #define KNOBS_PER_AMB 5 | 94 | #define KNOBS_PER_AMB 6 |
93 | 95 | ||
94 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) | 96 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) |
95 | { | 97 | { |
@@ -238,6 +240,16 @@ static ssize_t show_amb_temp(struct device *dev, | |||
238 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); | 240 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); |
239 | } | 241 | } |
240 | 242 | ||
243 | static ssize_t show_label(struct device *dev, | ||
244 | struct device_attribute *devattr, | ||
245 | char *buf) | ||
246 | { | ||
247 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
248 | |||
249 | return sprintf(buf, "Ch. %d DIMM %d\n", attr->index >> CHANNEL_SHIFT, | ||
250 | attr->index & DIMM_MASK); | ||
251 | } | ||
252 | |||
241 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) | 253 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) |
242 | { | 254 | { |
243 | int i, j, k, d = 0; | 255 | int i, j, k, d = 0; |
@@ -268,6 +280,20 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) | |||
268 | continue; | 280 | continue; |
269 | d++; | 281 | d++; |
270 | 282 | ||
283 | /* sysfs label */ | ||
284 | iattr = data->attrs + data->num_attrs; | ||
285 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
286 | "temp%d_label", d); | ||
287 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
288 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | ||
289 | iattr->s_attr.dev_attr.show = show_label; | ||
290 | iattr->s_attr.index = k; | ||
291 | res = device_create_file(&pdev->dev, | ||
292 | &iattr->s_attr.dev_attr); | ||
293 | if (res) | ||
294 | goto exit_remove; | ||
295 | data->num_attrs++; | ||
296 | |||
271 | /* Temperature sysfs knob */ | 297 | /* Temperature sysfs knob */ |
272 | iattr = data->attrs + data->num_attrs; | 298 | iattr = data->attrs + data->num_attrs; |
273 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 299 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index c9416e657487..7b0ed5dea399 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * A hwmon driver for the IBM Active Energy Manager temperature/power sensors | 2 | * A hwmon driver for the IBM System Director Active Energy Manager (AEM) |
3 | * and capping functionality. | 3 | * temperature/power/energy sensors and capping functionality. |
4 | * Copyright (C) 2008 IBM | 4 | * Copyright (C) 2008 IBM |
5 | * | 5 | * |
6 | * Author: Darrick J. Wong <djwong@us.ibm.com> | 6 | * Author: Darrick J. Wong <djwong@us.ibm.com> |
@@ -463,12 +463,18 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | |||
463 | } | 463 | } |
464 | 464 | ||
465 | /* Update AEM energy registers */ | 465 | /* Update AEM energy registers */ |
466 | static void update_aem_energy_one(struct aem_data *data, int which) | ||
467 | { | ||
468 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, which, | ||
469 | &data->energy[which], 8); | ||
470 | } | ||
471 | |||
466 | static void update_aem_energy(struct aem_data *data) | 472 | static void update_aem_energy(struct aem_data *data) |
467 | { | 473 | { |
468 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 0, &data->energy[0], 8); | 474 | update_aem_energy_one(data, 0); |
469 | if (data->ver_major < 2) | 475 | if (data->ver_major < 2) |
470 | return; | 476 | return; |
471 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 1, &data->energy[1], 8); | 477 | update_aem_energy_one(data, 1); |
472 | } | 478 | } |
473 | 479 | ||
474 | /* Update all AEM1 sensors */ | 480 | /* Update all AEM1 sensors */ |
@@ -676,7 +682,8 @@ static int aem_find_aem2(struct aem_ipmi_data *data, | |||
676 | return -ETIMEDOUT; | 682 | return -ETIMEDOUT; |
677 | 683 | ||
678 | if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || | 684 | if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || |
679 | memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id))) | 685 | memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id)) || |
686 | fi_resp->num_instances <= instance_num) | ||
680 | return -ENOENT; | 687 | return -ENOENT; |
681 | 688 | ||
682 | return 0; | 689 | return 0; |
@@ -849,7 +856,7 @@ static ssize_t aem_show_power(struct device *dev, | |||
849 | struct timespec b, a; | 856 | struct timespec b, a; |
850 | 857 | ||
851 | mutex_lock(&data->lock); | 858 | mutex_lock(&data->lock); |
852 | update_aem_energy(data); | 859 | update_aem_energy_one(data, attr->index); |
853 | getnstimeofday(&b); | 860 | getnstimeofday(&b); |
854 | before = data->energy[attr->index]; | 861 | before = data->energy[attr->index]; |
855 | 862 | ||
@@ -861,7 +868,7 @@ static ssize_t aem_show_power(struct device *dev, | |||
861 | return 0; | 868 | return 0; |
862 | } | 869 | } |
863 | 870 | ||
864 | update_aem_energy(data); | 871 | update_aem_energy_one(data, attr->index); |
865 | getnstimeofday(&a); | 872 | getnstimeofday(&a); |
866 | after = data->energy[attr->index]; | 873 | after = data->energy[attr->index]; |
867 | mutex_unlock(&data->lock); | 874 | mutex_unlock(&data->lock); |
@@ -880,7 +887,9 @@ static ssize_t aem_show_energy(struct device *dev, | |||
880 | { | 887 | { |
881 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 888 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
882 | struct aem_data *a = dev_get_drvdata(dev); | 889 | struct aem_data *a = dev_get_drvdata(dev); |
883 | a->update(a); | 890 | mutex_lock(&a->lock); |
891 | update_aem_energy_one(a, attr->index); | ||
892 | mutex_unlock(&a->lock); | ||
884 | 893 | ||
885 | return sprintf(buf, "%llu\n", | 894 | return sprintf(buf, "%llu\n", |
886 | (unsigned long long)a->energy[attr->index] * 1000); | 895 | (unsigned long long)a->energy[attr->index] * 1000); |
@@ -1104,8 +1113,15 @@ static void __exit aem_exit(void) | |||
1104 | } | 1113 | } |
1105 | 1114 | ||
1106 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | 1115 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); |
1107 | MODULE_DESCRIPTION("IBM Active Energy Manager power/temp sensor driver"); | 1116 | MODULE_DESCRIPTION("IBM AEM power/temp/energy sensor driver"); |
1108 | MODULE_LICENSE("GPL"); | 1117 | MODULE_LICENSE("GPL"); |
1109 | 1118 | ||
1110 | module_init(aem_init); | 1119 | module_init(aem_init); |
1111 | module_exit(aem_exit); | 1120 | module_exit(aem_exit); |
1121 | |||
1122 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3350-*"); | ||
1123 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550-*"); | ||
1124 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*"); | ||
1125 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*"); | ||
1126 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*"); | ||
1127 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*"); | ||
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 4e9b19c6732f..537d9fb2ff88 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c | |||
@@ -608,3 +608,9 @@ MODULE_LICENSE("GPL"); | |||
608 | 608 | ||
609 | module_init(ibmpex_init); | 609 | module_init(ibmpex_init); |
610 | module_exit(ibmpex_exit); | 610 | module_exit(ibmpex_exit); |
611 | |||
612 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3350-*"); | ||
613 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550-*"); | ||
614 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*"); | ||
615 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*"); | ||
616 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*"); | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e12c132ff83a..b74c95735f95 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <linux/err.h> | 46 | #include <linux/err.h> |
47 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
48 | #include <linux/sysfs.h> | 48 | #include <linux/sysfs.h> |
49 | #include <linux/string.h> | ||
50 | #include <linux/dmi.h> | ||
49 | #include <asm/io.h> | 51 | #include <asm/io.h> |
50 | 52 | ||
51 | #define DRVNAME "it87" | 53 | #define DRVNAME "it87" |
@@ -151,9 +153,9 @@ static int fix_pwm_polarity; | |||
151 | /* The IT8718F has the VID value in a different register, in Super-I/O | 153 | /* The IT8718F has the VID value in a different register, in Super-I/O |
152 | configuration space. */ | 154 | configuration space. */ |
153 | #define IT87_REG_VID 0x0a | 155 | #define IT87_REG_VID 0x0a |
154 | /* Warning: register 0x0b is used for something completely different in | 156 | /* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b |
155 | new chips/revisions. I suspect only 16-bit tachometer mode will work | 157 | for fan divisors. Later IT8712F revisions must use 16-bit tachometer |
156 | for these. */ | 158 | mode. */ |
157 | #define IT87_REG_FAN_DIV 0x0b | 159 | #define IT87_REG_FAN_DIV 0x0b |
158 | #define IT87_REG_FAN_16BIT 0x0c | 160 | #define IT87_REG_FAN_16BIT 0x0c |
159 | 161 | ||
@@ -234,7 +236,10 @@ static const unsigned int pwm_freq[8] = { | |||
234 | struct it87_sio_data { | 236 | struct it87_sio_data { |
235 | enum chips type; | 237 | enum chips type; |
236 | /* Values read from Super-I/O config space */ | 238 | /* Values read from Super-I/O config space */ |
239 | u8 revision; | ||
237 | u8 vid_value; | 240 | u8 vid_value; |
241 | /* Values set based on DMI strings */ | ||
242 | u8 skip_pwm; | ||
238 | }; | 243 | }; |
239 | 244 | ||
240 | /* For each registered chip, we need to keep some data in memory. | 245 | /* For each registered chip, we need to keep some data in memory. |
@@ -242,6 +247,7 @@ struct it87_sio_data { | |||
242 | struct it87_data { | 247 | struct it87_data { |
243 | struct device *hwmon_dev; | 248 | struct device *hwmon_dev; |
244 | enum chips type; | 249 | enum chips type; |
250 | u8 revision; | ||
245 | 251 | ||
246 | unsigned short addr; | 252 | unsigned short addr; |
247 | const char *name; | 253 | const char *name; |
@@ -268,6 +274,16 @@ struct it87_data { | |||
268 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ | 274 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ |
269 | }; | 275 | }; |
270 | 276 | ||
277 | static inline int has_16bit_fans(const struct it87_data *data) | ||
278 | { | ||
279 | /* IT8705F Datasheet 0.4.1, 3h == Version G. | ||
280 | IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
281 | These are the first revisions with 16bit tachometer support. */ | ||
282 | return (data->type == it87 && data->revision >= 0x03) | ||
283 | || (data->type == it8712 && data->revision >= 0x08) | ||
284 | || data->type == it8716 | ||
285 | || data->type == it8718; | ||
286 | } | ||
271 | 287 | ||
272 | static int it87_probe(struct platform_device *pdev); | 288 | static int it87_probe(struct platform_device *pdev); |
273 | static int __devexit it87_remove(struct platform_device *pdev); | 289 | static int __devexit it87_remove(struct platform_device *pdev); |
@@ -461,7 +477,7 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, | |||
461 | if (reg & (1 << nr)) | 477 | if (reg & (1 << nr)) |
462 | return sprintf(buf, "3\n"); /* thermal diode */ | 478 | return sprintf(buf, "3\n"); /* thermal diode */ |
463 | if (reg & (8 << nr)) | 479 | if (reg & (8 << nr)) |
464 | return sprintf(buf, "2\n"); /* thermistor */ | 480 | return sprintf(buf, "4\n"); /* thermistor */ |
465 | return sprintf(buf, "0\n"); /* disabled */ | 481 | return sprintf(buf, "0\n"); /* disabled */ |
466 | } | 482 | } |
467 | static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | 483 | static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, |
@@ -477,10 +493,15 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
477 | 493 | ||
478 | data->sensor &= ~(1 << nr); | 494 | data->sensor &= ~(1 << nr); |
479 | data->sensor &= ~(8 << nr); | 495 | data->sensor &= ~(8 << nr); |
480 | /* 3 = thermal diode; 2 = thermistor; 0 = disabled */ | 496 | if (val == 2) { /* backwards compatibility */ |
497 | dev_warn(dev, "Sensor type 2 is deprecated, please use 4 " | ||
498 | "instead\n"); | ||
499 | val = 4; | ||
500 | } | ||
501 | /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ | ||
481 | if (val == 3) | 502 | if (val == 3) |
482 | data->sensor |= 1 << nr; | 503 | data->sensor |= 1 << nr; |
483 | else if (val == 2) | 504 | else if (val == 4) |
484 | data->sensor |= 8 << nr; | 505 | data->sensor |= 8 << nr; |
485 | else if (val != 0) { | 506 | else if (val != 0) { |
486 | mutex_unlock(&data->update_lock); | 507 | mutex_unlock(&data->update_lock); |
@@ -952,6 +973,7 @@ static int __init it87_find(unsigned short *address, | |||
952 | { | 973 | { |
953 | int err = -ENODEV; | 974 | int err = -ENODEV; |
954 | u16 chip_type; | 975 | u16 chip_type; |
976 | const char *board_vendor, *board_name; | ||
955 | 977 | ||
956 | superio_enter(); | 978 | superio_enter(); |
957 | chip_type = force_id ? force_id : superio_inw(DEVID); | 979 | chip_type = force_id ? force_id : superio_inw(DEVID); |
@@ -991,8 +1013,9 @@ static int __init it87_find(unsigned short *address, | |||
991 | } | 1013 | } |
992 | 1014 | ||
993 | err = 0; | 1015 | err = 0; |
1016 | sio_data->revision = superio_inb(DEVREV) & 0x0f; | ||
994 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", | 1017 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", |
995 | chip_type, *address, superio_inb(DEVREV) & 0x0f); | 1018 | chip_type, *address, sio_data->revision); |
996 | 1019 | ||
997 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ | 1020 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ |
998 | if (chip_type != IT8705F_DEVID) { | 1021 | if (chip_type != IT8705F_DEVID) { |
@@ -1009,6 +1032,24 @@ static int __init it87_find(unsigned short *address, | |||
1009 | pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); | 1032 | pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); |
1010 | } | 1033 | } |
1011 | 1034 | ||
1035 | /* Disable specific features based on DMI strings */ | ||
1036 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
1037 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | ||
1038 | if (board_vendor && board_name) { | ||
1039 | if (strcmp(board_vendor, "nVIDIA") == 0 | ||
1040 | && strcmp(board_name, "FN68PT") == 0) { | ||
1041 | /* On the Shuttle SN68PT, FAN_CTL2 is apparently not | ||
1042 | connected to a fan, but to something else. One user | ||
1043 | has reported instant system power-off when changing | ||
1044 | the PWM2 duty cycle, so we disable it. | ||
1045 | I use the board name string as the trigger in case | ||
1046 | the same board is ever used in other systems. */ | ||
1047 | pr_info("it87: Disabling pwm2 due to " | ||
1048 | "hardware constraints\n"); | ||
1049 | sio_data->skip_pwm = (1 << 1); | ||
1050 | } | ||
1051 | } | ||
1052 | |||
1012 | exit: | 1053 | exit: |
1013 | superio_exit(); | 1054 | superio_exit(); |
1014 | return err; | 1055 | return err; |
@@ -1045,6 +1086,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1045 | 1086 | ||
1046 | data->addr = res->start; | 1087 | data->addr = res->start; |
1047 | data->type = sio_data->type; | 1088 | data->type = sio_data->type; |
1089 | data->revision = sio_data->revision; | ||
1048 | data->name = names[sio_data->type]; | 1090 | data->name = names[sio_data->type]; |
1049 | 1091 | ||
1050 | /* Now, we do the remaining detection. */ | 1092 | /* Now, we do the remaining detection. */ |
@@ -1069,7 +1111,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1069 | goto ERROR2; | 1111 | goto ERROR2; |
1070 | 1112 | ||
1071 | /* Do not create fan files for disabled fans */ | 1113 | /* Do not create fan files for disabled fans */ |
1072 | if (data->type == it8716 || data->type == it8718) { | 1114 | if (has_16bit_fans(data)) { |
1073 | /* 16-bit tachometers */ | 1115 | /* 16-bit tachometers */ |
1074 | if (data->has_fan & (1 << 0)) { | 1116 | if (data->has_fan & (1 << 0)) { |
1075 | if ((err = device_create_file(dev, | 1117 | if ((err = device_create_file(dev, |
@@ -1154,25 +1196,33 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1154 | } | 1196 | } |
1155 | 1197 | ||
1156 | if (enable_pwm_interface) { | 1198 | if (enable_pwm_interface) { |
1157 | if ((err = device_create_file(dev, | 1199 | if (!(sio_data->skip_pwm & (1 << 0))) { |
1158 | &sensor_dev_attr_pwm1_enable.dev_attr)) | 1200 | if ((err = device_create_file(dev, |
1159 | || (err = device_create_file(dev, | 1201 | &sensor_dev_attr_pwm1_enable.dev_attr)) |
1160 | &sensor_dev_attr_pwm2_enable.dev_attr)) | 1202 | || (err = device_create_file(dev, |
1161 | || (err = device_create_file(dev, | 1203 | &sensor_dev_attr_pwm1.dev_attr)) |
1162 | &sensor_dev_attr_pwm3_enable.dev_attr)) | 1204 | || (err = device_create_file(dev, |
1163 | || (err = device_create_file(dev, | 1205 | &dev_attr_pwm1_freq))) |
1164 | &sensor_dev_attr_pwm1.dev_attr)) | 1206 | goto ERROR4; |
1165 | || (err = device_create_file(dev, | 1207 | } |
1166 | &sensor_dev_attr_pwm2.dev_attr)) | 1208 | if (!(sio_data->skip_pwm & (1 << 1))) { |
1167 | || (err = device_create_file(dev, | 1209 | if ((err = device_create_file(dev, |
1168 | &sensor_dev_attr_pwm3.dev_attr)) | 1210 | &sensor_dev_attr_pwm2_enable.dev_attr)) |
1169 | || (err = device_create_file(dev, | 1211 | || (err = device_create_file(dev, |
1170 | &dev_attr_pwm1_freq)) | 1212 | &sensor_dev_attr_pwm2.dev_attr)) |
1171 | || (err = device_create_file(dev, | 1213 | || (err = device_create_file(dev, |
1172 | &dev_attr_pwm2_freq)) | 1214 | &dev_attr_pwm2_freq))) |
1173 | || (err = device_create_file(dev, | 1215 | goto ERROR4; |
1174 | &dev_attr_pwm3_freq))) | 1216 | } |
1175 | goto ERROR4; | 1217 | if (!(sio_data->skip_pwm & (1 << 2))) { |
1218 | if ((err = device_create_file(dev, | ||
1219 | &sensor_dev_attr_pwm3_enable.dev_attr)) | ||
1220 | || (err = device_create_file(dev, | ||
1221 | &sensor_dev_attr_pwm3.dev_attr)) | ||
1222 | || (err = device_create_file(dev, | ||
1223 | &dev_attr_pwm3_freq))) | ||
1224 | goto ERROR4; | ||
1225 | } | ||
1176 | } | 1226 | } |
1177 | 1227 | ||
1178 | if (data->type == it8712 || data->type == it8716 | 1228 | if (data->type == it8712 || data->type == it8716 |
@@ -1350,7 +1400,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1350 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 1400 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
1351 | 1401 | ||
1352 | /* Set tachometers to 16-bit mode if needed */ | 1402 | /* Set tachometers to 16-bit mode if needed */ |
1353 | if (data->type == it8716 || data->type == it8718) { | 1403 | if (has_16bit_fans(data)) { |
1354 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | 1404 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); |
1355 | if (~tmp & 0x07 & data->has_fan) { | 1405 | if (~tmp & 0x07 & data->has_fan) { |
1356 | dev_dbg(&pdev->dev, | 1406 | dev_dbg(&pdev->dev, |
@@ -1358,10 +1408,13 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1358 | it87_write_value(data, IT87_REG_FAN_16BIT, | 1408 | it87_write_value(data, IT87_REG_FAN_16BIT, |
1359 | tmp | 0x07); | 1409 | tmp | 0x07); |
1360 | } | 1410 | } |
1361 | if (tmp & (1 << 4)) | 1411 | /* IT8705F only supports three fans. */ |
1362 | data->has_fan |= (1 << 3); /* fan4 enabled */ | 1412 | if (data->type != it87) { |
1363 | if (tmp & (1 << 5)) | 1413 | if (tmp & (1 << 4)) |
1364 | data->has_fan |= (1 << 4); /* fan5 enabled */ | 1414 | data->has_fan |= (1 << 3); /* fan4 enabled */ |
1415 | if (tmp & (1 << 5)) | ||
1416 | data->has_fan |= (1 << 4); /* fan5 enabled */ | ||
1417 | } | ||
1365 | } | 1418 | } |
1366 | 1419 | ||
1367 | /* Set current fan mode registers and the default settings for the | 1420 | /* Set current fan mode registers and the default settings for the |
@@ -1426,7 +1479,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1426 | data->fan[i] = it87_read_value(data, | 1479 | data->fan[i] = it87_read_value(data, |
1427 | IT87_REG_FAN[i]); | 1480 | IT87_REG_FAN[i]); |
1428 | /* Add high byte if in 16-bit mode */ | 1481 | /* Add high byte if in 16-bit mode */ |
1429 | if (data->type == it8716 || data->type == it8718) { | 1482 | if (has_16bit_fans(data)) { |
1430 | data->fan[i] |= it87_read_value(data, | 1483 | data->fan[i] |= it87_read_value(data, |
1431 | IT87_REG_FANX[i]) << 8; | 1484 | IT87_REG_FANX[i]) << 8; |
1432 | data->fan_min[i] |= it87_read_value(data, | 1485 | data->fan_min[i] |= it87_read_value(data, |
@@ -1443,8 +1496,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1443 | } | 1496 | } |
1444 | 1497 | ||
1445 | /* Newer chips don't have clock dividers */ | 1498 | /* Newer chips don't have clock dividers */ |
1446 | if ((data->has_fan & 0x07) && data->type != it8716 | 1499 | if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { |
1447 | && data->type != it8718) { | ||
1448 | i = it87_read_value(data, IT87_REG_FAN_DIV); | 1500 | i = it87_read_value(data, IT87_REG_FAN_DIV); |
1449 | data->fan_div[0] = i & 0x07; | 1501 | data->fan_div[0] = i & 0x07; |
1450 | data->fan_div[1] = (i >> 3) & 0x07; | 1502 | data->fan_div[1] = (i >> 3) & 0x07; |
@@ -1460,7 +1512,8 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1460 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | 1512 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); |
1461 | 1513 | ||
1462 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 1514 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
1463 | /* The 8705 does not have VID capability */ | 1515 | /* The 8705 does not have VID capability. |
1516 | The 8718 does not use IT87_REG_VID for the same purpose. */ | ||
1464 | if (data->type == it8712 || data->type == it8716) { | 1517 | if (data->type == it8712 || data->type == it8716) { |
1465 | data->vid = it87_read_value(data, IT87_REG_VID); | 1518 | data->vid = it87_read_value(data, IT87_REG_VID); |
1466 | /* The older IT8712F revisions had only 5 VID pins, | 1519 | /* The older IT8712F revisions had only 5 VID pins, |
@@ -1529,6 +1582,7 @@ static int __init sm_it87_init(void) | |||
1529 | unsigned short isa_address=0; | 1582 | unsigned short isa_address=0; |
1530 | struct it87_sio_data sio_data; | 1583 | struct it87_sio_data sio_data; |
1531 | 1584 | ||
1585 | memset(&sio_data, 0, sizeof(struct it87_sio_data)); | ||
1532 | err = it87_find(&isa_address, &sio_data); | 1586 | err = it87_find(&isa_address, &sio_data); |
1533 | if (err) | 1587 | if (err) |
1534 | return err; | 1588 | return err; |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index de698dc73020..8f9595f2fb53 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -30,14 +30,37 @@ | |||
30 | #include "lm75.h" | 30 | #include "lm75.h" |
31 | 31 | ||
32 | 32 | ||
33 | /* Addresses to scan */ | 33 | /* |
34 | * This driver handles the LM75 and compatible digital temperature sensors. | ||
35 | * Only types which are _not_ listed in I2C_CLIENT_INSMOD_*() need to be | ||
36 | * listed here. We start at 9 since I2C_CLIENT_INSMOD_*() currently allow | ||
37 | * definition of up to 8 chip types (plus zero). | ||
38 | */ | ||
39 | |||
40 | enum lm75_type { /* keep sorted in alphabetical order */ | ||
41 | ds1775 = 9, | ||
42 | ds75, | ||
43 | /* lm75 -- in I2C_CLIENT_INSMOD_1() */ | ||
44 | lm75a, | ||
45 | max6625, | ||
46 | max6626, | ||
47 | mcp980x, | ||
48 | stds75, | ||
49 | tcn75, | ||
50 | tmp100, | ||
51 | tmp101, | ||
52 | tmp175, | ||
53 | tmp275, | ||
54 | tmp75, | ||
55 | }; | ||
56 | |||
57 | /* Addresses scanned */ | ||
34 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, | 58 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, |
35 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; | 59 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; |
36 | 60 | ||
37 | /* Insmod parameters */ | 61 | /* Insmod parameters */ |
38 | I2C_CLIENT_INSMOD_1(lm75); | 62 | I2C_CLIENT_INSMOD_1(lm75); |
39 | 63 | ||
40 | /* Many LM75 constants specified below */ | ||
41 | 64 | ||
42 | /* The LM75 registers */ | 65 | /* The LM75 registers */ |
43 | #define LM75_REG_CONF 0x01 | 66 | #define LM75_REG_CONF 0x01 |
@@ -49,10 +72,10 @@ static const u8 LM75_REG_TEMP[3] = { | |||
49 | 72 | ||
50 | /* Each client has this additional data */ | 73 | /* Each client has this additional data */ |
51 | struct lm75_data { | 74 | struct lm75_data { |
52 | struct i2c_client client; | 75 | struct device *hwmon_dev; |
53 | struct device *hwmon_dev; | ||
54 | struct mutex update_lock; | 76 | struct mutex update_lock; |
55 | char valid; /* !=0 if following fields are valid */ | 77 | u8 orig_conf; |
78 | char valid; /* !=0 if registers are valid */ | ||
56 | unsigned long last_updated; /* In jiffies */ | 79 | unsigned long last_updated; /* In jiffies */ |
57 | u16 temp[3]; /* Register values, | 80 | u16 temp[3]; /* Register values, |
58 | 0 = input | 81 | 0 = input |
@@ -60,23 +83,14 @@ struct lm75_data { | |||
60 | 2 = hyst */ | 83 | 2 = hyst */ |
61 | }; | 84 | }; |
62 | 85 | ||
63 | static int lm75_attach_adapter(struct i2c_adapter *adapter); | ||
64 | static int lm75_detect(struct i2c_adapter *adapter, int address, int kind); | ||
65 | static void lm75_init_client(struct i2c_client *client); | ||
66 | static int lm75_detach_client(struct i2c_client *client); | ||
67 | static int lm75_read_value(struct i2c_client *client, u8 reg); | 86 | static int lm75_read_value(struct i2c_client *client, u8 reg); |
68 | static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); | 87 | static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); |
69 | static struct lm75_data *lm75_update_device(struct device *dev); | 88 | static struct lm75_data *lm75_update_device(struct device *dev); |
70 | 89 | ||
71 | 90 | ||
72 | /* This is the driver that will be inserted */ | 91 | /*-----------------------------------------------------------------------*/ |
73 | static struct i2c_driver lm75_driver = { | 92 | |
74 | .driver = { | 93 | /* sysfs attributes for hwmon */ |
75 | .name = "lm75", | ||
76 | }, | ||
77 | .attach_adapter = lm75_attach_adapter, | ||
78 | .detach_client = lm75_detach_client, | ||
79 | }; | ||
80 | 94 | ||
81 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, | 95 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
82 | char *buf) | 96 | char *buf) |
@@ -109,13 +123,6 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | |||
109 | show_temp, set_temp, 2); | 123 | show_temp, set_temp, 2); |
110 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | 124 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); |
111 | 125 | ||
112 | static int lm75_attach_adapter(struct i2c_adapter *adapter) | ||
113 | { | ||
114 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
115 | return 0; | ||
116 | return i2c_probe(adapter, &addr_data, lm75_detect); | ||
117 | } | ||
118 | |||
119 | static struct attribute *lm75_attributes[] = { | 126 | static struct attribute *lm75_attributes[] = { |
120 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 127 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
121 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 128 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
@@ -128,33 +135,114 @@ static const struct attribute_group lm75_group = { | |||
128 | .attrs = lm75_attributes, | 135 | .attrs = lm75_attributes, |
129 | }; | 136 | }; |
130 | 137 | ||
131 | /* This function is called by i2c_probe */ | 138 | /*-----------------------------------------------------------------------*/ |
132 | static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) | 139 | |
140 | /* device probe and removal */ | ||
141 | |||
142 | static int | ||
143 | lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
133 | { | 144 | { |
134 | int i; | ||
135 | struct i2c_client *new_client; | ||
136 | struct lm75_data *data; | 145 | struct lm75_data *data; |
137 | int err = 0; | 146 | int status; |
138 | const char *name = ""; | 147 | u8 set_mask, clr_mask; |
148 | int new; | ||
139 | 149 | ||
140 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 150 | if (!i2c_check_functionality(client->adapter, |
141 | I2C_FUNC_SMBUS_WORD_DATA)) | 151 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) |
142 | goto exit; | 152 | return -EIO; |
143 | 153 | ||
144 | /* OK. For now, we presume we have a valid client. We now create the | 154 | data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL); |
145 | client structure, even though we cannot fill it completely yet. | 155 | if (!data) |
146 | But it allows us to access lm75_{read,write}_value. */ | 156 | return -ENOMEM; |
147 | if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) { | 157 | |
148 | err = -ENOMEM; | 158 | i2c_set_clientdata(client, data); |
149 | goto exit; | 159 | mutex_init(&data->update_lock); |
160 | |||
161 | /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. | ||
162 | * Then tweak to be more precise when appropriate. | ||
163 | */ | ||
164 | set_mask = 0; | ||
165 | clr_mask = (1 << 0) /* continuous conversions */ | ||
166 | | (1 << 6) | (1 << 5); /* 9-bit mode */ | ||
167 | |||
168 | /* configure as specified */ | ||
169 | status = lm75_read_value(client, LM75_REG_CONF); | ||
170 | if (status < 0) { | ||
171 | dev_dbg(&client->dev, "Can't read config? %d\n", status); | ||
172 | goto exit_free; | ||
150 | } | 173 | } |
174 | data->orig_conf = status; | ||
175 | new = status & ~clr_mask; | ||
176 | new |= set_mask; | ||
177 | if (status != new) | ||
178 | lm75_write_value(client, LM75_REG_CONF, new); | ||
179 | dev_dbg(&client->dev, "Config %02x\n", new); | ||
180 | |||
181 | /* Register sysfs hooks */ | ||
182 | status = sysfs_create_group(&client->dev.kobj, &lm75_group); | ||
183 | if (status) | ||
184 | goto exit_free; | ||
185 | |||
186 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
187 | if (IS_ERR(data->hwmon_dev)) { | ||
188 | status = PTR_ERR(data->hwmon_dev); | ||
189 | goto exit_remove; | ||
190 | } | ||
191 | |||
192 | dev_info(&client->dev, "%s: sensor '%s'\n", | ||
193 | data->hwmon_dev->bus_id, client->name); | ||
194 | |||
195 | return 0; | ||
196 | |||
197 | exit_remove: | ||
198 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | ||
199 | exit_free: | ||
200 | i2c_set_clientdata(client, NULL); | ||
201 | kfree(data); | ||
202 | return status; | ||
203 | } | ||
204 | |||
205 | static int lm75_remove(struct i2c_client *client) | ||
206 | { | ||
207 | struct lm75_data *data = i2c_get_clientdata(client); | ||
208 | |||
209 | hwmon_device_unregister(data->hwmon_dev); | ||
210 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | ||
211 | lm75_write_value(client, LM75_REG_CONF, data->orig_conf); | ||
212 | i2c_set_clientdata(client, NULL); | ||
213 | kfree(data); | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static const struct i2c_device_id lm75_ids[] = { | ||
218 | { "ds1775", ds1775, }, | ||
219 | { "ds75", ds75, }, | ||
220 | { "lm75", lm75, }, | ||
221 | { "lm75a", lm75a, }, | ||
222 | { "max6625", max6625, }, | ||
223 | { "max6626", max6626, }, | ||
224 | { "mcp980x", mcp980x, }, | ||
225 | { "stds75", stds75, }, | ||
226 | { "tcn75", tcn75, }, | ||
227 | { "tmp100", tmp100, }, | ||
228 | { "tmp101", tmp101, }, | ||
229 | { "tmp175", tmp175, }, | ||
230 | { "tmp275", tmp275, }, | ||
231 | { "tmp75", tmp75, }, | ||
232 | { /* LIST END */ } | ||
233 | }; | ||
234 | MODULE_DEVICE_TABLE(i2c, lm75_ids); | ||
235 | |||
236 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
237 | static int lm75_detect(struct i2c_client *new_client, int kind, | ||
238 | struct i2c_board_info *info) | ||
239 | { | ||
240 | struct i2c_adapter *adapter = new_client->adapter; | ||
241 | int i; | ||
151 | 242 | ||
152 | new_client = &data->client; | 243 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
153 | i2c_set_clientdata(new_client, data); | 244 | I2C_FUNC_SMBUS_WORD_DATA)) |
154 | new_client->addr = address; | 245 | return -ENODEV; |
155 | new_client->adapter = adapter; | ||
156 | new_client->driver = &lm75_driver; | ||
157 | new_client->flags = 0; | ||
158 | 246 | ||
159 | /* Now, we do the remaining detection. There is no identification- | 247 | /* Now, we do the remaining detection. There is no identification- |
160 | dedicated register so we have to rely on several tricks: | 248 | dedicated register so we have to rely on several tricks: |
@@ -174,77 +262,49 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) | |||
174 | || i2c_smbus_read_word_data(new_client, 5) != hyst | 262 | || i2c_smbus_read_word_data(new_client, 5) != hyst |
175 | || i2c_smbus_read_word_data(new_client, 6) != hyst | 263 | || i2c_smbus_read_word_data(new_client, 6) != hyst |
176 | || i2c_smbus_read_word_data(new_client, 7) != hyst) | 264 | || i2c_smbus_read_word_data(new_client, 7) != hyst) |
177 | goto exit_free; | 265 | return -ENODEV; |
178 | os = i2c_smbus_read_word_data(new_client, 3); | 266 | os = i2c_smbus_read_word_data(new_client, 3); |
179 | if (i2c_smbus_read_word_data(new_client, 4) != os | 267 | if (i2c_smbus_read_word_data(new_client, 4) != os |
180 | || i2c_smbus_read_word_data(new_client, 5) != os | 268 | || i2c_smbus_read_word_data(new_client, 5) != os |
181 | || i2c_smbus_read_word_data(new_client, 6) != os | 269 | || i2c_smbus_read_word_data(new_client, 6) != os |
182 | || i2c_smbus_read_word_data(new_client, 7) != os) | 270 | || i2c_smbus_read_word_data(new_client, 7) != os) |
183 | goto exit_free; | 271 | return -ENODEV; |
184 | 272 | ||
185 | /* Unused bits */ | 273 | /* Unused bits */ |
186 | if (conf & 0xe0) | 274 | if (conf & 0xe0) |
187 | goto exit_free; | 275 | return -ENODEV; |
188 | 276 | ||
189 | /* Addresses cycling */ | 277 | /* Addresses cycling */ |
190 | for (i = 8; i < 0xff; i += 8) | 278 | for (i = 8; i < 0xff; i += 8) |
191 | if (i2c_smbus_read_byte_data(new_client, i + 1) != conf | 279 | if (i2c_smbus_read_byte_data(new_client, i + 1) != conf |
192 | || i2c_smbus_read_word_data(new_client, i + 2) != hyst | 280 | || i2c_smbus_read_word_data(new_client, i + 2) != hyst |
193 | || i2c_smbus_read_word_data(new_client, i + 3) != os) | 281 | || i2c_smbus_read_word_data(new_client, i + 3) != os) |
194 | goto exit_free; | 282 | return -ENODEV; |
195 | } | 283 | } |
196 | 284 | ||
197 | /* Determine the chip type - only one kind supported! */ | 285 | /* NOTE: we treat "force=..." and "force_lm75=..." the same. |
198 | if (kind <= 0) | 286 | * Only new-style driver binding distinguishes chip types. |
199 | kind = lm75; | 287 | */ |
200 | 288 | strlcpy(info->type, "lm75", I2C_NAME_SIZE); | |
201 | if (kind == lm75) { | ||
202 | name = "lm75"; | ||
203 | } | ||
204 | |||
205 | /* Fill in the remaining client fields and put it into the global list */ | ||
206 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
207 | data->valid = 0; | ||
208 | mutex_init(&data->update_lock); | ||
209 | |||
210 | /* Tell the I2C layer a new client has arrived */ | ||
211 | if ((err = i2c_attach_client(new_client))) | ||
212 | goto exit_free; | ||
213 | |||
214 | /* Initialize the LM75 chip */ | ||
215 | lm75_init_client(new_client); | ||
216 | |||
217 | /* Register sysfs hooks */ | ||
218 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) | ||
219 | goto exit_detach; | ||
220 | |||
221 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
222 | if (IS_ERR(data->hwmon_dev)) { | ||
223 | err = PTR_ERR(data->hwmon_dev); | ||
224 | goto exit_remove; | ||
225 | } | ||
226 | 289 | ||
227 | return 0; | 290 | return 0; |
228 | |||
229 | exit_remove: | ||
230 | sysfs_remove_group(&new_client->dev.kobj, &lm75_group); | ||
231 | exit_detach: | ||
232 | i2c_detach_client(new_client); | ||
233 | exit_free: | ||
234 | kfree(data); | ||
235 | exit: | ||
236 | return err; | ||
237 | } | 291 | } |
238 | 292 | ||
239 | static int lm75_detach_client(struct i2c_client *client) | 293 | static struct i2c_driver lm75_driver = { |
240 | { | 294 | .class = I2C_CLASS_HWMON, |
241 | struct lm75_data *data = i2c_get_clientdata(client); | 295 | .driver = { |
242 | hwmon_device_unregister(data->hwmon_dev); | 296 | .name = "lm75", |
243 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | 297 | }, |
244 | i2c_detach_client(client); | 298 | .probe = lm75_probe, |
245 | kfree(data); | 299 | .remove = lm75_remove, |
246 | return 0; | 300 | .id_table = lm75_ids, |
247 | } | 301 | .detect = lm75_detect, |
302 | .address_data = &addr_data, | ||
303 | }; | ||
304 | |||
305 | /*-----------------------------------------------------------------------*/ | ||
306 | |||
307 | /* register access */ | ||
248 | 308 | ||
249 | /* All registers are word-sized, except for the configuration register. | 309 | /* All registers are word-sized, except for the configuration register. |
250 | LM75 uses a high-byte first convention, which is exactly opposite to | 310 | LM75 uses a high-byte first convention, which is exactly opposite to |
@@ -268,16 +328,6 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) | |||
268 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | 328 | return i2c_smbus_write_word_data(client, reg, swab16(value)); |
269 | } | 329 | } |
270 | 330 | ||
271 | static void lm75_init_client(struct i2c_client *client) | ||
272 | { | ||
273 | int reg; | ||
274 | |||
275 | /* Enable if in shutdown mode */ | ||
276 | reg = lm75_read_value(client, LM75_REG_CONF); | ||
277 | if (reg >= 0 && (reg & 0x01)) | ||
278 | lm75_write_value(client, LM75_REG_CONF, reg & 0xfe); | ||
279 | } | ||
280 | |||
281 | static struct lm75_data *lm75_update_device(struct device *dev) | 331 | static struct lm75_data *lm75_update_device(struct device *dev) |
282 | { | 332 | { |
283 | struct i2c_client *client = to_i2c_client(dev); | 333 | struct i2c_client *client = to_i2c_client(dev); |
@@ -309,6 +359,10 @@ static struct lm75_data *lm75_update_device(struct device *dev) | |||
309 | return data; | 359 | return data; |
310 | } | 360 | } |
311 | 361 | ||
362 | /*-----------------------------------------------------------------------*/ | ||
363 | |||
364 | /* module glue */ | ||
365 | |||
312 | static int __init sensors_lm75_init(void) | 366 | static int __init sensors_lm75_init(void) |
313 | { | 367 | { |
314 | return i2c_add_driver(&lm75_driver); | 368 | return i2c_add_driver(&lm75_driver); |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index ed7859f0e16a..b5e3b2851698 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -114,25 +114,16 @@ static inline int TEMP_FROM_REG(s8 val) | |||
114 | 114 | ||
115 | #define DIV_FROM_REG(val) (1 << (val)) | 115 | #define DIV_FROM_REG(val) (1 << (val)) |
116 | 116 | ||
117 | /* There are some complications in a module like this. First off, LM78 chips | ||
118 | may be both present on the SMBus and the ISA bus, and we have to handle | ||
119 | those cases separately at some places. Second, there might be several | ||
120 | LM78 chips available (well, actually, that is probably never done; but | ||
121 | it is a clean illustration of how to handle a case like that). Finally, | ||
122 | a specific chip may be attached to *both* ISA and SMBus, and we would | ||
123 | not like to detect it double. Fortunately, in the case of the LM78 at | ||
124 | least, a register tells us what SMBus address we are on, so that helps | ||
125 | a bit - except if there could be more than one SMBus. Groan. No solution | ||
126 | for this yet. */ | ||
127 | |||
128 | /* For ISA chips, we abuse the i2c_client addr and name fields. We also use | ||
129 | the driver field to differentiate between I2C and ISA chips. */ | ||
130 | struct lm78_data { | 117 | struct lm78_data { |
131 | struct i2c_client client; | 118 | struct i2c_client *client; |
132 | struct device *hwmon_dev; | 119 | struct device *hwmon_dev; |
133 | struct mutex lock; | 120 | struct mutex lock; |
134 | enum chips type; | 121 | enum chips type; |
135 | 122 | ||
123 | /* For ISA device only */ | ||
124 | const char *name; | ||
125 | int isa_addr; | ||
126 | |||
136 | struct mutex update_lock; | 127 | struct mutex update_lock; |
137 | char valid; /* !=0 if following fields are valid */ | 128 | char valid; /* !=0 if following fields are valid */ |
138 | unsigned long last_updated; /* In jiffies */ | 129 | unsigned long last_updated; /* In jiffies */ |
@@ -151,9 +142,11 @@ struct lm78_data { | |||
151 | }; | 142 | }; |
152 | 143 | ||
153 | 144 | ||
154 | static int lm78_attach_adapter(struct i2c_adapter *adapter); | 145 | static int lm78_i2c_detect(struct i2c_client *client, int kind, |
155 | static int lm78_detect(struct i2c_adapter *adapter, int address, int kind); | 146 | struct i2c_board_info *info); |
156 | static int lm78_detach_client(struct i2c_client *client); | 147 | static int lm78_i2c_probe(struct i2c_client *client, |
148 | const struct i2c_device_id *id); | ||
149 | static int lm78_i2c_remove(struct i2c_client *client); | ||
157 | 150 | ||
158 | static int __devinit lm78_isa_probe(struct platform_device *pdev); | 151 | static int __devinit lm78_isa_probe(struct platform_device *pdev); |
159 | static int __devexit lm78_isa_remove(struct platform_device *pdev); | 152 | static int __devexit lm78_isa_remove(struct platform_device *pdev); |
@@ -164,12 +157,23 @@ static struct lm78_data *lm78_update_device(struct device *dev); | |||
164 | static void lm78_init_device(struct lm78_data *data); | 157 | static void lm78_init_device(struct lm78_data *data); |
165 | 158 | ||
166 | 159 | ||
160 | static const struct i2c_device_id lm78_i2c_id[] = { | ||
161 | { "lm78", lm78 }, | ||
162 | { "lm79", lm79 }, | ||
163 | { } | ||
164 | }; | ||
165 | MODULE_DEVICE_TABLE(i2c, lm78_i2c_id); | ||
166 | |||
167 | static struct i2c_driver lm78_driver = { | 167 | static struct i2c_driver lm78_driver = { |
168 | .class = I2C_CLASS_HWMON, | ||
168 | .driver = { | 169 | .driver = { |
169 | .name = "lm78", | 170 | .name = "lm78", |
170 | }, | 171 | }, |
171 | .attach_adapter = lm78_attach_adapter, | 172 | .probe = lm78_i2c_probe, |
172 | .detach_client = lm78_detach_client, | 173 | .remove = lm78_i2c_remove, |
174 | .id_table = lm78_i2c_id, | ||
175 | .detect = lm78_i2c_detect, | ||
176 | .address_data = &addr_data, | ||
173 | }; | 177 | }; |
174 | 178 | ||
175 | static struct platform_driver lm78_isa_driver = { | 179 | static struct platform_driver lm78_isa_driver = { |
@@ -454,17 +458,6 @@ static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | |||
454 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); | 458 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); |
455 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); | 459 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); |
456 | 460 | ||
457 | /* This function is called when: | ||
458 | * lm78_driver is inserted (when this module is loaded), for each | ||
459 | available adapter | ||
460 | * when a new adapter is inserted (and lm78_driver is still present) */ | ||
461 | static int lm78_attach_adapter(struct i2c_adapter *adapter) | ||
462 | { | ||
463 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
464 | return 0; | ||
465 | return i2c_probe(adapter, &addr_data, lm78_detect); | ||
466 | } | ||
467 | |||
468 | static struct attribute *lm78_attributes[] = { | 461 | static struct attribute *lm78_attributes[] = { |
469 | &sensor_dev_attr_in0_input.dev_attr.attr, | 462 | &sensor_dev_attr_in0_input.dev_attr.attr, |
470 | &sensor_dev_attr_in0_min.dev_attr.attr, | 463 | &sensor_dev_attr_in0_min.dev_attr.attr, |
@@ -527,54 +520,77 @@ static ssize_t show_name(struct device *dev, struct device_attribute | |||
527 | { | 520 | { |
528 | struct lm78_data *data = dev_get_drvdata(dev); | 521 | struct lm78_data *data = dev_get_drvdata(dev); |
529 | 522 | ||
530 | return sprintf(buf, "%s\n", data->client.name); | 523 | return sprintf(buf, "%s\n", data->name); |
531 | } | 524 | } |
532 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 525 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
533 | 526 | ||
534 | /* This function is called by i2c_probe */ | 527 | /* Returns 1 if the I2C chip appears to be an alias of the ISA chip */ |
535 | static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | 528 | static int lm78_alias_detect(struct i2c_client *client, u8 chipid) |
536 | { | 529 | { |
537 | int i, err; | 530 | struct lm78_data *isa; |
538 | struct i2c_client *new_client; | 531 | int i; |
539 | struct lm78_data *data; | ||
540 | const char *client_name = ""; | ||
541 | 532 | ||
542 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 533 | if (!pdev) /* No ISA chip */ |
543 | err = -ENODEV; | 534 | return 0; |
544 | goto ERROR1; | 535 | isa = platform_get_drvdata(pdev); |
536 | |||
537 | if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr) | ||
538 | return 0; /* Address doesn't match */ | ||
539 | if ((lm78_read_value(isa, LM78_REG_CHIPID) & 0xfe) != (chipid & 0xfe)) | ||
540 | return 0; /* Chip type doesn't match */ | ||
541 | |||
542 | /* We compare all the limit registers, the config register and the | ||
543 | * interrupt mask registers */ | ||
544 | for (i = 0x2b; i <= 0x3d; i++) { | ||
545 | if (lm78_read_value(isa, i) != | ||
546 | i2c_smbus_read_byte_data(client, i)) | ||
547 | return 0; | ||
545 | } | 548 | } |
549 | if (lm78_read_value(isa, LM78_REG_CONFIG) != | ||
550 | i2c_smbus_read_byte_data(client, LM78_REG_CONFIG)) | ||
551 | return 0; | ||
552 | for (i = 0x43; i <= 0x46; i++) { | ||
553 | if (lm78_read_value(isa, i) != | ||
554 | i2c_smbus_read_byte_data(client, i)) | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | return 1; | ||
559 | } | ||
546 | 560 | ||
547 | /* OK. For now, we presume we have a valid client. We now create the | 561 | static int lm78_i2c_detect(struct i2c_client *client, int kind, |
548 | client structure, even though we cannot fill it completely yet. | 562 | struct i2c_board_info *info) |
549 | But it allows us to access lm78_{read,write}_value. */ | 563 | { |
564 | int i; | ||
565 | struct lm78_data *isa = pdev ? platform_get_drvdata(pdev) : NULL; | ||
566 | const char *client_name; | ||
567 | struct i2c_adapter *adapter = client->adapter; | ||
568 | int address = client->addr; | ||
550 | 569 | ||
551 | if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) { | 570 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
552 | err = -ENOMEM; | 571 | return -ENODEV; |
553 | goto ERROR1; | ||
554 | } | ||
555 | 572 | ||
556 | new_client = &data->client; | 573 | /* We block updates of the ISA device to minimize the risk of |
557 | i2c_set_clientdata(new_client, data); | 574 | concurrent access to the same LM78 chip through different |
558 | new_client->addr = address; | 575 | interfaces. */ |
559 | new_client->adapter = adapter; | 576 | if (isa) |
560 | new_client->driver = &lm78_driver; | 577 | mutex_lock(&isa->update_lock); |
561 | 578 | ||
562 | /* Now, we do the remaining detection. */ | ||
563 | if (kind < 0) { | 579 | if (kind < 0) { |
564 | if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) { | 580 | if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80) |
565 | err = -ENODEV; | 581 | || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) |
566 | goto ERROR2; | 582 | != address) |
567 | } | 583 | goto err_nodev; |
568 | if (lm78_read_value(data, LM78_REG_I2C_ADDR) != | 584 | |
569 | address) { | 585 | /* Explicitly prevent the misdetection of Winbond chips */ |
570 | err = -ENODEV; | 586 | i = i2c_smbus_read_byte_data(client, 0x4f); |
571 | goto ERROR2; | 587 | if (i == 0xa3 || i == 0x5c) |
572 | } | 588 | goto err_nodev; |
573 | } | 589 | } |
574 | 590 | ||
575 | /* Determine the chip type. */ | 591 | /* Determine the chip type. */ |
576 | if (kind <= 0) { | 592 | if (kind <= 0) { |
577 | i = lm78_read_value(data, LM78_REG_CHIPID); | 593 | i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID); |
578 | if (i == 0x00 || i == 0x20 /* LM78 */ | 594 | if (i == 0x00 || i == 0x20 /* LM78 */ |
579 | || i == 0x40) /* LM78-J */ | 595 | || i == 0x40) /* LM78-J */ |
580 | kind = lm78; | 596 | kind = lm78; |
@@ -586,33 +602,59 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
586 | "parameter for unknown chip at " | 602 | "parameter for unknown chip at " |
587 | "adapter %d, address 0x%02x\n", | 603 | "adapter %d, address 0x%02x\n", |
588 | i2c_adapter_id(adapter), address); | 604 | i2c_adapter_id(adapter), address); |
589 | err = -ENODEV; | 605 | goto err_nodev; |
590 | goto ERROR2; | 606 | } |
607 | |||
608 | if (lm78_alias_detect(client, i)) { | ||
609 | dev_dbg(&adapter->dev, "Device at 0x%02x appears to " | ||
610 | "be the same as ISA device\n", address); | ||
611 | goto err_nodev; | ||
591 | } | 612 | } |
592 | } | 613 | } |
593 | 614 | ||
594 | if (kind == lm78) { | 615 | if (isa) |
595 | client_name = "lm78"; | 616 | mutex_unlock(&isa->update_lock); |
596 | } else if (kind == lm79) { | 617 | |
618 | switch (kind) { | ||
619 | case lm79: | ||
597 | client_name = "lm79"; | 620 | client_name = "lm79"; |
621 | break; | ||
622 | default: | ||
623 | client_name = "lm78"; | ||
598 | } | 624 | } |
625 | strlcpy(info->type, client_name, I2C_NAME_SIZE); | ||
626 | |||
627 | return 0; | ||
628 | |||
629 | err_nodev: | ||
630 | if (isa) | ||
631 | mutex_unlock(&isa->update_lock); | ||
632 | return -ENODEV; | ||
633 | } | ||
634 | |||
635 | static int lm78_i2c_probe(struct i2c_client *client, | ||
636 | const struct i2c_device_id *id) | ||
637 | { | ||
638 | struct lm78_data *data; | ||
639 | int err; | ||
599 | 640 | ||
600 | /* Fill in the remaining client fields and put into the global list */ | 641 | data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL); |
601 | strlcpy(new_client->name, client_name, I2C_NAME_SIZE); | 642 | if (!data) |
602 | data->type = kind; | 643 | return -ENOMEM; |
603 | 644 | ||
604 | /* Tell the I2C layer a new client has arrived */ | 645 | i2c_set_clientdata(client, data); |
605 | if ((err = i2c_attach_client(new_client))) | 646 | data->client = client; |
606 | goto ERROR2; | 647 | data->type = id->driver_data; |
607 | 648 | ||
608 | /* Initialize the LM78 chip */ | 649 | /* Initialize the LM78 chip */ |
609 | lm78_init_device(data); | 650 | lm78_init_device(data); |
610 | 651 | ||
611 | /* Register sysfs hooks */ | 652 | /* Register sysfs hooks */ |
612 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) | 653 | err = sysfs_create_group(&client->dev.kobj, &lm78_group); |
654 | if (err) | ||
613 | goto ERROR3; | 655 | goto ERROR3; |
614 | 656 | ||
615 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 657 | data->hwmon_dev = hwmon_device_register(&client->dev); |
616 | if (IS_ERR(data->hwmon_dev)) { | 658 | if (IS_ERR(data->hwmon_dev)) { |
617 | err = PTR_ERR(data->hwmon_dev); | 659 | err = PTR_ERR(data->hwmon_dev); |
618 | goto ERROR4; | 660 | goto ERROR4; |
@@ -621,26 +663,18 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
621 | return 0; | 663 | return 0; |
622 | 664 | ||
623 | ERROR4: | 665 | ERROR4: |
624 | sysfs_remove_group(&new_client->dev.kobj, &lm78_group); | 666 | sysfs_remove_group(&client->dev.kobj, &lm78_group); |
625 | ERROR3: | 667 | ERROR3: |
626 | i2c_detach_client(new_client); | ||
627 | ERROR2: | ||
628 | kfree(data); | 668 | kfree(data); |
629 | ERROR1: | ||
630 | return err; | 669 | return err; |
631 | } | 670 | } |
632 | 671 | ||
633 | static int lm78_detach_client(struct i2c_client *client) | 672 | static int lm78_i2c_remove(struct i2c_client *client) |
634 | { | 673 | { |
635 | struct lm78_data *data = i2c_get_clientdata(client); | 674 | struct lm78_data *data = i2c_get_clientdata(client); |
636 | int err; | ||
637 | 675 | ||
638 | hwmon_device_unregister(data->hwmon_dev); | 676 | hwmon_device_unregister(data->hwmon_dev); |
639 | sysfs_remove_group(&client->dev.kobj, &lm78_group); | 677 | sysfs_remove_group(&client->dev.kobj, &lm78_group); |
640 | |||
641 | if ((err = i2c_detach_client(client))) | ||
642 | return err; | ||
643 | |||
644 | kfree(data); | 678 | kfree(data); |
645 | 679 | ||
646 | return 0; | 680 | return 0; |
@@ -651,11 +685,10 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
651 | int err; | 685 | int err; |
652 | struct lm78_data *data; | 686 | struct lm78_data *data; |
653 | struct resource *res; | 687 | struct resource *res; |
654 | const char *name; | ||
655 | 688 | ||
656 | /* Reserve the ISA region */ | 689 | /* Reserve the ISA region */ |
657 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 690 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
658 | if (!request_region(res->start, LM78_EXTENT, "lm78")) { | 691 | if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) { |
659 | err = -EBUSY; | 692 | err = -EBUSY; |
660 | goto exit; | 693 | goto exit; |
661 | } | 694 | } |
@@ -665,18 +698,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
665 | goto exit_release_region; | 698 | goto exit_release_region; |
666 | } | 699 | } |
667 | mutex_init(&data->lock); | 700 | mutex_init(&data->lock); |
668 | data->client.addr = res->start; | 701 | data->isa_addr = res->start; |
669 | i2c_set_clientdata(&data->client, data); | ||
670 | platform_set_drvdata(pdev, data); | 702 | platform_set_drvdata(pdev, data); |
671 | 703 | ||
672 | if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) { | 704 | if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) { |
673 | data->type = lm79; | 705 | data->type = lm79; |
674 | name = "lm79"; | 706 | data->name = "lm79"; |
675 | } else { | 707 | } else { |
676 | data->type = lm78; | 708 | data->type = lm78; |
677 | name = "lm78"; | 709 | data->name = "lm78"; |
678 | } | 710 | } |
679 | strlcpy(data->client.name, name, I2C_NAME_SIZE); | ||
680 | 711 | ||
681 | /* Initialize the LM78 chip */ | 712 | /* Initialize the LM78 chip */ |
682 | lm78_init_device(data); | 713 | lm78_init_device(data); |
@@ -699,7 +730,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
699 | device_remove_file(&pdev->dev, &dev_attr_name); | 730 | device_remove_file(&pdev->dev, &dev_attr_name); |
700 | kfree(data); | 731 | kfree(data); |
701 | exit_release_region: | 732 | exit_release_region: |
702 | release_region(res->start, LM78_EXTENT); | 733 | release_region(res->start + LM78_ADDR_REG_OFFSET, 2); |
703 | exit: | 734 | exit: |
704 | return err; | 735 | return err; |
705 | } | 736 | } |
@@ -707,13 +738,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
707 | static int __devexit lm78_isa_remove(struct platform_device *pdev) | 738 | static int __devexit lm78_isa_remove(struct platform_device *pdev) |
708 | { | 739 | { |
709 | struct lm78_data *data = platform_get_drvdata(pdev); | 740 | struct lm78_data *data = platform_get_drvdata(pdev); |
741 | struct resource *res; | ||
710 | 742 | ||
711 | hwmon_device_unregister(data->hwmon_dev); | 743 | hwmon_device_unregister(data->hwmon_dev); |
712 | sysfs_remove_group(&pdev->dev.kobj, &lm78_group); | 744 | sysfs_remove_group(&pdev->dev.kobj, &lm78_group); |
713 | device_remove_file(&pdev->dev, &dev_attr_name); | 745 | device_remove_file(&pdev->dev, &dev_attr_name); |
714 | release_region(data->client.addr, LM78_EXTENT); | ||
715 | kfree(data); | 746 | kfree(data); |
716 | 747 | ||
748 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
749 | release_region(res->start + LM78_ADDR_REG_OFFSET, 2); | ||
750 | |||
717 | return 0; | 751 | return 0; |
718 | } | 752 | } |
719 | 753 | ||
@@ -724,13 +758,13 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev) | |||
724 | would slow down the LM78 access and should not be necessary. */ | 758 | would slow down the LM78 access and should not be necessary. */ |
725 | static int lm78_read_value(struct lm78_data *data, u8 reg) | 759 | static int lm78_read_value(struct lm78_data *data, u8 reg) |
726 | { | 760 | { |
727 | struct i2c_client *client = &data->client; | 761 | struct i2c_client *client = data->client; |
728 | 762 | ||
729 | if (!client->driver) { /* ISA device */ | 763 | if (!client) { /* ISA device */ |
730 | int res; | 764 | int res; |
731 | mutex_lock(&data->lock); | 765 | mutex_lock(&data->lock); |
732 | outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); | 766 | outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); |
733 | res = inb_p(client->addr + LM78_DATA_REG_OFFSET); | 767 | res = inb_p(data->isa_addr + LM78_DATA_REG_OFFSET); |
734 | mutex_unlock(&data->lock); | 768 | mutex_unlock(&data->lock); |
735 | return res; | 769 | return res; |
736 | } else | 770 | } else |
@@ -746,12 +780,12 @@ static int lm78_read_value(struct lm78_data *data, u8 reg) | |||
746 | nowhere else be necessary! */ | 780 | nowhere else be necessary! */ |
747 | static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) | 781 | static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) |
748 | { | 782 | { |
749 | struct i2c_client *client = &data->client; | 783 | struct i2c_client *client = data->client; |
750 | 784 | ||
751 | if (!client->driver) { /* ISA device */ | 785 | if (!client) { /* ISA device */ |
752 | mutex_lock(&data->lock); | 786 | mutex_lock(&data->lock); |
753 | outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); | 787 | outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); |
754 | outb_p(value, client->addr + LM78_DATA_REG_OFFSET); | 788 | outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET); |
755 | mutex_unlock(&data->lock); | 789 | mutex_unlock(&data->lock); |
756 | return 0; | 790 | return 0; |
757 | } else | 791 | } else |
@@ -837,8 +871,17 @@ static int __init lm78_isa_found(unsigned short address) | |||
837 | { | 871 | { |
838 | int val, save, found = 0; | 872 | int val, save, found = 0; |
839 | 873 | ||
840 | if (!request_region(address, LM78_EXTENT, "lm78")) | 874 | /* We have to request the region in two parts because some |
875 | boards declare base+4 to base+7 as a PNP device */ | ||
876 | if (!request_region(address, 4, "lm78")) { | ||
877 | pr_debug("lm78: Failed to request low part of region\n"); | ||
841 | return 0; | 878 | return 0; |
879 | } | ||
880 | if (!request_region(address + 4, 4, "lm78")) { | ||
881 | pr_debug("lm78: Failed to request high part of region\n"); | ||
882 | release_region(address, 4); | ||
883 | return 0; | ||
884 | } | ||
842 | 885 | ||
843 | #define REALLY_SLOW_IO | 886 | #define REALLY_SLOW_IO |
844 | /* We need the timeouts for at least some LM78-like | 887 | /* We need the timeouts for at least some LM78-like |
@@ -901,7 +944,8 @@ static int __init lm78_isa_found(unsigned short address) | |||
901 | val & 0x80 ? "LM79" : "LM78", (int)address); | 944 | val & 0x80 ? "LM79" : "LM78", (int)address); |
902 | 945 | ||
903 | release: | 946 | release: |
904 | release_region(address, LM78_EXTENT); | 947 | release_region(address + 4, 4); |
948 | release_region(address, 4); | ||
905 | return found; | 949 | return found; |
906 | } | 950 | } |
907 | 951 | ||
@@ -949,14 +993,12 @@ static int __init sm_lm78_init(void) | |||
949 | { | 993 | { |
950 | int res; | 994 | int res; |
951 | 995 | ||
952 | res = i2c_add_driver(&lm78_driver); | 996 | /* We register the ISA device first, so that we can skip the |
953 | if (res) | 997 | * registration of an I2C interface to the same device. */ |
954 | goto exit; | ||
955 | |||
956 | if (lm78_isa_found(isa_address)) { | 998 | if (lm78_isa_found(isa_address)) { |
957 | res = platform_driver_register(&lm78_isa_driver); | 999 | res = platform_driver_register(&lm78_isa_driver); |
958 | if (res) | 1000 | if (res) |
959 | goto exit_unreg_i2c_driver; | 1001 | goto exit; |
960 | 1002 | ||
961 | /* Sets global pdev as a side effect */ | 1003 | /* Sets global pdev as a side effect */ |
962 | res = lm78_isa_device_add(isa_address); | 1004 | res = lm78_isa_device_add(isa_address); |
@@ -964,12 +1006,16 @@ static int __init sm_lm78_init(void) | |||
964 | goto exit_unreg_isa_driver; | 1006 | goto exit_unreg_isa_driver; |
965 | } | 1007 | } |
966 | 1008 | ||
1009 | res = i2c_add_driver(&lm78_driver); | ||
1010 | if (res) | ||
1011 | goto exit_unreg_isa_device; | ||
1012 | |||
967 | return 0; | 1013 | return 0; |
968 | 1014 | ||
1015 | exit_unreg_isa_device: | ||
1016 | platform_device_unregister(pdev); | ||
969 | exit_unreg_isa_driver: | 1017 | exit_unreg_isa_driver: |
970 | platform_driver_unregister(&lm78_isa_driver); | 1018 | platform_driver_unregister(&lm78_isa_driver); |
971 | exit_unreg_i2c_driver: | ||
972 | i2c_del_driver(&lm78_driver); | ||
973 | exit: | 1019 | exit: |
974 | return res; | 1020 | return res; |
975 | } | 1021 | } |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index ee5eca1c1921..3ff0285396fa 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | lm85.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | lm85.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | 4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> |
5 | Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> | 5 | Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> |
6 | Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> | 6 | Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> |
7 | Copyright (c) 2004 Justin Thiessen <jthiessen@penguincomputing.com> | 7 | Copyright (c) 2004 Justin Thiessen <jthiessen@penguincomputing.com> |
8 | Copyright (C) 2007, 2008 Jean Delvare <khali@linux-fr.org> | ||
8 | 9 | ||
9 | Chip details at <http://www.national.com/ds/LM/LM85.pdf> | 10 | Chip details at <http://www.national.com/ds/LM/LM85.pdf> |
10 | 11 | ||
@@ -51,24 +52,17 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
51 | #define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) | 52 | #define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) |
52 | 53 | ||
53 | /* Fan speeds are LSB, MSB (2 bytes) */ | 54 | /* Fan speeds are LSB, MSB (2 bytes) */ |
54 | #define LM85_REG_FAN(nr) (0x28 + (nr) *2) | 55 | #define LM85_REG_FAN(nr) (0x28 + (nr) * 2) |
55 | #define LM85_REG_FAN_MIN(nr) (0x54 + (nr) *2) | 56 | #define LM85_REG_FAN_MIN(nr) (0x54 + (nr) * 2) |
56 | 57 | ||
57 | #define LM85_REG_PWM(nr) (0x30 + (nr)) | 58 | #define LM85_REG_PWM(nr) (0x30 + (nr)) |
58 | 59 | ||
59 | #define ADT7463_REG_OPPOINT(nr) (0x33 + (nr)) | ||
60 | |||
61 | #define ADT7463_REG_TMIN_CTL1 0x36 | ||
62 | #define ADT7463_REG_TMIN_CTL2 0x37 | ||
63 | |||
64 | #define LM85_REG_DEVICE 0x3d | ||
65 | #define LM85_REG_COMPANY 0x3e | 60 | #define LM85_REG_COMPANY 0x3e |
66 | #define LM85_REG_VERSTEP 0x3f | 61 | #define LM85_REG_VERSTEP 0x3f |
67 | /* These are the recognized values for the above regs */ | 62 | /* These are the recognized values for the above regs */ |
68 | #define LM85_DEVICE_ADX 0x27 | ||
69 | #define LM85_COMPANY_NATIONAL 0x01 | 63 | #define LM85_COMPANY_NATIONAL 0x01 |
70 | #define LM85_COMPANY_ANALOG_DEV 0x41 | 64 | #define LM85_COMPANY_ANALOG_DEV 0x41 |
71 | #define LM85_COMPANY_SMSC 0x5c | 65 | #define LM85_COMPANY_SMSC 0x5c |
72 | #define LM85_VERSTEP_VMASK 0xf0 | 66 | #define LM85_VERSTEP_VMASK 0xf0 |
73 | #define LM85_VERSTEP_GENERIC 0x60 | 67 | #define LM85_VERSTEP_GENERIC 0x60 |
74 | #define LM85_VERSTEP_LM85C 0x60 | 68 | #define LM85_VERSTEP_LM85C 0x60 |
@@ -91,58 +85,45 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
91 | #define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) | 85 | #define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) |
92 | #define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) | 86 | #define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) |
93 | #define LM85_REG_AFAN_SPIKE1 0x62 | 87 | #define LM85_REG_AFAN_SPIKE1 0x62 |
94 | #define LM85_REG_AFAN_SPIKE2 0x63 | ||
95 | #define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) | 88 | #define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) |
96 | #define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) | 89 | #define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) |
97 | #define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) | 90 | #define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) |
98 | #define LM85_REG_AFAN_HYST1 0x6d | 91 | #define LM85_REG_AFAN_HYST1 0x6d |
99 | #define LM85_REG_AFAN_HYST2 0x6e | 92 | #define LM85_REG_AFAN_HYST2 0x6e |
100 | 93 | ||
101 | #define LM85_REG_TACH_MODE 0x74 | ||
102 | #define LM85_REG_SPINUP_CTL 0x75 | ||
103 | |||
104 | #define ADM1027_REG_TEMP_OFFSET(nr) (0x70 + (nr)) | ||
105 | #define ADM1027_REG_CONFIG2 0x73 | ||
106 | #define ADM1027_REG_INTMASK1 0x74 | ||
107 | #define ADM1027_REG_INTMASK2 0x75 | ||
108 | #define ADM1027_REG_EXTEND_ADC1 0x76 | 94 | #define ADM1027_REG_EXTEND_ADC1 0x76 |
109 | #define ADM1027_REG_EXTEND_ADC2 0x77 | 95 | #define ADM1027_REG_EXTEND_ADC2 0x77 |
110 | #define ADM1027_REG_CONFIG3 0x78 | ||
111 | #define ADM1027_REG_FAN_PPR 0x7b | ||
112 | |||
113 | #define ADT7463_REG_THERM 0x79 | ||
114 | #define ADT7463_REG_THERM_LIMIT 0x7A | ||
115 | 96 | ||
116 | #define EMC6D100_REG_ALARM3 0x7d | 97 | #define EMC6D100_REG_ALARM3 0x7d |
117 | /* IN5, IN6 and IN7 */ | 98 | /* IN5, IN6 and IN7 */ |
118 | #define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5)) | 99 | #define EMC6D100_REG_IN(nr) (0x70 + ((nr) - 5)) |
119 | #define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2) | 100 | #define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr) - 5) * 2) |
120 | #define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2) | 101 | #define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr) - 5) * 2) |
121 | #define EMC6D102_REG_EXTEND_ADC1 0x85 | 102 | #define EMC6D102_REG_EXTEND_ADC1 0x85 |
122 | #define EMC6D102_REG_EXTEND_ADC2 0x86 | 103 | #define EMC6D102_REG_EXTEND_ADC2 0x86 |
123 | #define EMC6D102_REG_EXTEND_ADC3 0x87 | 104 | #define EMC6D102_REG_EXTEND_ADC3 0x87 |
124 | #define EMC6D102_REG_EXTEND_ADC4 0x88 | 105 | #define EMC6D102_REG_EXTEND_ADC4 0x88 |
125 | 106 | ||
126 | 107 | ||
127 | /* Conversions. Rounding and limit checking is only done on the TO_REG | 108 | /* Conversions. Rounding and limit checking is only done on the TO_REG |
128 | variants. Note that you should be a bit careful with which arguments | 109 | variants. Note that you should be a bit careful with which arguments |
129 | these macros are called: arguments may be evaluated more than once. | 110 | these macros are called: arguments may be evaluated more than once. |
130 | */ | 111 | */ |
131 | 112 | ||
132 | /* IN are scaled acording to built-in resistors */ | 113 | /* IN are scaled acording to built-in resistors */ |
133 | static int lm85_scaling[] = { /* .001 Volts */ | 114 | static const int lm85_scaling[] = { /* .001 Volts */ |
134 | 2500, 2250, 3300, 5000, 12000, | 115 | 2500, 2250, 3300, 5000, 12000, |
135 | 3300, 1500, 1800 /*EMC6D100*/ | 116 | 3300, 1500, 1800 /*EMC6D100*/ |
136 | }; | 117 | }; |
137 | #define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from)) | 118 | #define SCALE(val, from, to) (((val) * (to) + ((from) / 2)) / (from)) |
138 | 119 | ||
139 | #define INS_TO_REG(n,val) \ | 120 | #define INS_TO_REG(n, val) \ |
140 | SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255) | 121 | SENSORS_LIMIT(SCALE(val, lm85_scaling[n], 192), 0, 255) |
141 | 122 | ||
142 | #define INSEXT_FROM_REG(n,val,ext) \ | 123 | #define INSEXT_FROM_REG(n, val, ext) \ |
143 | SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n]) | 124 | SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n]) |
144 | 125 | ||
145 | #define INS_FROM_REG(n,val) SCALE((val), 192, lm85_scaling[n]) | 126 | #define INS_FROM_REG(n, val) SCALE((val), 192, lm85_scaling[n]) |
146 | 127 | ||
147 | /* FAN speed is measured using 90kHz clock */ | 128 | /* FAN speed is measured using 90kHz clock */ |
148 | static inline u16 FAN_TO_REG(unsigned long val) | 129 | static inline u16 FAN_TO_REG(unsigned long val) |
@@ -151,16 +132,17 @@ static inline u16 FAN_TO_REG(unsigned long val) | |||
151 | return 0xffff; | 132 | return 0xffff; |
152 | return SENSORS_LIMIT(5400000 / val, 1, 0xfffe); | 133 | return SENSORS_LIMIT(5400000 / val, 1, 0xfffe); |
153 | } | 134 | } |
154 | #define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) | 135 | #define FAN_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \ |
136 | 5400000 / (val)) | ||
155 | 137 | ||
156 | /* Temperature is reported in .001 degC increments */ | 138 | /* Temperature is reported in .001 degC increments */ |
157 | #define TEMP_TO_REG(val) \ | 139 | #define TEMP_TO_REG(val) \ |
158 | SENSORS_LIMIT(SCALE(val,1000,1),-127,127) | 140 | SENSORS_LIMIT(SCALE(val, 1000, 1), -127, 127) |
159 | #define TEMPEXT_FROM_REG(val,ext) \ | 141 | #define TEMPEXT_FROM_REG(val, ext) \ |
160 | SCALE(((val) << 4) + (ext), 16, 1000) | 142 | SCALE(((val) << 4) + (ext), 16, 1000) |
161 | #define TEMP_FROM_REG(val) ((val) * 1000) | 143 | #define TEMP_FROM_REG(val) ((val) * 1000) |
162 | 144 | ||
163 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) | 145 | #define PWM_TO_REG(val) SENSORS_LIMIT(val, 0, 255) |
164 | #define PWM_FROM_REG(val) (val) | 146 | #define PWM_FROM_REG(val) (val) |
165 | 147 | ||
166 | 148 | ||
@@ -183,52 +165,48 @@ static inline u16 FAN_TO_REG(unsigned long val) | |||
183 | */ | 165 | */ |
184 | 166 | ||
185 | /* These are the zone temperature range encodings in .001 degree C */ | 167 | /* These are the zone temperature range encodings in .001 degree C */ |
186 | static int lm85_range_map[] = { | 168 | static const int lm85_range_map[] = { |
187 | 2000, 2500, 3300, 4000, 5000, 6600, | 169 | 2000, 2500, 3300, 4000, 5000, 6600, 8000, 10000, |
188 | 8000, 10000, 13300, 16000, 20000, 26600, | 170 | 13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000 |
189 | 32000, 40000, 53300, 80000 | 171 | }; |
190 | }; | 172 | |
191 | static int RANGE_TO_REG( int range ) | 173 | static int RANGE_TO_REG(int range) |
192 | { | 174 | { |
193 | int i; | 175 | int i; |
194 | 176 | ||
195 | if (range >= lm85_range_map[15]) | ||
196 | return 15 ; | ||
197 | |||
198 | /* Find the closest match */ | 177 | /* Find the closest match */ |
199 | for (i = 14; i >= 0; --i) { | 178 | for (i = 0; i < 15; ++i) { |
200 | if (range >= lm85_range_map[i]) { | 179 | if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2) |
201 | if ((lm85_range_map[i + 1] - range) < | 180 | break; |
202 | (range - lm85_range_map[i])) | ||
203 | return i + 1; | ||
204 | return i; | ||
205 | } | ||
206 | } | 181 | } |
207 | 182 | ||
208 | return 0; | 183 | return i; |
209 | } | 184 | } |
210 | #define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f]) | 185 | #define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f] |
211 | 186 | ||
212 | /* These are the Acoustic Enhancement, or Temperature smoothing encodings | ||
213 | * NOTE: The enable/disable bit is INCLUDED in these encodings as the | ||
214 | * MSB (bit 3, value 8). If the enable bit is 0, the encoded value | ||
215 | * is ignored, or set to 0. | ||
216 | */ | ||
217 | /* These are the PWM frequency encodings */ | 187 | /* These are the PWM frequency encodings */ |
218 | static int lm85_freq_map[] = { /* .1 Hz */ | 188 | static const int lm85_freq_map[8] = { /* 1 Hz */ |
219 | 100, 150, 230, 300, 380, 470, 620, 940 | 189 | 10, 15, 23, 30, 38, 47, 61, 94 |
220 | }; | 190 | }; |
221 | static int FREQ_TO_REG( int freq ) | 191 | static const int adm1027_freq_map[8] = { /* 1 Hz */ |
192 | 11, 15, 22, 29, 35, 44, 59, 88 | ||
193 | }; | ||
194 | |||
195 | static int FREQ_TO_REG(const int *map, int freq) | ||
222 | { | 196 | { |
223 | int i; | 197 | int i; |
224 | 198 | ||
225 | if( freq >= lm85_freq_map[7] ) { return 7 ; } | 199 | /* Find the closest match */ |
226 | for( i = 0 ; i < 7 ; ++i ) | 200 | for (i = 0; i < 7; ++i) |
227 | if( freq <= lm85_freq_map[i] ) | 201 | if (freq <= (map[i] + map[i + 1]) / 2) |
228 | break ; | 202 | break; |
229 | return( i & 0x07 ); | 203 | return i; |
204 | } | ||
205 | |||
206 | static int FREQ_FROM_REG(const int *map, u8 reg) | ||
207 | { | ||
208 | return map[reg & 0x07]; | ||
230 | } | 209 | } |
231 | #define FREQ_FROM_REG(val) (lm85_freq_map[(val)&0x07]) | ||
232 | 210 | ||
233 | /* Since we can't use strings, I'm abusing these numbers | 211 | /* Since we can't use strings, I'm abusing these numbers |
234 | * to stand in for the following meanings: | 212 | * to stand in for the following meanings: |
@@ -242,30 +220,23 @@ static int FREQ_TO_REG( int freq ) | |||
242 | * -2 -- PWM responds to manual control | 220 | * -2 -- PWM responds to manual control |
243 | */ | 221 | */ |
244 | 222 | ||
245 | static int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 }; | 223 | static const int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 }; |
246 | #define ZONE_FROM_REG(val) (lm85_zone_map[((val)>>5)&0x07]) | 224 | #define ZONE_FROM_REG(val) lm85_zone_map[(val) >> 5] |
247 | 225 | ||
248 | static int ZONE_TO_REG( int zone ) | 226 | static int ZONE_TO_REG(int zone) |
249 | { | 227 | { |
250 | int i; | 228 | int i; |
251 | 229 | ||
252 | for( i = 0 ; i <= 7 ; ++i ) | 230 | for (i = 0; i <= 7; ++i) |
253 | if( zone == lm85_zone_map[i] ) | 231 | if (zone == lm85_zone_map[i]) |
254 | break ; | 232 | break; |
255 | if( i > 7 ) /* Not found. */ | 233 | if (i > 7) /* Not found. */ |
256 | i = 3; /* Always 100% */ | 234 | i = 3; /* Always 100% */ |
257 | return( (i & 0x07)<<5 ); | 235 | return i << 5; |
258 | } | 236 | } |
259 | 237 | ||
260 | #define HYST_TO_REG(val) (SENSORS_LIMIT(((val)+500)/1000,0,15)) | 238 | #define HYST_TO_REG(val) SENSORS_LIMIT(((val) + 500) / 1000, 0, 15) |
261 | #define HYST_FROM_REG(val) ((val)*1000) | 239 | #define HYST_FROM_REG(val) ((val) * 1000) |
262 | |||
263 | #define OFFSET_TO_REG(val) (SENSORS_LIMIT((val)/25,-127,127)) | ||
264 | #define OFFSET_FROM_REG(val) ((val)*25) | ||
265 | |||
266 | #define PPR_MASK(fan) (0x03<<(fan *2)) | ||
267 | #define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2)) | ||
268 | #define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1) | ||
269 | 240 | ||
270 | /* Chip sampling rates | 241 | /* Chip sampling rates |
271 | * | 242 | * |
@@ -292,11 +263,11 @@ struct lm85_zone { | |||
292 | u8 hyst; /* Low limit hysteresis. (0-15) */ | 263 | u8 hyst; /* Low limit hysteresis. (0-15) */ |
293 | u8 range; /* Temp range, encoded */ | 264 | u8 range; /* Temp range, encoded */ |
294 | s8 critical; /* "All fans ON" temp limit */ | 265 | s8 critical; /* "All fans ON" temp limit */ |
295 | u8 off_desired; /* Actual "off" temperature specified. Preserved | 266 | u8 off_desired; /* Actual "off" temperature specified. Preserved |
296 | * to prevent "drift" as other autofan control | 267 | * to prevent "drift" as other autofan control |
297 | * values change. | 268 | * values change. |
298 | */ | 269 | */ |
299 | u8 max_desired; /* Actual "max" temperature specified. Preserved | 270 | u8 max_desired; /* Actual "max" temperature specified. Preserved |
300 | * to prevent "drift" as other autofan control | 271 | * to prevent "drift" as other autofan control |
301 | * values change. | 272 | * values change. |
302 | */ | 273 | */ |
@@ -304,7 +275,6 @@ struct lm85_zone { | |||
304 | 275 | ||
305 | struct lm85_autofan { | 276 | struct lm85_autofan { |
306 | u8 config; /* Register value */ | 277 | u8 config; /* Register value */ |
307 | u8 freq; /* PWM frequency, encoded */ | ||
308 | u8 min_pwm; /* Minimum PWM value, encoded */ | 278 | u8 min_pwm; /* Minimum PWM value, encoded */ |
309 | u8 min_off; /* Min PWM or OFF below "limit", flag */ | 279 | u8 min_off; /* Min PWM or OFF below "limit", flag */ |
310 | }; | 280 | }; |
@@ -312,8 +282,8 @@ struct lm85_autofan { | |||
312 | /* For each registered chip, we need to keep some data in memory. | 282 | /* For each registered chip, we need to keep some data in memory. |
313 | The structure is dynamically allocated. */ | 283 | The structure is dynamically allocated. */ |
314 | struct lm85_data { | 284 | struct lm85_data { |
315 | struct i2c_client client; | ||
316 | struct device *hwmon_dev; | 285 | struct device *hwmon_dev; |
286 | const int *freq_map; | ||
317 | enum chips type; | 287 | enum chips type; |
318 | 288 | ||
319 | struct mutex update_lock; | 289 | struct mutex update_lock; |
@@ -327,45 +297,53 @@ struct lm85_data { | |||
327 | s8 temp[3]; /* Register value */ | 297 | s8 temp[3]; /* Register value */ |
328 | s8 temp_min[3]; /* Register value */ | 298 | s8 temp_min[3]; /* Register value */ |
329 | s8 temp_max[3]; /* Register value */ | 299 | s8 temp_max[3]; /* Register value */ |
330 | s8 temp_offset[3]; /* Register value */ | ||
331 | u16 fan[4]; /* Register value */ | 300 | u16 fan[4]; /* Register value */ |
332 | u16 fan_min[4]; /* Register value */ | 301 | u16 fan_min[4]; /* Register value */ |
333 | u8 pwm[3]; /* Register value */ | 302 | u8 pwm[3]; /* Register value */ |
334 | u8 spinup_ctl; /* Register encoding, combined */ | 303 | u8 pwm_freq[3]; /* Register encoding */ |
335 | u8 tach_mode; /* Register encoding, combined */ | ||
336 | u8 temp_ext[3]; /* Decoded values */ | 304 | u8 temp_ext[3]; /* Decoded values */ |
337 | u8 in_ext[8]; /* Decoded values */ | 305 | u8 in_ext[8]; /* Decoded values */ |
338 | u8 fan_ppr; /* Register value */ | ||
339 | u8 smooth[3]; /* Register encoding */ | ||
340 | u8 vid; /* Register value */ | 306 | u8 vid; /* Register value */ |
341 | u8 vrm; /* VRM version */ | 307 | u8 vrm; /* VRM version */ |
342 | u8 syncpwm3; /* Saved PWM3 for TACH 2,3,4 config */ | ||
343 | u8 oppoint[3]; /* Register value */ | ||
344 | u16 tmin_ctl; /* Register value */ | ||
345 | unsigned long therm_total; /* Cummulative therm count */ | ||
346 | u8 therm_limit; /* Register value */ | ||
347 | u32 alarms; /* Register encoding, combined */ | 308 | u32 alarms; /* Register encoding, combined */ |
348 | struct lm85_autofan autofan[3]; | 309 | struct lm85_autofan autofan[3]; |
349 | struct lm85_zone zone[3]; | 310 | struct lm85_zone zone[3]; |
350 | }; | 311 | }; |
351 | 312 | ||
352 | static int lm85_attach_adapter(struct i2c_adapter *adapter); | 313 | static int lm85_detect(struct i2c_client *client, int kind, |
353 | static int lm85_detect(struct i2c_adapter *adapter, int address, | 314 | struct i2c_board_info *info); |
354 | int kind); | 315 | static int lm85_probe(struct i2c_client *client, |
355 | static int lm85_detach_client(struct i2c_client *client); | 316 | const struct i2c_device_id *id); |
317 | static int lm85_remove(struct i2c_client *client); | ||
356 | 318 | ||
357 | static int lm85_read_value(struct i2c_client *client, u8 reg); | 319 | static int lm85_read_value(struct i2c_client *client, u8 reg); |
358 | static int lm85_write_value(struct i2c_client *client, u8 reg, int value); | 320 | static void lm85_write_value(struct i2c_client *client, u8 reg, int value); |
359 | static struct lm85_data *lm85_update_device(struct device *dev); | 321 | static struct lm85_data *lm85_update_device(struct device *dev); |
360 | static void lm85_init_client(struct i2c_client *client); | ||
361 | 322 | ||
362 | 323 | ||
324 | static const struct i2c_device_id lm85_id[] = { | ||
325 | { "adm1027", adm1027 }, | ||
326 | { "adt7463", adt7463 }, | ||
327 | { "lm85", any_chip }, | ||
328 | { "lm85b", lm85b }, | ||
329 | { "lm85c", lm85c }, | ||
330 | { "emc6d100", emc6d100 }, | ||
331 | { "emc6d101", emc6d100 }, | ||
332 | { "emc6d102", emc6d102 }, | ||
333 | { } | ||
334 | }; | ||
335 | MODULE_DEVICE_TABLE(i2c, lm85_id); | ||
336 | |||
363 | static struct i2c_driver lm85_driver = { | 337 | static struct i2c_driver lm85_driver = { |
338 | .class = I2C_CLASS_HWMON, | ||
364 | .driver = { | 339 | .driver = { |
365 | .name = "lm85", | 340 | .name = "lm85", |
366 | }, | 341 | }, |
367 | .attach_adapter = lm85_attach_adapter, | 342 | .probe = lm85_probe, |
368 | .detach_client = lm85_detach_client, | 343 | .remove = lm85_remove, |
344 | .id_table = lm85_id, | ||
345 | .detect = lm85_detect, | ||
346 | .address_data = &addr_data, | ||
369 | }; | 347 | }; |
370 | 348 | ||
371 | 349 | ||
@@ -375,7 +353,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | |||
375 | { | 353 | { |
376 | int nr = to_sensor_dev_attr(attr)->index; | 354 | int nr = to_sensor_dev_attr(attr)->index; |
377 | struct lm85_data *data = lm85_update_device(dev); | 355 | struct lm85_data *data = lm85_update_device(dev); |
378 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) ); | 356 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr])); |
379 | } | 357 | } |
380 | 358 | ||
381 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | 359 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, |
@@ -383,7 +361,7 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | |||
383 | { | 361 | { |
384 | int nr = to_sensor_dev_attr(attr)->index; | 362 | int nr = to_sensor_dev_attr(attr)->index; |
385 | struct lm85_data *data = lm85_update_device(dev); | 363 | struct lm85_data *data = lm85_update_device(dev); |
386 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) ); | 364 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr])); |
387 | } | 365 | } |
388 | 366 | ||
389 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | 367 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
@@ -414,7 +392,8 @@ show_fan_offset(4); | |||
414 | 392 | ||
415 | /* vid, vrm, alarms */ | 393 | /* vid, vrm, alarms */ |
416 | 394 | ||
417 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | 395 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, |
396 | char *buf) | ||
418 | { | 397 | { |
419 | struct lm85_data *data = lm85_update_device(dev); | 398 | struct lm85_data *data = lm85_update_device(dev); |
420 | int vid; | 399 | int vid; |
@@ -432,13 +411,15 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, c | |||
432 | 411 | ||
433 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 412 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
434 | 413 | ||
435 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 414 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, |
415 | char *buf) | ||
436 | { | 416 | { |
437 | struct lm85_data *data = dev_get_drvdata(dev); | 417 | struct lm85_data *data = dev_get_drvdata(dev); |
438 | return sprintf(buf, "%ld\n", (long) data->vrm); | 418 | return sprintf(buf, "%ld\n", (long) data->vrm); |
439 | } | 419 | } |
440 | 420 | ||
441 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 421 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, |
422 | const char *buf, size_t count) | ||
442 | { | 423 | { |
443 | struct lm85_data *data = dev_get_drvdata(dev); | 424 | struct lm85_data *data = dev_get_drvdata(dev); |
444 | data->vrm = simple_strtoul(buf, NULL, 10); | 425 | data->vrm = simple_strtoul(buf, NULL, 10); |
@@ -447,7 +428,8 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, | |||
447 | 428 | ||
448 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | 429 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); |
449 | 430 | ||
450 | static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) | 431 | static ssize_t show_alarms_reg(struct device *dev, struct device_attribute |
432 | *attr, char *buf) | ||
451 | { | 433 | { |
452 | struct lm85_data *data = lm85_update_device(dev); | 434 | struct lm85_data *data = lm85_update_device(dev); |
453 | return sprintf(buf, "%u\n", data->alarms); | 435 | return sprintf(buf, "%u\n", data->alarms); |
@@ -488,7 +470,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | |||
488 | { | 470 | { |
489 | int nr = to_sensor_dev_attr(attr)->index; | 471 | int nr = to_sensor_dev_attr(attr)->index; |
490 | struct lm85_data *data = lm85_update_device(dev); | 472 | struct lm85_data *data = lm85_update_device(dev); |
491 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) ); | 473 | return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); |
492 | } | 474 | } |
493 | 475 | ||
494 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | 476 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
@@ -564,11 +546,39 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute | |||
564 | return count; | 546 | return count; |
565 | } | 547 | } |
566 | 548 | ||
549 | static ssize_t show_pwm_freq(struct device *dev, | ||
550 | struct device_attribute *attr, char *buf) | ||
551 | { | ||
552 | int nr = to_sensor_dev_attr(attr)->index; | ||
553 | struct lm85_data *data = lm85_update_device(dev); | ||
554 | return sprintf(buf, "%d\n", FREQ_FROM_REG(data->freq_map, | ||
555 | data->pwm_freq[nr])); | ||
556 | } | ||
557 | |||
558 | static ssize_t set_pwm_freq(struct device *dev, | ||
559 | struct device_attribute *attr, const char *buf, size_t count) | ||
560 | { | ||
561 | int nr = to_sensor_dev_attr(attr)->index; | ||
562 | struct i2c_client *client = to_i2c_client(dev); | ||
563 | struct lm85_data *data = i2c_get_clientdata(client); | ||
564 | long val = simple_strtol(buf, NULL, 10); | ||
565 | |||
566 | mutex_lock(&data->update_lock); | ||
567 | data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val); | ||
568 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), | ||
569 | (data->zone[nr].range << 4) | ||
570 | | data->pwm_freq[nr]); | ||
571 | mutex_unlock(&data->update_lock); | ||
572 | return count; | ||
573 | } | ||
574 | |||
567 | #define show_pwm_reg(offset) \ | 575 | #define show_pwm_reg(offset) \ |
568 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | 576 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ |
569 | show_pwm, set_pwm, offset - 1); \ | 577 | show_pwm, set_pwm, offset - 1); \ |
570 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ | 578 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ |
571 | show_pwm_enable, set_pwm_enable, offset - 1) | 579 | show_pwm_enable, set_pwm_enable, offset - 1); \ |
580 | static SENSOR_DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \ | ||
581 | show_pwm_freq, set_pwm_freq, offset - 1) | ||
572 | 582 | ||
573 | show_pwm_reg(1); | 583 | show_pwm_reg(1); |
574 | show_pwm_reg(2); | 584 | show_pwm_reg(2); |
@@ -581,17 +591,16 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, | |||
581 | { | 591 | { |
582 | int nr = to_sensor_dev_attr(attr)->index; | 592 | int nr = to_sensor_dev_attr(attr)->index; |
583 | struct lm85_data *data = lm85_update_device(dev); | 593 | struct lm85_data *data = lm85_update_device(dev); |
584 | return sprintf( buf, "%d\n", INSEXT_FROM_REG(nr, | 594 | return sprintf(buf, "%d\n", INSEXT_FROM_REG(nr, data->in[nr], |
585 | data->in[nr], | 595 | data->in_ext[nr])); |
586 | data->in_ext[nr])); | ||
587 | } | 596 | } |
588 | 597 | ||
589 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | 598 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, |
590 | char *buf) | 599 | char *buf) |
591 | { | 600 | { |
592 | int nr = to_sensor_dev_attr(attr)->index; | 601 | int nr = to_sensor_dev_attr(attr)->index; |
593 | struct lm85_data *data = lm85_update_device(dev); | 602 | struct lm85_data *data = lm85_update_device(dev); |
594 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) ); | 603 | return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_min[nr])); |
595 | } | 604 | } |
596 | 605 | ||
597 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | 606 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, |
@@ -614,7 +623,7 @@ static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | |||
614 | { | 623 | { |
615 | int nr = to_sensor_dev_attr(attr)->index; | 624 | int nr = to_sensor_dev_attr(attr)->index; |
616 | struct lm85_data *data = lm85_update_device(dev); | 625 | struct lm85_data *data = lm85_update_device(dev); |
617 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) ); | 626 | return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_max[nr])); |
618 | } | 627 | } |
619 | 628 | ||
620 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | 629 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, |
@@ -656,8 +665,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | |||
656 | { | 665 | { |
657 | int nr = to_sensor_dev_attr(attr)->index; | 666 | int nr = to_sensor_dev_attr(attr)->index; |
658 | struct lm85_data *data = lm85_update_device(dev); | 667 | struct lm85_data *data = lm85_update_device(dev); |
659 | return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr], | 668 | return sprintf(buf, "%d\n", TEMPEXT_FROM_REG(data->temp[nr], |
660 | data->temp_ext[nr])); | 669 | data->temp_ext[nr])); |
661 | } | 670 | } |
662 | 671 | ||
663 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | 672 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, |
@@ -665,7 +674,7 @@ static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | |||
665 | { | 674 | { |
666 | int nr = to_sensor_dev_attr(attr)->index; | 675 | int nr = to_sensor_dev_attr(attr)->index; |
667 | struct lm85_data *data = lm85_update_device(dev); | 676 | struct lm85_data *data = lm85_update_device(dev); |
668 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) ); | 677 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); |
669 | } | 678 | } |
670 | 679 | ||
671 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | 680 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, |
@@ -688,7 +697,7 @@ static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | |||
688 | { | 697 | { |
689 | int nr = to_sensor_dev_attr(attr)->index; | 698 | int nr = to_sensor_dev_attr(attr)->index; |
690 | struct lm85_data *data = lm85_update_device(dev); | 699 | struct lm85_data *data = lm85_update_device(dev); |
691 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) ); | 700 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); |
692 | } | 701 | } |
693 | 702 | ||
694 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | 703 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, |
@@ -697,7 +706,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
697 | int nr = to_sensor_dev_attr(attr)->index; | 706 | int nr = to_sensor_dev_attr(attr)->index; |
698 | struct i2c_client *client = to_i2c_client(dev); | 707 | struct i2c_client *client = to_i2c_client(dev); |
699 | struct lm85_data *data = i2c_get_clientdata(client); | 708 | struct lm85_data *data = i2c_get_clientdata(client); |
700 | long val = simple_strtol(buf, NULL, 10); | 709 | long val = simple_strtol(buf, NULL, 10); |
701 | 710 | ||
702 | mutex_lock(&data->update_lock); | 711 | mutex_lock(&data->update_lock); |
703 | data->temp_max[nr] = TEMP_TO_REG(val); | 712 | data->temp_max[nr] = TEMP_TO_REG(val); |
@@ -726,7 +735,7 @@ static ssize_t show_pwm_auto_channels(struct device *dev, | |||
726 | { | 735 | { |
727 | int nr = to_sensor_dev_attr(attr)->index; | 736 | int nr = to_sensor_dev_attr(attr)->index; |
728 | struct lm85_data *data = lm85_update_device(dev); | 737 | struct lm85_data *data = lm85_update_device(dev); |
729 | return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config)); | 738 | return sprintf(buf, "%d\n", ZONE_FROM_REG(data->autofan[nr].config)); |
730 | } | 739 | } |
731 | 740 | ||
732 | static ssize_t set_pwm_auto_channels(struct device *dev, | 741 | static ssize_t set_pwm_auto_channels(struct device *dev, |
@@ -735,11 +744,11 @@ static ssize_t set_pwm_auto_channels(struct device *dev, | |||
735 | int nr = to_sensor_dev_attr(attr)->index; | 744 | int nr = to_sensor_dev_attr(attr)->index; |
736 | struct i2c_client *client = to_i2c_client(dev); | 745 | struct i2c_client *client = to_i2c_client(dev); |
737 | struct lm85_data *data = i2c_get_clientdata(client); | 746 | struct lm85_data *data = i2c_get_clientdata(client); |
738 | long val = simple_strtol(buf, NULL, 10); | 747 | long val = simple_strtol(buf, NULL, 10); |
739 | 748 | ||
740 | mutex_lock(&data->update_lock); | 749 | mutex_lock(&data->update_lock); |
741 | data->autofan[nr].config = (data->autofan[nr].config & (~0xe0)) | 750 | data->autofan[nr].config = (data->autofan[nr].config & (~0xe0)) |
742 | | ZONE_TO_REG(val) ; | 751 | | ZONE_TO_REG(val); |
743 | lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), | 752 | lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), |
744 | data->autofan[nr].config); | 753 | data->autofan[nr].config); |
745 | mutex_unlock(&data->update_lock); | 754 | mutex_unlock(&data->update_lock); |
@@ -751,7 +760,7 @@ static ssize_t show_pwm_auto_pwm_min(struct device *dev, | |||
751 | { | 760 | { |
752 | int nr = to_sensor_dev_attr(attr)->index; | 761 | int nr = to_sensor_dev_attr(attr)->index; |
753 | struct lm85_data *data = lm85_update_device(dev); | 762 | struct lm85_data *data = lm85_update_device(dev); |
754 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); | 763 | return sprintf(buf, "%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); |
755 | } | 764 | } |
756 | 765 | ||
757 | static ssize_t set_pwm_auto_pwm_min(struct device *dev, | 766 | static ssize_t set_pwm_auto_pwm_min(struct device *dev, |
@@ -775,7 +784,7 @@ static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, | |||
775 | { | 784 | { |
776 | int nr = to_sensor_dev_attr(attr)->index; | 785 | int nr = to_sensor_dev_attr(attr)->index; |
777 | struct lm85_data *data = lm85_update_device(dev); | 786 | struct lm85_data *data = lm85_update_device(dev); |
778 | return sprintf(buf,"%d\n", data->autofan[nr].min_off); | 787 | return sprintf(buf, "%d\n", data->autofan[nr].min_off); |
779 | } | 788 | } |
780 | 789 | ||
781 | static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, | 790 | static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, |
@@ -785,41 +794,15 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, | |||
785 | struct i2c_client *client = to_i2c_client(dev); | 794 | struct i2c_client *client = to_i2c_client(dev); |
786 | struct lm85_data *data = i2c_get_clientdata(client); | 795 | struct lm85_data *data = i2c_get_clientdata(client); |
787 | long val = simple_strtol(buf, NULL, 10); | 796 | long val = simple_strtol(buf, NULL, 10); |
797 | u8 tmp; | ||
788 | 798 | ||
789 | mutex_lock(&data->update_lock); | 799 | mutex_lock(&data->update_lock); |
790 | data->autofan[nr].min_off = val; | 800 | data->autofan[nr].min_off = val; |
791 | lm85_write_value(client, LM85_REG_AFAN_SPIKE1, data->smooth[0] | 801 | tmp = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
792 | | data->syncpwm3 | 802 | tmp &= ~(0x20 << nr); |
793 | | (data->autofan[0].min_off ? 0x20 : 0) | 803 | if (data->autofan[nr].min_off) |
794 | | (data->autofan[1].min_off ? 0x40 : 0) | 804 | tmp |= 0x20 << nr; |
795 | | (data->autofan[2].min_off ? 0x80 : 0) | 805 | lm85_write_value(client, LM85_REG_AFAN_SPIKE1, tmp); |
796 | ); | ||
797 | mutex_unlock(&data->update_lock); | ||
798 | return count; | ||
799 | } | ||
800 | |||
801 | static ssize_t show_pwm_auto_pwm_freq(struct device *dev, | ||
802 | struct device_attribute *attr, char *buf) | ||
803 | { | ||
804 | int nr = to_sensor_dev_attr(attr)->index; | ||
805 | struct lm85_data *data = lm85_update_device(dev); | ||
806 | return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq)); | ||
807 | } | ||
808 | |||
809 | static ssize_t set_pwm_auto_pwm_freq(struct device *dev, | ||
810 | struct device_attribute *attr, const char *buf, size_t count) | ||
811 | { | ||
812 | int nr = to_sensor_dev_attr(attr)->index; | ||
813 | struct i2c_client *client = to_i2c_client(dev); | ||
814 | struct lm85_data *data = i2c_get_clientdata(client); | ||
815 | long val = simple_strtol(buf, NULL, 10); | ||
816 | |||
817 | mutex_lock(&data->update_lock); | ||
818 | data->autofan[nr].freq = FREQ_TO_REG(val); | ||
819 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), | ||
820 | (data->zone[nr].range << 4) | ||
821 | | data->autofan[nr].freq | ||
822 | ); | ||
823 | mutex_unlock(&data->update_lock); | 806 | mutex_unlock(&data->update_lock); |
824 | return count; | 807 | return count; |
825 | } | 808 | } |
@@ -833,10 +816,7 @@ static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \ | |||
833 | set_pwm_auto_pwm_min, offset - 1); \ | 816 | set_pwm_auto_pwm_min, offset - 1); \ |
834 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \ | 817 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \ |
835 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \ | 818 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \ |
836 | set_pwm_auto_pwm_minctl, offset - 1); \ | 819 | set_pwm_auto_pwm_minctl, offset - 1) |
837 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_freq, \ | ||
838 | S_IRUGO | S_IWUSR, show_pwm_auto_pwm_freq, \ | ||
839 | set_pwm_auto_pwm_freq, offset - 1); | ||
840 | 820 | ||
841 | pwm_auto(1); | 821 | pwm_auto(1); |
842 | pwm_auto(2); | 822 | pwm_auto(2); |
@@ -849,7 +829,7 @@ static ssize_t show_temp_auto_temp_off(struct device *dev, | |||
849 | { | 829 | { |
850 | int nr = to_sensor_dev_attr(attr)->index; | 830 | int nr = to_sensor_dev_attr(attr)->index; |
851 | struct lm85_data *data = lm85_update_device(dev); | 831 | struct lm85_data *data = lm85_update_device(dev); |
852 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) - | 832 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) - |
853 | HYST_FROM_REG(data->zone[nr].hyst)); | 833 | HYST_FROM_REG(data->zone[nr].hyst)); |
854 | } | 834 | } |
855 | 835 | ||
@@ -866,15 +846,13 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, | |||
866 | min = TEMP_FROM_REG(data->zone[nr].limit); | 846 | min = TEMP_FROM_REG(data->zone[nr].limit); |
867 | data->zone[nr].off_desired = TEMP_TO_REG(val); | 847 | data->zone[nr].off_desired = TEMP_TO_REG(val); |
868 | data->zone[nr].hyst = HYST_TO_REG(min - val); | 848 | data->zone[nr].hyst = HYST_TO_REG(min - val); |
869 | if ( nr == 0 || nr == 1 ) { | 849 | if (nr == 0 || nr == 1) { |
870 | lm85_write_value(client, LM85_REG_AFAN_HYST1, | 850 | lm85_write_value(client, LM85_REG_AFAN_HYST1, |
871 | (data->zone[0].hyst << 4) | 851 | (data->zone[0].hyst << 4) |
872 | | data->zone[1].hyst | 852 | | data->zone[1].hyst); |
873 | ); | ||
874 | } else { | 853 | } else { |
875 | lm85_write_value(client, LM85_REG_AFAN_HYST2, | 854 | lm85_write_value(client, LM85_REG_AFAN_HYST2, |
876 | (data->zone[2].hyst << 4) | 855 | (data->zone[2].hyst << 4)); |
877 | ); | ||
878 | } | 856 | } |
879 | mutex_unlock(&data->update_lock); | 857 | mutex_unlock(&data->update_lock); |
880 | return count; | 858 | return count; |
@@ -885,7 +863,7 @@ static ssize_t show_temp_auto_temp_min(struct device *dev, | |||
885 | { | 863 | { |
886 | int nr = to_sensor_dev_attr(attr)->index; | 864 | int nr = to_sensor_dev_attr(attr)->index; |
887 | struct lm85_data *data = lm85_update_device(dev); | 865 | struct lm85_data *data = lm85_update_device(dev); |
888 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) ); | 866 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit)); |
889 | } | 867 | } |
890 | 868 | ||
891 | static ssize_t set_temp_auto_temp_min(struct device *dev, | 869 | static ssize_t set_temp_auto_temp_min(struct device *dev, |
@@ -907,21 +885,19 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, | |||
907 | TEMP_FROM_REG(data->zone[nr].limit)); | 885 | TEMP_FROM_REG(data->zone[nr].limit)); |
908 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), | 886 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), |
909 | ((data->zone[nr].range & 0x0f) << 4) | 887 | ((data->zone[nr].range & 0x0f) << 4) |
910 | | (data->autofan[nr].freq & 0x07)); | 888 | | (data->pwm_freq[nr] & 0x07)); |
911 | 889 | ||
912 | /* Update temp_auto_hyst and temp_auto_off */ | 890 | /* Update temp_auto_hyst and temp_auto_off */ |
913 | data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG( | 891 | data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG( |
914 | data->zone[nr].limit) - TEMP_FROM_REG( | 892 | data->zone[nr].limit) - TEMP_FROM_REG( |
915 | data->zone[nr].off_desired)); | 893 | data->zone[nr].off_desired)); |
916 | if ( nr == 0 || nr == 1 ) { | 894 | if (nr == 0 || nr == 1) { |
917 | lm85_write_value(client, LM85_REG_AFAN_HYST1, | 895 | lm85_write_value(client, LM85_REG_AFAN_HYST1, |
918 | (data->zone[0].hyst << 4) | 896 | (data->zone[0].hyst << 4) |
919 | | data->zone[1].hyst | 897 | | data->zone[1].hyst); |
920 | ); | ||
921 | } else { | 898 | } else { |
922 | lm85_write_value(client, LM85_REG_AFAN_HYST2, | 899 | lm85_write_value(client, LM85_REG_AFAN_HYST2, |
923 | (data->zone[2].hyst << 4) | 900 | (data->zone[2].hyst << 4)); |
924 | ); | ||
925 | } | 901 | } |
926 | mutex_unlock(&data->update_lock); | 902 | mutex_unlock(&data->update_lock); |
927 | return count; | 903 | return count; |
@@ -932,7 +908,7 @@ static ssize_t show_temp_auto_temp_max(struct device *dev, | |||
932 | { | 908 | { |
933 | int nr = to_sensor_dev_attr(attr)->index; | 909 | int nr = to_sensor_dev_attr(attr)->index; |
934 | struct lm85_data *data = lm85_update_device(dev); | 910 | struct lm85_data *data = lm85_update_device(dev); |
935 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) + | 911 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) + |
936 | RANGE_FROM_REG(data->zone[nr].range)); | 912 | RANGE_FROM_REG(data->zone[nr].range)); |
937 | } | 913 | } |
938 | 914 | ||
@@ -952,7 +928,7 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, | |||
952 | val - min); | 928 | val - min); |
953 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), | 929 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), |
954 | ((data->zone[nr].range & 0x0f) << 4) | 930 | ((data->zone[nr].range & 0x0f) << 4) |
955 | | (data->autofan[nr].freq & 0x07)); | 931 | | (data->pwm_freq[nr] & 0x07)); |
956 | mutex_unlock(&data->update_lock); | 932 | mutex_unlock(&data->update_lock); |
957 | return count; | 933 | return count; |
958 | } | 934 | } |
@@ -962,11 +938,11 @@ static ssize_t show_temp_auto_temp_crit(struct device *dev, | |||
962 | { | 938 | { |
963 | int nr = to_sensor_dev_attr(attr)->index; | 939 | int nr = to_sensor_dev_attr(attr)->index; |
964 | struct lm85_data *data = lm85_update_device(dev); | 940 | struct lm85_data *data = lm85_update_device(dev); |
965 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical)); | 941 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].critical)); |
966 | } | 942 | } |
967 | 943 | ||
968 | static ssize_t set_temp_auto_temp_crit(struct device *dev, | 944 | static ssize_t set_temp_auto_temp_crit(struct device *dev, |
969 | struct device_attribute *attr,const char *buf, size_t count) | 945 | struct device_attribute *attr, const char *buf, size_t count) |
970 | { | 946 | { |
971 | int nr = to_sensor_dev_attr(attr)->index; | 947 | int nr = to_sensor_dev_attr(attr)->index; |
972 | struct i2c_client *client = to_i2c_client(dev); | 948 | struct i2c_client *client = to_i2c_client(dev); |
@@ -999,13 +975,6 @@ temp_auto(1); | |||
999 | temp_auto(2); | 975 | temp_auto(2); |
1000 | temp_auto(3); | 976 | temp_auto(3); |
1001 | 977 | ||
1002 | static int lm85_attach_adapter(struct i2c_adapter *adapter) | ||
1003 | { | ||
1004 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
1005 | return 0; | ||
1006 | return i2c_probe(adapter, &addr_data, lm85_detect); | ||
1007 | } | ||
1008 | |||
1009 | static struct attribute *lm85_attributes[] = { | 978 | static struct attribute *lm85_attributes[] = { |
1010 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 979 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1011 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 980 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
@@ -1026,6 +995,9 @@ static struct attribute *lm85_attributes[] = { | |||
1026 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 995 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
1027 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | 996 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
1028 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | 997 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
998 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | ||
999 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | ||
1000 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | ||
1029 | 1001 | ||
1030 | &sensor_dev_attr_in0_input.dev_attr.attr, | 1002 | &sensor_dev_attr_in0_input.dev_attr.attr, |
1031 | &sensor_dev_attr_in1_input.dev_attr.attr, | 1003 | &sensor_dev_attr_in1_input.dev_attr.attr, |
@@ -1068,9 +1040,6 @@ static struct attribute *lm85_attributes[] = { | |||
1068 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, | 1040 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, |
1069 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, | 1041 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, |
1070 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, | 1042 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, |
1071 | &sensor_dev_attr_pwm1_auto_pwm_freq.dev_attr.attr, | ||
1072 | &sensor_dev_attr_pwm2_auto_pwm_freq.dev_attr.attr, | ||
1073 | &sensor_dev_attr_pwm3_auto_pwm_freq.dev_attr.attr, | ||
1074 | 1043 | ||
1075 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, | 1044 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, |
1076 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, | 1045 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, |
@@ -1127,184 +1096,190 @@ static const struct attribute_group lm85_group_in567 = { | |||
1127 | .attrs = lm85_attributes_in567, | 1096 | .attrs = lm85_attributes_in567, |
1128 | }; | 1097 | }; |
1129 | 1098 | ||
1130 | static int lm85_detect(struct i2c_adapter *adapter, int address, | 1099 | static void lm85_init_client(struct i2c_client *client) |
1131 | int kind) | ||
1132 | { | 1100 | { |
1133 | int company, verstep ; | 1101 | int value; |
1134 | struct i2c_client *new_client = NULL; | ||
1135 | struct lm85_data *data; | ||
1136 | int err = 0; | ||
1137 | const char *type_name = ""; | ||
1138 | 1102 | ||
1139 | if (!i2c_check_functionality(adapter, | 1103 | /* Start monitoring if needed */ |
1140 | I2C_FUNC_SMBUS_BYTE_DATA)) { | 1104 | value = lm85_read_value(client, LM85_REG_CONFIG); |
1141 | /* We need to be able to do byte I/O */ | 1105 | if (!(value & 0x01)) { |
1142 | goto ERROR0 ; | 1106 | dev_info(&client->dev, "Starting monitoring\n"); |
1143 | }; | 1107 | lm85_write_value(client, LM85_REG_CONFIG, value | 0x01); |
1108 | } | ||
1109 | |||
1110 | /* Warn about unusual configuration bits */ | ||
1111 | if (value & 0x02) | ||
1112 | dev_warn(&client->dev, "Device configuration is locked\n"); | ||
1113 | if (!(value & 0x04)) | ||
1114 | dev_warn(&client->dev, "Device is not ready\n"); | ||
1115 | } | ||
1144 | 1116 | ||
1145 | /* OK. For now, we presume we have a valid client. We now create the | 1117 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1146 | client structure, even though we cannot fill it completely yet. | 1118 | static int lm85_detect(struct i2c_client *client, int kind, |
1147 | But it allows us to access lm85_{read,write}_value. */ | 1119 | struct i2c_board_info *info) |
1120 | { | ||
1121 | struct i2c_adapter *adapter = client->adapter; | ||
1122 | int address = client->addr; | ||
1123 | const char *type_name; | ||
1148 | 1124 | ||
1149 | if (!(data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL))) { | 1125 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1150 | err = -ENOMEM; | 1126 | /* We need to be able to do byte I/O */ |
1151 | goto ERROR0; | 1127 | return -ENODEV; |
1152 | } | 1128 | } |
1153 | 1129 | ||
1154 | new_client = &data->client; | 1130 | /* If auto-detecting, determine the chip type */ |
1155 | i2c_set_clientdata(new_client, data); | 1131 | if (kind < 0) { |
1156 | new_client->addr = address; | 1132 | int company = lm85_read_value(client, LM85_REG_COMPANY); |
1157 | new_client->adapter = adapter; | 1133 | int verstep = lm85_read_value(client, LM85_REG_VERSTEP); |
1158 | new_client->driver = &lm85_driver; | 1134 | |
1159 | new_client->flags = 0; | 1135 | dev_dbg(&adapter->dev, "Detecting device at 0x%02x with " |
1160 | 1136 | "COMPANY: 0x%02x and VERSTEP: 0x%02x\n", | |
1161 | /* Now, we do the remaining detection. */ | 1137 | address, company, verstep); |
1162 | 1138 | ||
1163 | company = lm85_read_value(new_client, LM85_REG_COMPANY); | 1139 | /* All supported chips have the version in common */ |
1164 | verstep = lm85_read_value(new_client, LM85_REG_VERSTEP); | 1140 | if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC) { |
1165 | 1141 | dev_dbg(&adapter->dev, "Autodetection failed: " | |
1166 | dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with" | 1142 | "unsupported version\n"); |
1167 | " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", | 1143 | return -ENODEV; |
1168 | i2c_adapter_id(new_client->adapter), new_client->addr, | 1144 | } |
1169 | company, verstep); | 1145 | kind = any_chip; |
1170 | 1146 | ||
1171 | /* If auto-detecting, Determine the chip type. */ | 1147 | /* Now, refine the detection */ |
1172 | if (kind <= 0) { | 1148 | if (company == LM85_COMPANY_NATIONAL) { |
1173 | dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x ...\n", | 1149 | switch (verstep) { |
1174 | i2c_adapter_id(adapter), address ); | 1150 | case LM85_VERSTEP_LM85C: |
1175 | if( company == LM85_COMPANY_NATIONAL | 1151 | kind = lm85c; |
1176 | && verstep == LM85_VERSTEP_LM85C ) { | 1152 | break; |
1177 | kind = lm85c ; | 1153 | case LM85_VERSTEP_LM85B: |
1178 | } else if( company == LM85_COMPANY_NATIONAL | 1154 | kind = lm85b; |
1179 | && verstep == LM85_VERSTEP_LM85B ) { | 1155 | break; |
1180 | kind = lm85b ; | 1156 | } |
1181 | } else if( company == LM85_COMPANY_NATIONAL | 1157 | } else if (company == LM85_COMPANY_ANALOG_DEV) { |
1182 | && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) { | 1158 | switch (verstep) { |
1183 | dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x" | 1159 | case LM85_VERSTEP_ADM1027: |
1184 | " Defaulting to LM85.\n", verstep); | 1160 | kind = adm1027; |
1185 | kind = any_chip ; | 1161 | break; |
1186 | } else if( company == LM85_COMPANY_ANALOG_DEV | 1162 | case LM85_VERSTEP_ADT7463: |
1187 | && verstep == LM85_VERSTEP_ADM1027 ) { | 1163 | case LM85_VERSTEP_ADT7463C: |
1188 | kind = adm1027 ; | 1164 | kind = adt7463; |
1189 | } else if( company == LM85_COMPANY_ANALOG_DEV | 1165 | break; |
1190 | && (verstep == LM85_VERSTEP_ADT7463 | 1166 | } |
1191 | || verstep == LM85_VERSTEP_ADT7463C) ) { | 1167 | } else if (company == LM85_COMPANY_SMSC) { |
1192 | kind = adt7463 ; | 1168 | switch (verstep) { |
1193 | } else if( company == LM85_COMPANY_ANALOG_DEV | 1169 | case LM85_VERSTEP_EMC6D100_A0: |
1194 | && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) { | 1170 | case LM85_VERSTEP_EMC6D100_A1: |
1195 | dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x" | 1171 | /* Note: we can't tell a '100 from a '101 */ |
1196 | " Defaulting to Generic LM85.\n", verstep ); | 1172 | kind = emc6d100; |
1197 | kind = any_chip ; | 1173 | break; |
1198 | } else if( company == LM85_COMPANY_SMSC | 1174 | case LM85_VERSTEP_EMC6D102: |
1199 | && (verstep == LM85_VERSTEP_EMC6D100_A0 | 1175 | kind = emc6d102; |
1200 | || verstep == LM85_VERSTEP_EMC6D100_A1) ) { | 1176 | break; |
1201 | /* Unfortunately, we can't tell a '100 from a '101 | ||
1202 | * from the registers. Since a '101 is a '100 | ||
1203 | * in a package with fewer pins and therefore no | ||
1204 | * 3.3V, 1.5V or 1.8V inputs, perhaps if those | ||
1205 | * inputs read 0, then it's a '101. | ||
1206 | */ | ||
1207 | kind = emc6d100 ; | ||
1208 | } else if( company == LM85_COMPANY_SMSC | ||
1209 | && verstep == LM85_VERSTEP_EMC6D102) { | ||
1210 | kind = emc6d102 ; | ||
1211 | } else if( company == LM85_COMPANY_SMSC | ||
1212 | && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) { | ||
1213 | dev_err(&adapter->dev, "lm85: Detected SMSC chip\n"); | ||
1214 | dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x" | ||
1215 | " Defaulting to Generic LM85.\n", verstep ); | ||
1216 | kind = any_chip ; | ||
1217 | } else if( kind == any_chip | ||
1218 | && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) { | ||
1219 | dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n"); | ||
1220 | /* Leave kind as "any_chip" */ | ||
1221 | } else { | ||
1222 | dev_dbg(&adapter->dev, "Autodetection failed\n"); | ||
1223 | /* Not an LM85 ... */ | ||
1224 | if( kind == any_chip ) { /* User used force=x,y */ | ||
1225 | dev_err(&adapter->dev, "Generic LM85 Version 6 not" | ||
1226 | " found at %d,0x%02x. Try force_lm85c.\n", | ||
1227 | i2c_adapter_id(adapter), address ); | ||
1228 | } | 1177 | } |
1229 | err = 0 ; | 1178 | } else { |
1230 | goto ERROR1; | 1179 | dev_dbg(&adapter->dev, "Autodetection failed: " |
1180 | "unknown vendor\n"); | ||
1181 | return -ENODEV; | ||
1231 | } | 1182 | } |
1232 | } | 1183 | } |
1233 | 1184 | ||
1234 | /* Fill in the chip specific driver values */ | 1185 | switch (kind) { |
1235 | if ( kind == any_chip ) { | 1186 | case lm85b: |
1236 | type_name = "lm85"; | ||
1237 | } else if ( kind == lm85b ) { | ||
1238 | type_name = "lm85b"; | 1187 | type_name = "lm85b"; |
1239 | } else if ( kind == lm85c ) { | 1188 | break; |
1189 | case lm85c: | ||
1240 | type_name = "lm85c"; | 1190 | type_name = "lm85c"; |
1241 | } else if ( kind == adm1027 ) { | 1191 | break; |
1192 | case adm1027: | ||
1242 | type_name = "adm1027"; | 1193 | type_name = "adm1027"; |
1243 | } else if ( kind == adt7463 ) { | 1194 | break; |
1195 | case adt7463: | ||
1244 | type_name = "adt7463"; | 1196 | type_name = "adt7463"; |
1245 | } else if ( kind == emc6d100){ | 1197 | break; |
1198 | case emc6d100: | ||
1246 | type_name = "emc6d100"; | 1199 | type_name = "emc6d100"; |
1247 | } else if ( kind == emc6d102 ) { | 1200 | break; |
1201 | case emc6d102: | ||
1248 | type_name = "emc6d102"; | 1202 | type_name = "emc6d102"; |
1203 | break; | ||
1204 | default: | ||
1205 | type_name = "lm85"; | ||
1249 | } | 1206 | } |
1250 | strlcpy(new_client->name, type_name, I2C_NAME_SIZE); | 1207 | strlcpy(info->type, type_name, I2C_NAME_SIZE); |
1208 | |||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1212 | static int lm85_probe(struct i2c_client *client, | ||
1213 | const struct i2c_device_id *id) | ||
1214 | { | ||
1215 | struct lm85_data *data; | ||
1216 | int err; | ||
1217 | |||
1218 | data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL); | ||
1219 | if (!data) | ||
1220 | return -ENOMEM; | ||
1251 | 1221 | ||
1252 | /* Fill in the remaining client fields */ | 1222 | i2c_set_clientdata(client, data); |
1253 | data->type = kind; | 1223 | data->type = id->driver_data; |
1254 | data->valid = 0; | ||
1255 | mutex_init(&data->update_lock); | 1224 | mutex_init(&data->update_lock); |
1256 | 1225 | ||
1257 | /* Tell the I2C layer a new client has arrived */ | 1226 | /* Fill in the chip specific driver values */ |
1258 | if ((err = i2c_attach_client(new_client))) | 1227 | switch (data->type) { |
1259 | goto ERROR1; | 1228 | case adm1027: |
1229 | case adt7463: | ||
1230 | case emc6d100: | ||
1231 | case emc6d102: | ||
1232 | data->freq_map = adm1027_freq_map; | ||
1233 | break; | ||
1234 | default: | ||
1235 | data->freq_map = lm85_freq_map; | ||
1236 | } | ||
1260 | 1237 | ||
1261 | /* Set the VRM version */ | 1238 | /* Set the VRM version */ |
1262 | data->vrm = vid_which_vrm(); | 1239 | data->vrm = vid_which_vrm(); |
1263 | 1240 | ||
1264 | /* Initialize the LM85 chip */ | 1241 | /* Initialize the LM85 chip */ |
1265 | lm85_init_client(new_client); | 1242 | lm85_init_client(client); |
1266 | 1243 | ||
1267 | /* Register sysfs hooks */ | 1244 | /* Register sysfs hooks */ |
1268 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm85_group))) | 1245 | err = sysfs_create_group(&client->dev.kobj, &lm85_group); |
1269 | goto ERROR2; | 1246 | if (err) |
1247 | goto err_kfree; | ||
1270 | 1248 | ||
1271 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used | 1249 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used |
1272 | as a sixth digital VID input rather than an analog input. */ | 1250 | as a sixth digital VID input rather than an analog input. */ |
1273 | data->vid = lm85_read_value(new_client, LM85_REG_VID); | 1251 | data->vid = lm85_read_value(client, LM85_REG_VID); |
1274 | if (!(kind == adt7463 && (data->vid & 0x80))) | 1252 | if (!(data->type == adt7463 && (data->vid & 0x80))) |
1275 | if ((err = sysfs_create_group(&new_client->dev.kobj, | 1253 | if ((err = sysfs_create_group(&client->dev.kobj, |
1276 | &lm85_group_in4))) | 1254 | &lm85_group_in4))) |
1277 | goto ERROR3; | 1255 | goto err_remove_files; |
1278 | 1256 | ||
1279 | /* The EMC6D100 has 3 additional voltage inputs */ | 1257 | /* The EMC6D100 has 3 additional voltage inputs */ |
1280 | if (kind == emc6d100) | 1258 | if (data->type == emc6d100) |
1281 | if ((err = sysfs_create_group(&new_client->dev.kobj, | 1259 | if ((err = sysfs_create_group(&client->dev.kobj, |
1282 | &lm85_group_in567))) | 1260 | &lm85_group_in567))) |
1283 | goto ERROR3; | 1261 | goto err_remove_files; |
1284 | 1262 | ||
1285 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 1263 | data->hwmon_dev = hwmon_device_register(&client->dev); |
1286 | if (IS_ERR(data->hwmon_dev)) { | 1264 | if (IS_ERR(data->hwmon_dev)) { |
1287 | err = PTR_ERR(data->hwmon_dev); | 1265 | err = PTR_ERR(data->hwmon_dev); |
1288 | goto ERROR3; | 1266 | goto err_remove_files; |
1289 | } | 1267 | } |
1290 | 1268 | ||
1291 | return 0; | 1269 | return 0; |
1292 | 1270 | ||
1293 | /* Error out and cleanup code */ | 1271 | /* Error out and cleanup code */ |
1294 | ERROR3: | 1272 | err_remove_files: |
1295 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group); | 1273 | sysfs_remove_group(&client->dev.kobj, &lm85_group); |
1296 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_in4); | 1274 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); |
1297 | if (kind == emc6d100) | 1275 | if (data->type == emc6d100) |
1298 | sysfs_remove_group(&new_client->dev.kobj, &lm85_group_in567); | 1276 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in567); |
1299 | ERROR2: | 1277 | err_kfree: |
1300 | i2c_detach_client(new_client); | ||
1301 | ERROR1: | ||
1302 | kfree(data); | 1278 | kfree(data); |
1303 | ERROR0: | ||
1304 | return err; | 1279 | return err; |
1305 | } | 1280 | } |
1306 | 1281 | ||
1307 | static int lm85_detach_client(struct i2c_client *client) | 1282 | static int lm85_remove(struct i2c_client *client) |
1308 | { | 1283 | { |
1309 | struct lm85_data *data = i2c_get_clientdata(client); | 1284 | struct lm85_data *data = i2c_get_clientdata(client); |
1310 | hwmon_device_unregister(data->hwmon_dev); | 1285 | hwmon_device_unregister(data->hwmon_dev); |
@@ -1312,7 +1287,6 @@ static int lm85_detach_client(struct i2c_client *client) | |||
1312 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); | 1287 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); |
1313 | if (data->type == emc6d100) | 1288 | if (data->type == emc6d100) |
1314 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in567); | 1289 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in567); |
1315 | i2c_detach_client(client); | ||
1316 | kfree(data); | 1290 | kfree(data); |
1317 | return 0; | 1291 | return 0; |
1318 | } | 1292 | } |
@@ -1323,100 +1297,46 @@ static int lm85_read_value(struct i2c_client *client, u8 reg) | |||
1323 | int res; | 1297 | int res; |
1324 | 1298 | ||
1325 | /* What size location is it? */ | 1299 | /* What size location is it? */ |
1326 | switch( reg ) { | 1300 | switch (reg) { |
1327 | case LM85_REG_FAN(0) : /* Read WORD data */ | 1301 | case LM85_REG_FAN(0): /* Read WORD data */ |
1328 | case LM85_REG_FAN(1) : | 1302 | case LM85_REG_FAN(1): |
1329 | case LM85_REG_FAN(2) : | 1303 | case LM85_REG_FAN(2): |
1330 | case LM85_REG_FAN(3) : | 1304 | case LM85_REG_FAN(3): |
1331 | case LM85_REG_FAN_MIN(0) : | 1305 | case LM85_REG_FAN_MIN(0): |
1332 | case LM85_REG_FAN_MIN(1) : | 1306 | case LM85_REG_FAN_MIN(1): |
1333 | case LM85_REG_FAN_MIN(2) : | 1307 | case LM85_REG_FAN_MIN(2): |
1334 | case LM85_REG_FAN_MIN(3) : | 1308 | case LM85_REG_FAN_MIN(3): |
1335 | case LM85_REG_ALARM1 : /* Read both bytes at once */ | 1309 | case LM85_REG_ALARM1: /* Read both bytes at once */ |
1336 | res = i2c_smbus_read_byte_data(client, reg) & 0xff ; | 1310 | res = i2c_smbus_read_byte_data(client, reg) & 0xff; |
1337 | res |= i2c_smbus_read_byte_data(client, reg+1) << 8 ; | 1311 | res |= i2c_smbus_read_byte_data(client, reg + 1) << 8; |
1338 | break ; | 1312 | break; |
1339 | case ADT7463_REG_TMIN_CTL1 : /* Read WORD MSB, LSB */ | ||
1340 | res = i2c_smbus_read_byte_data(client, reg) << 8 ; | ||
1341 | res |= i2c_smbus_read_byte_data(client, reg+1) & 0xff ; | ||
1342 | break ; | ||
1343 | default: /* Read BYTE data */ | 1313 | default: /* Read BYTE data */ |
1344 | res = i2c_smbus_read_byte_data(client, reg); | 1314 | res = i2c_smbus_read_byte_data(client, reg); |
1345 | break ; | 1315 | break; |
1346 | } | 1316 | } |
1347 | 1317 | ||
1348 | return res ; | 1318 | return res; |
1349 | } | 1319 | } |
1350 | 1320 | ||
1351 | static int lm85_write_value(struct i2c_client *client, u8 reg, int value) | 1321 | static void lm85_write_value(struct i2c_client *client, u8 reg, int value) |
1352 | { | 1322 | { |
1353 | int res ; | 1323 | switch (reg) { |
1354 | 1324 | case LM85_REG_FAN(0): /* Write WORD data */ | |
1355 | switch( reg ) { | 1325 | case LM85_REG_FAN(1): |
1356 | case LM85_REG_FAN(0) : /* Write WORD data */ | 1326 | case LM85_REG_FAN(2): |
1357 | case LM85_REG_FAN(1) : | 1327 | case LM85_REG_FAN(3): |
1358 | case LM85_REG_FAN(2) : | 1328 | case LM85_REG_FAN_MIN(0): |
1359 | case LM85_REG_FAN(3) : | 1329 | case LM85_REG_FAN_MIN(1): |
1360 | case LM85_REG_FAN_MIN(0) : | 1330 | case LM85_REG_FAN_MIN(2): |
1361 | case LM85_REG_FAN_MIN(1) : | 1331 | case LM85_REG_FAN_MIN(3): |
1362 | case LM85_REG_FAN_MIN(2) : | ||
1363 | case LM85_REG_FAN_MIN(3) : | ||
1364 | /* NOTE: ALARM is read only, so not included here */ | 1332 | /* NOTE: ALARM is read only, so not included here */ |
1365 | res = i2c_smbus_write_byte_data(client, reg, value & 0xff) ; | 1333 | i2c_smbus_write_byte_data(client, reg, value & 0xff); |
1366 | res |= i2c_smbus_write_byte_data(client, reg+1, (value>>8) & 0xff) ; | 1334 | i2c_smbus_write_byte_data(client, reg + 1, value >> 8); |
1367 | break ; | 1335 | break; |
1368 | case ADT7463_REG_TMIN_CTL1 : /* Write WORD MSB, LSB */ | ||
1369 | res = i2c_smbus_write_byte_data(client, reg, (value>>8) & 0xff); | ||
1370 | res |= i2c_smbus_write_byte_data(client, reg+1, value & 0xff) ; | ||
1371 | break ; | ||
1372 | default: /* Write BYTE data */ | 1336 | default: /* Write BYTE data */ |
1373 | res = i2c_smbus_write_byte_data(client, reg, value); | 1337 | i2c_smbus_write_byte_data(client, reg, value); |
1374 | break ; | 1338 | break; |
1375 | } | 1339 | } |
1376 | |||
1377 | return res ; | ||
1378 | } | ||
1379 | |||
1380 | static void lm85_init_client(struct i2c_client *client) | ||
1381 | { | ||
1382 | int value; | ||
1383 | struct lm85_data *data = i2c_get_clientdata(client); | ||
1384 | |||
1385 | dev_dbg(&client->dev, "Initializing device\n"); | ||
1386 | |||
1387 | /* Warn if part was not "READY" */ | ||
1388 | value = lm85_read_value(client, LM85_REG_CONFIG); | ||
1389 | dev_dbg(&client->dev, "LM85_REG_CONFIG is: 0x%02x\n", value); | ||
1390 | if( value & 0x02 ) { | ||
1391 | dev_err(&client->dev, "Client (%d,0x%02x) config is locked.\n", | ||
1392 | i2c_adapter_id(client->adapter), client->addr ); | ||
1393 | }; | ||
1394 | if( ! (value & 0x04) ) { | ||
1395 | dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n", | ||
1396 | i2c_adapter_id(client->adapter), client->addr ); | ||
1397 | }; | ||
1398 | if( value & 0x10 | ||
1399 | && ( data->type == adm1027 | ||
1400 | || data->type == adt7463 ) ) { | ||
1401 | dev_err(&client->dev, "Client (%d,0x%02x) VxI mode is set. " | ||
1402 | "Please report this to the lm85 maintainer.\n", | ||
1403 | i2c_adapter_id(client->adapter), client->addr ); | ||
1404 | }; | ||
1405 | |||
1406 | /* WE INTENTIONALLY make no changes to the limits, | ||
1407 | * offsets, pwms, fans and zones. If they were | ||
1408 | * configured, we don't want to mess with them. | ||
1409 | * If they weren't, the default is 100% PWM, no | ||
1410 | * control and will suffice until 'sensors -s' | ||
1411 | * can be run by the user. | ||
1412 | */ | ||
1413 | |||
1414 | /* Start monitoring */ | ||
1415 | value = lm85_read_value(client, LM85_REG_CONFIG); | ||
1416 | /* Try to clear LOCK, Set START, save everything else */ | ||
1417 | value = (value & ~ 0x02) | 0x01 ; | ||
1418 | dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value); | ||
1419 | lm85_write_value(client, LM85_REG_CONFIG, value); | ||
1420 | } | 1340 | } |
1421 | 1341 | ||
1422 | static struct lm85_data *lm85_update_device(struct device *dev) | 1342 | static struct lm85_data *lm85_update_device(struct device *dev) |
@@ -1427,28 +1347,30 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1427 | 1347 | ||
1428 | mutex_lock(&data->update_lock); | 1348 | mutex_lock(&data->update_lock); |
1429 | 1349 | ||
1430 | if ( !data->valid || | 1350 | if (!data->valid || |
1431 | time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL) ) { | 1351 | time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) { |
1432 | /* Things that change quickly */ | 1352 | /* Things that change quickly */ |
1433 | dev_dbg(&client->dev, "Reading sensor values\n"); | 1353 | dev_dbg(&client->dev, "Reading sensor values\n"); |
1434 | 1354 | ||
1435 | /* Have to read extended bits first to "freeze" the | 1355 | /* Have to read extended bits first to "freeze" the |
1436 | * more significant bits that are read later. | 1356 | * more significant bits that are read later. |
1437 | * There are 2 additional resolution bits per channel and we | 1357 | * There are 2 additional resolution bits per channel and we |
1438 | * have room for 4, so we shift them to the left. | 1358 | * have room for 4, so we shift them to the left. |
1439 | */ | 1359 | */ |
1440 | if ( (data->type == adm1027) || (data->type == adt7463) ) { | 1360 | if (data->type == adm1027 || data->type == adt7463) { |
1441 | int ext1 = lm85_read_value(client, | 1361 | int ext1 = lm85_read_value(client, |
1442 | ADM1027_REG_EXTEND_ADC1); | 1362 | ADM1027_REG_EXTEND_ADC1); |
1443 | int ext2 = lm85_read_value(client, | 1363 | int ext2 = lm85_read_value(client, |
1444 | ADM1027_REG_EXTEND_ADC2); | 1364 | ADM1027_REG_EXTEND_ADC2); |
1445 | int val = (ext1 << 8) + ext2; | 1365 | int val = (ext1 << 8) + ext2; |
1446 | 1366 | ||
1447 | for(i = 0; i <= 4; i++) | 1367 | for (i = 0; i <= 4; i++) |
1448 | data->in_ext[i] = ((val>>(i * 2))&0x03) << 2; | 1368 | data->in_ext[i] = |
1369 | ((val >> (i * 2)) & 0x03) << 2; | ||
1449 | 1370 | ||
1450 | for(i = 0; i <= 2; i++) | 1371 | for (i = 0; i <= 2; i++) |
1451 | data->temp_ext[i] = (val>>((i + 4) * 2))&0x0c; | 1372 | data->temp_ext[i] = |
1373 | (val >> ((i + 4) * 2)) & 0x0c; | ||
1452 | } | 1374 | } |
1453 | 1375 | ||
1454 | data->vid = lm85_read_value(client, LM85_REG_VID); | 1376 | data->vid = lm85_read_value(client, LM85_REG_VID); |
@@ -1456,6 +1378,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1456 | for (i = 0; i <= 3; ++i) { | 1378 | for (i = 0; i <= 3; ++i) { |
1457 | data->in[i] = | 1379 | data->in[i] = |
1458 | lm85_read_value(client, LM85_REG_IN(i)); | 1380 | lm85_read_value(client, LM85_REG_IN(i)); |
1381 | data->fan[i] = | ||
1382 | lm85_read_value(client, LM85_REG_FAN(i)); | ||
1459 | } | 1383 | } |
1460 | 1384 | ||
1461 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1385 | if (!(data->type == adt7463 && (data->vid & 0x80))) { |
@@ -1463,38 +1387,25 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1463 | LM85_REG_IN(4)); | 1387 | LM85_REG_IN(4)); |
1464 | } | 1388 | } |
1465 | 1389 | ||
1466 | for (i = 0; i <= 3; ++i) { | ||
1467 | data->fan[i] = | ||
1468 | lm85_read_value(client, LM85_REG_FAN(i)); | ||
1469 | } | ||
1470 | |||
1471 | for (i = 0; i <= 2; ++i) { | 1390 | for (i = 0; i <= 2; ++i) { |
1472 | data->temp[i] = | 1391 | data->temp[i] = |
1473 | lm85_read_value(client, LM85_REG_TEMP(i)); | 1392 | lm85_read_value(client, LM85_REG_TEMP(i)); |
1474 | } | ||
1475 | |||
1476 | for (i = 0; i <= 2; ++i) { | ||
1477 | data->pwm[i] = | 1393 | data->pwm[i] = |
1478 | lm85_read_value(client, LM85_REG_PWM(i)); | 1394 | lm85_read_value(client, LM85_REG_PWM(i)); |
1479 | } | 1395 | } |
1480 | 1396 | ||
1481 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); | 1397 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); |
1482 | 1398 | ||
1483 | if ( data->type == adt7463 ) { | 1399 | if (data->type == emc6d100) { |
1484 | if( data->therm_total < ULONG_MAX - 256 ) { | ||
1485 | data->therm_total += | ||
1486 | lm85_read_value(client, ADT7463_REG_THERM ); | ||
1487 | } | ||
1488 | } else if ( data->type == emc6d100 ) { | ||
1489 | /* Three more voltage sensors */ | 1400 | /* Three more voltage sensors */ |
1490 | for (i = 5; i <= 7; ++i) { | 1401 | for (i = 5; i <= 7; ++i) { |
1491 | data->in[i] = | 1402 | data->in[i] = lm85_read_value(client, |
1492 | lm85_read_value(client, EMC6D100_REG_IN(i)); | 1403 | EMC6D100_REG_IN(i)); |
1493 | } | 1404 | } |
1494 | /* More alarm bits */ | 1405 | /* More alarm bits */ |
1495 | data->alarms |= | 1406 | data->alarms |= lm85_read_value(client, |
1496 | lm85_read_value(client, EMC6D100_REG_ALARM3) << 16; | 1407 | EMC6D100_REG_ALARM3) << 16; |
1497 | } else if (data->type == emc6d102 ) { | 1408 | } else if (data->type == emc6d102) { |
1498 | /* Have to read LSB bits after the MSB ones because | 1409 | /* Have to read LSB bits after the MSB ones because |
1499 | the reading of the MSB bits has frozen the | 1410 | the reading of the MSB bits has frozen the |
1500 | LSBs (backward from the ADM1027). | 1411 | LSBs (backward from the ADM1027). |
@@ -1509,20 +1420,20 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1509 | EMC6D102_REG_EXTEND_ADC4); | 1420 | EMC6D102_REG_EXTEND_ADC4); |
1510 | data->in_ext[0] = ext3 & 0x0f; | 1421 | data->in_ext[0] = ext3 & 0x0f; |
1511 | data->in_ext[1] = ext4 & 0x0f; | 1422 | data->in_ext[1] = ext4 & 0x0f; |
1512 | data->in_ext[2] = (ext4 >> 4) & 0x0f; | 1423 | data->in_ext[2] = ext4 >> 4; |
1513 | data->in_ext[3] = (ext3 >> 4) & 0x0f; | 1424 | data->in_ext[3] = ext3 >> 4; |
1514 | data->in_ext[4] = (ext2 >> 4) & 0x0f; | 1425 | data->in_ext[4] = ext2 >> 4; |
1515 | 1426 | ||
1516 | data->temp_ext[0] = ext1 & 0x0f; | 1427 | data->temp_ext[0] = ext1 & 0x0f; |
1517 | data->temp_ext[1] = ext2 & 0x0f; | 1428 | data->temp_ext[1] = ext2 & 0x0f; |
1518 | data->temp_ext[2] = (ext1 >> 4) & 0x0f; | 1429 | data->temp_ext[2] = ext1 >> 4; |
1519 | } | 1430 | } |
1520 | 1431 | ||
1521 | data->last_reading = jiffies ; | 1432 | data->last_reading = jiffies; |
1522 | }; /* last_reading */ | 1433 | } /* last_reading */ |
1523 | 1434 | ||
1524 | if ( !data->valid || | 1435 | if (!data->valid || |
1525 | time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL) ) { | 1436 | time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) { |
1526 | /* Things that don't change often */ | 1437 | /* Things that don't change often */ |
1527 | dev_dbg(&client->dev, "Reading config values\n"); | 1438 | dev_dbg(&client->dev, "Reading config values\n"); |
1528 | 1439 | ||
@@ -1531,6 +1442,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1531 | lm85_read_value(client, LM85_REG_IN_MIN(i)); | 1442 | lm85_read_value(client, LM85_REG_IN_MIN(i)); |
1532 | data->in_max[i] = | 1443 | data->in_max[i] = |
1533 | lm85_read_value(client, LM85_REG_IN_MAX(i)); | 1444 | lm85_read_value(client, LM85_REG_IN_MAX(i)); |
1445 | data->fan_min[i] = | ||
1446 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); | ||
1534 | } | 1447 | } |
1535 | 1448 | ||
1536 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1449 | if (!(data->type == adt7463 && (data->vid & 0x80))) { |
@@ -1540,34 +1453,28 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1540 | LM85_REG_IN_MAX(4)); | 1453 | LM85_REG_IN_MAX(4)); |
1541 | } | 1454 | } |
1542 | 1455 | ||
1543 | if ( data->type == emc6d100 ) { | 1456 | if (data->type == emc6d100) { |
1544 | for (i = 5; i <= 7; ++i) { | 1457 | for (i = 5; i <= 7; ++i) { |
1545 | data->in_min[i] = | 1458 | data->in_min[i] = lm85_read_value(client, |
1546 | lm85_read_value(client, EMC6D100_REG_IN_MIN(i)); | 1459 | EMC6D100_REG_IN_MIN(i)); |
1547 | data->in_max[i] = | 1460 | data->in_max[i] = lm85_read_value(client, |
1548 | lm85_read_value(client, EMC6D100_REG_IN_MAX(i)); | 1461 | EMC6D100_REG_IN_MAX(i)); |
1549 | } | 1462 | } |
1550 | } | 1463 | } |
1551 | 1464 | ||
1552 | for (i = 0; i <= 3; ++i) { | ||
1553 | data->fan_min[i] = | ||
1554 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); | ||
1555 | } | ||
1556 | |||
1557 | for (i = 0; i <= 2; ++i) { | 1465 | for (i = 0; i <= 2; ++i) { |
1466 | int val; | ||
1467 | |||
1558 | data->temp_min[i] = | 1468 | data->temp_min[i] = |
1559 | lm85_read_value(client, LM85_REG_TEMP_MIN(i)); | 1469 | lm85_read_value(client, LM85_REG_TEMP_MIN(i)); |
1560 | data->temp_max[i] = | 1470 | data->temp_max[i] = |
1561 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); | 1471 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); |
1562 | } | ||
1563 | 1472 | ||
1564 | for (i = 0; i <= 2; ++i) { | ||
1565 | int val ; | ||
1566 | data->autofan[i].config = | 1473 | data->autofan[i].config = |
1567 | lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); | 1474 | lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); |
1568 | val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); | 1475 | val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); |
1569 | data->autofan[i].freq = val & 0x07 ; | 1476 | data->pwm_freq[i] = val & 0x07; |
1570 | data->zone[i].range = (val >> 4) & 0x0f ; | 1477 | data->zone[i].range = val >> 4; |
1571 | data->autofan[i].min_pwm = | 1478 | data->autofan[i].min_pwm = |
1572 | lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); | 1479 | lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); |
1573 | data->zone[i].limit = | 1480 | data->zone[i].limit = |
@@ -1577,50 +1484,19 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1577 | } | 1484 | } |
1578 | 1485 | ||
1579 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); | 1486 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
1580 | data->smooth[0] = i & 0x0f ; | 1487 | data->autofan[0].min_off = (i & 0x20) != 0; |
1581 | data->syncpwm3 = i & 0x10 ; /* Save PWM3 config */ | 1488 | data->autofan[1].min_off = (i & 0x40) != 0; |
1582 | data->autofan[0].min_off = (i & 0x20) != 0 ; | 1489 | data->autofan[2].min_off = (i & 0x80) != 0; |
1583 | data->autofan[1].min_off = (i & 0x40) != 0 ; | ||
1584 | data->autofan[2].min_off = (i & 0x80) != 0 ; | ||
1585 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE2); | ||
1586 | data->smooth[1] = (i>>4) & 0x0f ; | ||
1587 | data->smooth[2] = i & 0x0f ; | ||
1588 | 1490 | ||
1589 | i = lm85_read_value(client, LM85_REG_AFAN_HYST1); | 1491 | i = lm85_read_value(client, LM85_REG_AFAN_HYST1); |
1590 | data->zone[0].hyst = (i>>4) & 0x0f ; | 1492 | data->zone[0].hyst = i >> 4; |
1591 | data->zone[1].hyst = i & 0x0f ; | 1493 | data->zone[1].hyst = i & 0x0f; |
1592 | 1494 | ||
1593 | i = lm85_read_value(client, LM85_REG_AFAN_HYST2); | 1495 | i = lm85_read_value(client, LM85_REG_AFAN_HYST2); |
1594 | data->zone[2].hyst = (i>>4) & 0x0f ; | 1496 | data->zone[2].hyst = i >> 4; |
1595 | 1497 | ||
1596 | if ( (data->type == lm85b) || (data->type == lm85c) ) { | ||
1597 | data->tach_mode = lm85_read_value(client, | ||
1598 | LM85_REG_TACH_MODE ); | ||
1599 | data->spinup_ctl = lm85_read_value(client, | ||
1600 | LM85_REG_SPINUP_CTL ); | ||
1601 | } else if ( (data->type == adt7463) || (data->type == adm1027) ) { | ||
1602 | if ( data->type == adt7463 ) { | ||
1603 | for (i = 0; i <= 2; ++i) { | ||
1604 | data->oppoint[i] = lm85_read_value(client, | ||
1605 | ADT7463_REG_OPPOINT(i) ); | ||
1606 | } | ||
1607 | data->tmin_ctl = lm85_read_value(client, | ||
1608 | ADT7463_REG_TMIN_CTL1 ); | ||
1609 | data->therm_limit = lm85_read_value(client, | ||
1610 | ADT7463_REG_THERM_LIMIT ); | ||
1611 | } | ||
1612 | for (i = 0; i <= 2; ++i) { | ||
1613 | data->temp_offset[i] = lm85_read_value(client, | ||
1614 | ADM1027_REG_TEMP_OFFSET(i) ); | ||
1615 | } | ||
1616 | data->tach_mode = lm85_read_value(client, | ||
1617 | ADM1027_REG_CONFIG3 ); | ||
1618 | data->fan_ppr = lm85_read_value(client, | ||
1619 | ADM1027_REG_FAN_PPR ); | ||
1620 | } | ||
1621 | |||
1622 | data->last_config = jiffies; | 1498 | data->last_config = jiffies; |
1623 | }; /* last_config */ | 1499 | } /* last_config */ |
1624 | 1500 | ||
1625 | data->valid = 1; | 1501 | data->valid = 1; |
1626 | 1502 | ||
@@ -1635,17 +1511,15 @@ static int __init sm_lm85_init(void) | |||
1635 | return i2c_add_driver(&lm85_driver); | 1511 | return i2c_add_driver(&lm85_driver); |
1636 | } | 1512 | } |
1637 | 1513 | ||
1638 | static void __exit sm_lm85_exit(void) | 1514 | static void __exit sm_lm85_exit(void) |
1639 | { | 1515 | { |
1640 | i2c_del_driver(&lm85_driver); | 1516 | i2c_del_driver(&lm85_driver); |
1641 | } | 1517 | } |
1642 | 1518 | ||
1643 | /* Thanks to Richard Barrington for adding the LM85 to sensors-detect. | ||
1644 | * Thanks to Margit Schubert-While <margitsw@t-online.de> for help with | ||
1645 | * post 2.7.0 CVS changes. | ||
1646 | */ | ||
1647 | MODULE_LICENSE("GPL"); | 1519 | MODULE_LICENSE("GPL"); |
1648 | MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, Margit Schubert-While <margitsw@t-online.de>, Justin Thiessen <jthiessen@penguincomputing.com"); | 1520 | MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " |
1521 | "Margit Schubert-While <margitsw@t-online.de>, " | ||
1522 | "Justin Thiessen <jthiessen@penguincomputing.com>"); | ||
1649 | MODULE_DESCRIPTION("LM85-B, LM85-C driver"); | 1523 | MODULE_DESCRIPTION("LM85-B, LM85-C driver"); |
1650 | 1524 | ||
1651 | module_init(sm_lm85_init); | 1525 | module_init(sm_lm85_init); |
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 21970f0d53a1..2e4a3cea95f7 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c | |||
@@ -21,11 +21,10 @@ | |||
21 | * http://www.national.com/pf/LM/LM87.html | 21 | * http://www.national.com/pf/LM/LM87.html |
22 | * | 22 | * |
23 | * Some functions share pins, so not all functions are available at the same | 23 | * Some functions share pins, so not all functions are available at the same |
24 | * time. Which are depends on the hardware setup. This driver assumes that | 24 | * time. Which are depends on the hardware setup. This driver normally |
25 | * the BIOS configured the chip correctly. In that respect, it differs from | 25 | * assumes that firmware configured the chip correctly. Where this is not |
26 | * the original driver (from lm_sensors for Linux 2.4), which would force the | 26 | * the case, platform code must set the I2C client's platform_data to point |
27 | * LM87 to an arbitrary, compile-time chosen mode, regardless of the actual | 27 | * to a u8 value to be written to the channel register. |
28 | * chipset wiring. | ||
29 | * For reference, here is the list of exclusive functions: | 28 | * For reference, here is the list of exclusive functions: |
30 | * - in0+in5 (default) or temp3 | 29 | * - in0+in5 (default) or temp3 |
31 | * - fan1 (default) or in6 | 30 | * - fan1 (default) or in6 |
@@ -199,6 +198,7 @@ struct lm87_data { | |||
199 | unsigned long last_updated; /* In jiffies */ | 198 | unsigned long last_updated; /* In jiffies */ |
200 | 199 | ||
201 | u8 channel; /* register value */ | 200 | u8 channel; /* register value */ |
201 | u8 config; /* original register value */ | ||
202 | 202 | ||
203 | u8 in[8]; /* register value */ | 203 | u8 in[8]; /* register value */ |
204 | u8 in_max[8]; /* register value */ | 204 | u8 in_max[8]; /* register value */ |
@@ -832,6 +832,7 @@ exit_remove: | |||
832 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group); | 832 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group); |
833 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); | 833 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); |
834 | exit_free: | 834 | exit_free: |
835 | lm87_write_value(new_client, LM87_REG_CONFIG, data->config); | ||
835 | kfree(data); | 836 | kfree(data); |
836 | exit: | 837 | exit: |
837 | return err; | 838 | return err; |
@@ -840,12 +841,17 @@ exit: | |||
840 | static void lm87_init_client(struct i2c_client *client) | 841 | static void lm87_init_client(struct i2c_client *client) |
841 | { | 842 | { |
842 | struct lm87_data *data = i2c_get_clientdata(client); | 843 | struct lm87_data *data = i2c_get_clientdata(client); |
843 | u8 config; | ||
844 | 844 | ||
845 | data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); | 845 | if (client->dev.platform_data) { |
846 | data->channel = *(u8 *)client->dev.platform_data; | ||
847 | lm87_write_value(client, | ||
848 | LM87_REG_CHANNEL_MODE, data->channel); | ||
849 | } else { | ||
850 | data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); | ||
851 | } | ||
852 | data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F; | ||
846 | 853 | ||
847 | config = lm87_read_value(client, LM87_REG_CONFIG); | 854 | if (!(data->config & 0x01)) { |
848 | if (!(config & 0x01)) { | ||
849 | int i; | 855 | int i; |
850 | 856 | ||
851 | /* Limits are left uninitialized after power-up */ | 857 | /* Limits are left uninitialized after power-up */ |
@@ -867,11 +873,11 @@ static void lm87_init_client(struct i2c_client *client) | |||
867 | lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF); | 873 | lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF); |
868 | } | 874 | } |
869 | } | 875 | } |
870 | if ((config & 0x81) != 0x01) { | 876 | |
871 | /* Start monitoring */ | 877 | /* Make sure Start is set and INT#_Clear is clear */ |
878 | if ((data->config & 0x09) != 0x01) | ||
872 | lm87_write_value(client, LM87_REG_CONFIG, | 879 | lm87_write_value(client, LM87_REG_CONFIG, |
873 | (config & 0xF7) | 0x01); | 880 | (data->config & 0x77) | 0x01); |
874 | } | ||
875 | } | 881 | } |
876 | 882 | ||
877 | static int lm87_remove(struct i2c_client *client) | 883 | static int lm87_remove(struct i2c_client *client) |
@@ -882,6 +888,7 @@ static int lm87_remove(struct i2c_client *client) | |||
882 | sysfs_remove_group(&client->dev.kobj, &lm87_group); | 888 | sysfs_remove_group(&client->dev.kobj, &lm87_group); |
883 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); | 889 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); |
884 | 890 | ||
891 | lm87_write_value(client, LM87_REG_CONFIG, data->config); | ||
885 | kfree(data); | 892 | kfree(data); |
886 | return 0; | 893 | return 0; |
887 | } | 894 | } |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index c24fe36ac787..96a701866726 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -1,63 +1,51 @@ | |||
1 | /* | 1 | /* |
2 | * lm90.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * lm90.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | * monitoring | 3 | * monitoring |
4 | * Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org> |
5 | * | 5 | * |
6 | * Based on the lm83 driver. The LM90 is a sensor chip made by National | 6 | * Based on the lm83 driver. The LM90 is a sensor chip made by National |
7 | * Semiconductor. It reports up to two temperatures (its own plus up to | 7 | * Semiconductor. It reports up to two temperatures (its own plus up to |
8 | * one external one) with a 0.125 deg resolution (1 deg for local | 8 | * one external one) with a 0.125 deg resolution (1 deg for local |
9 | * temperature) and a 3-4 deg accuracy. Complete datasheet can be | 9 | * temperature) and a 3-4 deg accuracy. |
10 | * obtained from National's website at: | ||
11 | * http://www.national.com/pf/LM/LM90.html | ||
12 | * | 10 | * |
13 | * This driver also supports the LM89 and LM99, two other sensor chips | 11 | * This driver also supports the LM89 and LM99, two other sensor chips |
14 | * made by National Semiconductor. Both have an increased remote | 12 | * made by National Semiconductor. Both have an increased remote |
15 | * temperature measurement accuracy (1 degree), and the LM99 | 13 | * temperature measurement accuracy (1 degree), and the LM99 |
16 | * additionally shifts remote temperatures (measured and limits) by 16 | 14 | * additionally shifts remote temperatures (measured and limits) by 16 |
17 | * degrees, which allows for higher temperatures measurement. The | 15 | * degrees, which allows for higher temperatures measurement. |
18 | * driver doesn't handle it since it can be done easily in user-space. | ||
19 | * Complete datasheets can be obtained from National's website at: | ||
20 | * http://www.national.com/pf/LM/LM89.html | ||
21 | * http://www.national.com/pf/LM/LM99.html | ||
22 | * Note that there is no way to differentiate between both chips. | 16 | * Note that there is no way to differentiate between both chips. |
17 | * When device is auto-detected, the driver will assume an LM99. | ||
23 | * | 18 | * |
24 | * This driver also supports the LM86, another sensor chip made by | 19 | * This driver also supports the LM86, another sensor chip made by |
25 | * National Semiconductor. It is exactly similar to the LM90 except it | 20 | * National Semiconductor. It is exactly similar to the LM90 except it |
26 | * has a higher accuracy. | 21 | * has a higher accuracy. |
27 | * Complete datasheet can be obtained from National's website at: | ||
28 | * http://www.national.com/pf/LM/LM86.html | ||
29 | * | 22 | * |
30 | * This driver also supports the ADM1032, a sensor chip made by Analog | 23 | * This driver also supports the ADM1032, a sensor chip made by Analog |
31 | * Devices. That chip is similar to the LM90, with a few differences | 24 | * Devices. That chip is similar to the LM90, with a few differences |
32 | * that are not handled by this driver. Complete datasheet can be | 25 | * that are not handled by this driver. Among others, it has a higher |
33 | * obtained from Analog's website at: | 26 | * accuracy than the LM90, much like the LM86 does. |
34 | * http://www.analog.com/en/prod/0,2877,ADM1032,00.html | ||
35 | * Among others, it has a higher accuracy than the LM90, much like the | ||
36 | * LM86 does. | ||
37 | * | 27 | * |
38 | * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor | 28 | * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor |
39 | * chips made by Maxim. These chips are similar to the LM86. Complete | 29 | * chips made by Maxim. These chips are similar to the LM86. |
40 | * datasheet can be obtained at Maxim's website at: | ||
41 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 | ||
42 | * Note that there is no easy way to differentiate between the three | 30 | * Note that there is no easy way to differentiate between the three |
43 | * variants. The extra address and features of the MAX6659 are not | 31 | * variants. The extra address and features of the MAX6659 are not |
44 | * supported by this driver. These chips lack the remote temperature | 32 | * supported by this driver. These chips lack the remote temperature |
45 | * offset feature. | 33 | * offset feature. |
46 | * | 34 | * |
35 | * This driver also supports the MAX6646, MAX6647 and MAX6649 chips | ||
36 | * made by Maxim. These are again similar to the LM86, but they use | ||
37 | * unsigned temperature values and can report temperatures from 0 to | ||
38 | * 145 degrees. | ||
39 | * | ||
47 | * This driver also supports the MAX6680 and MAX6681, two other sensor | 40 | * This driver also supports the MAX6680 and MAX6681, two other sensor |
48 | * chips made by Maxim. These are quite similar to the other Maxim | 41 | * chips made by Maxim. These are quite similar to the other Maxim |
49 | * chips. Complete datasheet can be obtained at: | 42 | * chips. The MAX6680 and MAX6681 only differ in the pinout so they can |
50 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | 43 | * be treated identically. |
51 | * The MAX6680 and MAX6681 only differ in the pinout so they can be | ||
52 | * treated identically. | ||
53 | * | 44 | * |
54 | * This driver also supports the ADT7461 chip from Analog Devices but | 45 | * This driver also supports the ADT7461 chip from Analog Devices. |
55 | * only in its "compatability mode". If an ADT7461 chip is found but | 46 | * It's supported in both compatibility and extended mode. It is mostly |
56 | * is configured in non-compatible mode (where its temperature | 47 | * compatible with LM90 except for a data format difference for the |
57 | * register values are decoded differently) it is ignored by this | 48 | * temperature value registers. |
58 | * driver. Complete datasheet can be obtained from Analog's website | ||
59 | * at: | ||
60 | * http://www.analog.com/en/prod/0,2877,ADT7461,00.html | ||
61 | * | 49 | * |
62 | * Since the LM90 was the first chipset supported by this driver, most | 50 | * Since the LM90 was the first chipset supported by this driver, most |
63 | * comments will refer to this chipset, but are actually general and | 51 | * comments will refer to this chipset, but are actually general and |
@@ -93,9 +81,10 @@ | |||
93 | * Addresses to scan | 81 | * Addresses to scan |
94 | * Address is fully defined internally and cannot be changed except for | 82 | * Address is fully defined internally and cannot be changed except for |
95 | * MAX6659, MAX6680 and MAX6681. | 83 | * MAX6659, MAX6680 and MAX6681. |
96 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 | 84 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6649, MAX6657 |
97 | * have address 0x4c. | 85 | * and MAX6658 have address 0x4c. |
98 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. | 86 | * ADM1032-2, ADT7461-2, LM89-1, LM99-1 and MAX6646 have address 0x4d. |
87 | * MAX6647 has address 0x4e. | ||
99 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). | 88 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). |
100 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | 89 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, |
101 | * 0x4c, 0x4d or 0x4e. | 90 | * 0x4c, 0x4d or 0x4e. |
@@ -108,7 +97,8 @@ static const unsigned short normal_i2c[] = { | |||
108 | * Insmod parameters | 97 | * Insmod parameters |
109 | */ | 98 | */ |
110 | 99 | ||
111 | I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); | 100 | I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, |
101 | max6646); | ||
112 | 102 | ||
113 | /* | 103 | /* |
114 | * The LM90 registers | 104 | * The LM90 registers |
@@ -149,39 +139,14 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); | |||
149 | #define LM90_REG_R_TCRIT_HYST 0x21 | 139 | #define LM90_REG_R_TCRIT_HYST 0x21 |
150 | #define LM90_REG_W_TCRIT_HYST 0x21 | 140 | #define LM90_REG_W_TCRIT_HYST 0x21 |
151 | 141 | ||
152 | /* | 142 | /* MAX6646/6647/6649/6657/6658/6659 registers */ |
153 | * Conversions and various macros | ||
154 | * For local temperatures and limits, critical limits and the hysteresis | ||
155 | * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. | ||
156 | * For remote temperatures and limits, it uses signed 11-bit values with | ||
157 | * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. | ||
158 | */ | ||
159 | 143 | ||
160 | #define TEMP1_FROM_REG(val) ((val) * 1000) | 144 | #define MAX6657_REG_R_LOCAL_TEMPL 0x11 |
161 | #define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \ | ||
162 | (val) >= 127000 ? 127 : \ | ||
163 | (val) < 0 ? ((val) - 500) / 1000 : \ | ||
164 | ((val) + 500) / 1000) | ||
165 | #define TEMP2_FROM_REG(val) ((val) / 32 * 125) | ||
166 | #define TEMP2_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ | ||
167 | (val) >= 127875 ? 0x7FE0 : \ | ||
168 | (val) < 0 ? ((val) - 62) / 125 * 32 : \ | ||
169 | ((val) + 62) / 125 * 32) | ||
170 | #define HYST_TO_REG(val) ((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \ | ||
171 | ((val) + 500) / 1000) | ||
172 | |||
173 | /* | ||
174 | * ADT7461 is almost identical to LM90 except that attempts to write | ||
175 | * values that are outside the range 0 < temp < 127 are treated as | ||
176 | * the boundary value. | ||
177 | */ | ||
178 | 145 | ||
179 | #define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \ | 146 | /* |
180 | (val) >= 127000 ? 127 : \ | 147 | * Device flags |
181 | ((val) + 500) / 1000) | 148 | */ |
182 | #define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \ | 149 | #define LM90_FLAG_ADT7461_EXT 0x01 /* ADT7461 extended mode */ |
183 | (val) >= 127750 ? 0x7FC0 : \ | ||
184 | ((val) + 125) / 250 * 64) | ||
185 | 150 | ||
186 | /* | 151 | /* |
187 | * Functions declaration | 152 | * Functions declaration |
@@ -204,8 +169,11 @@ static const struct i2c_device_id lm90_id[] = { | |||
204 | { "adt7461", adt7461 }, | 169 | { "adt7461", adt7461 }, |
205 | { "lm90", lm90 }, | 170 | { "lm90", lm90 }, |
206 | { "lm86", lm86 }, | 171 | { "lm86", lm86 }, |
207 | { "lm89", lm99 }, | 172 | { "lm89", lm86 }, |
208 | { "lm99", lm99 }, /* Missing temperature offset */ | 173 | { "lm99", lm99 }, |
174 | { "max6646", max6646 }, | ||
175 | { "max6647", max6646 }, | ||
176 | { "max6649", max6646 }, | ||
209 | { "max6657", max6657 }, | 177 | { "max6657", max6657 }, |
210 | { "max6658", max6657 }, | 178 | { "max6658", max6657 }, |
211 | { "max6659", max6657 }, | 179 | { "max6659", max6657 }, |
@@ -237,22 +205,150 @@ struct lm90_data { | |||
237 | char valid; /* zero until following fields are valid */ | 205 | char valid; /* zero until following fields are valid */ |
238 | unsigned long last_updated; /* in jiffies */ | 206 | unsigned long last_updated; /* in jiffies */ |
239 | int kind; | 207 | int kind; |
208 | int flags; | ||
240 | 209 | ||
241 | /* registers values */ | 210 | /* registers values */ |
242 | s8 temp8[5]; /* 0: local input | 211 | s8 temp8[4]; /* 0: local low limit |
243 | 1: local low limit | 212 | 1: local high limit |
244 | 2: local high limit | 213 | 2: local critical limit |
245 | 3: local critical limit | 214 | 3: remote critical limit */ |
246 | 4: remote critical limit */ | 215 | s16 temp11[5]; /* 0: remote input |
247 | s16 temp11[4]; /* 0: remote input | ||
248 | 1: remote low limit | 216 | 1: remote low limit |
249 | 2: remote high limit | 217 | 2: remote high limit |
250 | 3: remote offset (except max6657) */ | 218 | 3: remote offset (except max6646 and max6657) |
219 | 4: local input */ | ||
251 | u8 temp_hyst; | 220 | u8 temp_hyst; |
252 | u8 alarms; /* bitvector */ | 221 | u8 alarms; /* bitvector */ |
253 | }; | 222 | }; |
254 | 223 | ||
255 | /* | 224 | /* |
225 | * Conversions | ||
226 | * For local temperatures and limits, critical limits and the hysteresis | ||
227 | * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. | ||
228 | * For remote temperatures and limits, it uses signed 11-bit values with | ||
229 | * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. Some | ||
230 | * Maxim chips use unsigned values. | ||
231 | */ | ||
232 | |||
233 | static inline int temp_from_s8(s8 val) | ||
234 | { | ||
235 | return val * 1000; | ||
236 | } | ||
237 | |||
238 | static inline int temp_from_u8(u8 val) | ||
239 | { | ||
240 | return val * 1000; | ||
241 | } | ||
242 | |||
243 | static inline int temp_from_s16(s16 val) | ||
244 | { | ||
245 | return val / 32 * 125; | ||
246 | } | ||
247 | |||
248 | static inline int temp_from_u16(u16 val) | ||
249 | { | ||
250 | return val / 32 * 125; | ||
251 | } | ||
252 | |||
253 | static s8 temp_to_s8(long val) | ||
254 | { | ||
255 | if (val <= -128000) | ||
256 | return -128; | ||
257 | if (val >= 127000) | ||
258 | return 127; | ||
259 | if (val < 0) | ||
260 | return (val - 500) / 1000; | ||
261 | return (val + 500) / 1000; | ||
262 | } | ||
263 | |||
264 | static u8 temp_to_u8(long val) | ||
265 | { | ||
266 | if (val <= 0) | ||
267 | return 0; | ||
268 | if (val >= 255000) | ||
269 | return 255; | ||
270 | return (val + 500) / 1000; | ||
271 | } | ||
272 | |||
273 | static s16 temp_to_s16(long val) | ||
274 | { | ||
275 | if (val <= -128000) | ||
276 | return 0x8000; | ||
277 | if (val >= 127875) | ||
278 | return 0x7FE0; | ||
279 | if (val < 0) | ||
280 | return (val - 62) / 125 * 32; | ||
281 | return (val + 62) / 125 * 32; | ||
282 | } | ||
283 | |||
284 | static u8 hyst_to_reg(long val) | ||
285 | { | ||
286 | if (val <= 0) | ||
287 | return 0; | ||
288 | if (val >= 30500) | ||
289 | return 31; | ||
290 | return (val + 500) / 1000; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * ADT7461 in compatibility mode is almost identical to LM90 except that | ||
295 | * attempts to write values that are outside the range 0 < temp < 127 are | ||
296 | * treated as the boundary value. | ||
297 | * | ||
298 | * ADT7461 in "extended mode" operation uses unsigned integers offset by | ||
299 | * 64 (e.g., 0 -> -64 degC). The range is restricted to -64..191 degC. | ||
300 | */ | ||
301 | static inline int temp_from_u8_adt7461(struct lm90_data *data, u8 val) | ||
302 | { | ||
303 | if (data->flags & LM90_FLAG_ADT7461_EXT) | ||
304 | return (val - 64) * 1000; | ||
305 | else | ||
306 | return temp_from_s8(val); | ||
307 | } | ||
308 | |||
309 | static inline int temp_from_u16_adt7461(struct lm90_data *data, u16 val) | ||
310 | { | ||
311 | if (data->flags & LM90_FLAG_ADT7461_EXT) | ||
312 | return (val - 0x4000) / 64 * 250; | ||
313 | else | ||
314 | return temp_from_s16(val); | ||
315 | } | ||
316 | |||
317 | static u8 temp_to_u8_adt7461(struct lm90_data *data, long val) | ||
318 | { | ||
319 | if (data->flags & LM90_FLAG_ADT7461_EXT) { | ||
320 | if (val <= -64000) | ||
321 | return 0; | ||
322 | if (val >= 191000) | ||
323 | return 0xFF; | ||
324 | return (val + 500 + 64000) / 1000; | ||
325 | } else { | ||
326 | if (val <= 0) | ||
327 | return 0; | ||
328 | if (val >= 127000) | ||
329 | return 127; | ||
330 | return (val + 500) / 1000; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | static u16 temp_to_u16_adt7461(struct lm90_data *data, long val) | ||
335 | { | ||
336 | if (data->flags & LM90_FLAG_ADT7461_EXT) { | ||
337 | if (val <= -64000) | ||
338 | return 0; | ||
339 | if (val >= 191750) | ||
340 | return 0xFFC0; | ||
341 | return (val + 64000 + 125) / 250 * 64; | ||
342 | } else { | ||
343 | if (val <= 0) | ||
344 | return 0; | ||
345 | if (val >= 127750) | ||
346 | return 0x7FC0; | ||
347 | return (val + 125) / 250 * 64; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | /* | ||
256 | * Sysfs stuff | 352 | * Sysfs stuff |
257 | */ | 353 | */ |
258 | 354 | ||
@@ -261,7 +357,20 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | |||
261 | { | 357 | { |
262 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 358 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
263 | struct lm90_data *data = lm90_update_device(dev); | 359 | struct lm90_data *data = lm90_update_device(dev); |
264 | return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index])); | 360 | int temp; |
361 | |||
362 | if (data->kind == adt7461) | ||
363 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | ||
364 | else if (data->kind == max6646) | ||
365 | temp = temp_from_u8(data->temp8[attr->index]); | ||
366 | else | ||
367 | temp = temp_from_s8(data->temp8[attr->index]); | ||
368 | |||
369 | /* +16 degrees offset for temp2 for the LM99 */ | ||
370 | if (data->kind == lm99 && attr->index == 3) | ||
371 | temp += 16000; | ||
372 | |||
373 | return sprintf(buf, "%d\n", temp); | ||
265 | } | 374 | } |
266 | 375 | ||
267 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | 376 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, |
@@ -280,12 +389,18 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
280 | long val = simple_strtol(buf, NULL, 10); | 389 | long val = simple_strtol(buf, NULL, 10); |
281 | int nr = attr->index; | 390 | int nr = attr->index; |
282 | 391 | ||
392 | /* +16 degrees offset for temp2 for the LM99 */ | ||
393 | if (data->kind == lm99 && attr->index == 3) | ||
394 | val -= 16000; | ||
395 | |||
283 | mutex_lock(&data->update_lock); | 396 | mutex_lock(&data->update_lock); |
284 | if (data->kind == adt7461) | 397 | if (data->kind == adt7461) |
285 | data->temp8[nr] = TEMP1_TO_REG_ADT7461(val); | 398 | data->temp8[nr] = temp_to_u8_adt7461(data, val); |
399 | else if (data->kind == max6646) | ||
400 | data->temp8[nr] = temp_to_u8(val); | ||
286 | else | 401 | else |
287 | data->temp8[nr] = TEMP1_TO_REG(val); | 402 | data->temp8[nr] = temp_to_s8(val); |
288 | i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]); | 403 | i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); |
289 | mutex_unlock(&data->update_lock); | 404 | mutex_unlock(&data->update_lock); |
290 | return count; | 405 | return count; |
291 | } | 406 | } |
@@ -295,7 +410,20 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
295 | { | 410 | { |
296 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 411 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
297 | struct lm90_data *data = lm90_update_device(dev); | 412 | struct lm90_data *data = lm90_update_device(dev); |
298 | return sprintf(buf, "%d\n", TEMP2_FROM_REG(data->temp11[attr->index])); | 413 | int temp; |
414 | |||
415 | if (data->kind == adt7461) | ||
416 | temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); | ||
417 | else if (data->kind == max6646) | ||
418 | temp = temp_from_u16(data->temp11[attr->index]); | ||
419 | else | ||
420 | temp = temp_from_s16(data->temp11[attr->index]); | ||
421 | |||
422 | /* +16 degrees offset for temp2 for the LM99 */ | ||
423 | if (data->kind == lm99 && attr->index <= 2) | ||
424 | temp += 16000; | ||
425 | |||
426 | return sprintf(buf, "%d\n", temp); | ||
299 | } | 427 | } |
300 | 428 | ||
301 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 429 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, |
@@ -316,15 +444,26 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
316 | long val = simple_strtol(buf, NULL, 10); | 444 | long val = simple_strtol(buf, NULL, 10); |
317 | int nr = attr->index; | 445 | int nr = attr->index; |
318 | 446 | ||
447 | /* +16 degrees offset for temp2 for the LM99 */ | ||
448 | if (data->kind == lm99 && attr->index <= 2) | ||
449 | val -= 16000; | ||
450 | |||
319 | mutex_lock(&data->update_lock); | 451 | mutex_lock(&data->update_lock); |
320 | if (data->kind == adt7461) | 452 | if (data->kind == adt7461) |
321 | data->temp11[nr] = TEMP2_TO_REG_ADT7461(val); | 453 | data->temp11[nr] = temp_to_u16_adt7461(data, val); |
454 | else if (data->kind == max6657 || data->kind == max6680) | ||
455 | data->temp11[nr] = temp_to_s8(val) << 8; | ||
456 | else if (data->kind == max6646) | ||
457 | data->temp11[nr] = temp_to_u8(val) << 8; | ||
322 | else | 458 | else |
323 | data->temp11[nr] = TEMP2_TO_REG(val); | 459 | data->temp11[nr] = temp_to_s16(val); |
460 | |||
324 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], | 461 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], |
325 | data->temp11[nr] >> 8); | 462 | data->temp11[nr] >> 8); |
326 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], | 463 | if (data->kind != max6657 && data->kind != max6680 |
327 | data->temp11[nr] & 0xff); | 464 | && data->kind != max6646) |
465 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], | ||
466 | data->temp11[nr] & 0xff); | ||
328 | mutex_unlock(&data->update_lock); | 467 | mutex_unlock(&data->update_lock); |
329 | return count; | 468 | return count; |
330 | } | 469 | } |
@@ -334,8 +473,20 @@ static ssize_t show_temphyst(struct device *dev, struct device_attribute *devatt | |||
334 | { | 473 | { |
335 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 474 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
336 | struct lm90_data *data = lm90_update_device(dev); | 475 | struct lm90_data *data = lm90_update_device(dev); |
337 | return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index]) | 476 | int temp; |
338 | - TEMP1_FROM_REG(data->temp_hyst)); | 477 | |
478 | if (data->kind == adt7461) | ||
479 | temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); | ||
480 | else if (data->kind == max6646) | ||
481 | temp = temp_from_u8(data->temp8[attr->index]); | ||
482 | else | ||
483 | temp = temp_from_s8(data->temp8[attr->index]); | ||
484 | |||
485 | /* +16 degrees offset for temp2 for the LM99 */ | ||
486 | if (data->kind == lm99 && attr->index == 3) | ||
487 | temp += 16000; | ||
488 | |||
489 | return sprintf(buf, "%d\n", temp - temp_from_s8(data->temp_hyst)); | ||
339 | } | 490 | } |
340 | 491 | ||
341 | static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, | 492 | static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, |
@@ -344,12 +495,19 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, | |||
344 | struct i2c_client *client = to_i2c_client(dev); | 495 | struct i2c_client *client = to_i2c_client(dev); |
345 | struct lm90_data *data = i2c_get_clientdata(client); | 496 | struct lm90_data *data = i2c_get_clientdata(client); |
346 | long val = simple_strtol(buf, NULL, 10); | 497 | long val = simple_strtol(buf, NULL, 10); |
347 | long hyst; | 498 | int temp; |
348 | 499 | ||
349 | mutex_lock(&data->update_lock); | 500 | mutex_lock(&data->update_lock); |
350 | hyst = TEMP1_FROM_REG(data->temp8[3]) - val; | 501 | if (data->kind == adt7461) |
502 | temp = temp_from_u8_adt7461(data, data->temp8[2]); | ||
503 | else if (data->kind == max6646) | ||
504 | temp = temp_from_u8(data->temp8[2]); | ||
505 | else | ||
506 | temp = temp_from_s8(data->temp8[2]); | ||
507 | |||
508 | data->temp_hyst = hyst_to_reg(temp - val); | ||
351 | i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, | 509 | i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, |
352 | HYST_TO_REG(hyst)); | 510 | data->temp_hyst); |
353 | mutex_unlock(&data->update_lock); | 511 | mutex_unlock(&data->update_lock); |
354 | return count; | 512 | return count; |
355 | } | 513 | } |
@@ -371,23 +529,23 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute | |||
371 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | 529 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); |
372 | } | 530 | } |
373 | 531 | ||
374 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0); | 532 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 4); |
375 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); | 533 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); |
376 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, | 534 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, |
377 | set_temp8, 1); | 535 | set_temp8, 0); |
378 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, | 536 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, |
379 | set_temp11, 1); | 537 | set_temp11, 1); |
380 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, | 538 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, |
381 | set_temp8, 2); | 539 | set_temp8, 1); |
382 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, | 540 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, |
383 | set_temp11, 2); | 541 | set_temp11, 2); |
384 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, | 542 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, |
385 | set_temp8, 3); | 543 | set_temp8, 2); |
386 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, | 544 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, |
387 | set_temp8, 4); | 545 | set_temp8, 3); |
388 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, | 546 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, |
389 | set_temphyst, 3); | 547 | set_temphyst, 2); |
390 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); | 548 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 3); |
391 | static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, | 549 | static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, |
392 | set_temp11, 3); | 550 | set_temp11, 3); |
393 | 551 | ||
@@ -553,6 +711,15 @@ static int lm90_detect(struct i2c_client *new_client, int kind, | |||
553 | } else | 711 | } else |
554 | if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */ | 712 | if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */ |
555 | kind = lm99; | 713 | kind = lm99; |
714 | dev_info(&adapter->dev, | ||
715 | "Assuming LM99 chip at " | ||
716 | "0x%02x\n", address); | ||
717 | dev_info(&adapter->dev, | ||
718 | "If it is an LM89, pass " | ||
719 | "force_lm86=%d,0x%02x when " | ||
720 | "loading the lm90 driver\n", | ||
721 | i2c_adapter_id(adapter), | ||
722 | address); | ||
556 | } else | 723 | } else |
557 | if (address == 0x4C | 724 | if (address == 0x4C |
558 | && (chip_id & 0xF0) == 0x10) { /* LM86 */ | 725 | && (chip_id & 0xF0) == 0x10) { /* LM86 */ |
@@ -568,7 +735,7 @@ static int lm90_detect(struct i2c_client *new_client, int kind, | |||
568 | kind = adm1032; | 735 | kind = adm1032; |
569 | } else | 736 | } else |
570 | if (chip_id == 0x51 /* ADT7461 */ | 737 | if (chip_id == 0x51 /* ADT7461 */ |
571 | && (reg_config1 & 0x1F) == 0x00 /* check compat mode */ | 738 | && (reg_config1 & 0x1B) == 0x00 |
572 | && reg_convrate <= 0x0A) { | 739 | && reg_convrate <= 0x0A) { |
573 | kind = adt7461; | 740 | kind = adt7461; |
574 | } | 741 | } |
@@ -599,13 +766,23 @@ static int lm90_detect(struct i2c_client *new_client, int kind, | |||
599 | && (reg_config1 & 0x03) == 0x00 | 766 | && (reg_config1 & 0x03) == 0x00 |
600 | && reg_convrate <= 0x07) { | 767 | && reg_convrate <= 0x07) { |
601 | kind = max6680; | 768 | kind = max6680; |
769 | } else | ||
770 | /* The chip_id register of the MAX6646/6647/6649 | ||
771 | * holds the revision of the chip. | ||
772 | * The lowest 6 bits of the config1 register are | ||
773 | * unused and should return zero when read. | ||
774 | */ | ||
775 | if (chip_id == 0x59 | ||
776 | && (reg_config1 & 0x3f) == 0x00 | ||
777 | && reg_convrate <= 0x07) { | ||
778 | kind = max6646; | ||
602 | } | 779 | } |
603 | } | 780 | } |
604 | 781 | ||
605 | if (kind <= 0) { /* identification failed */ | 782 | if (kind <= 0) { /* identification failed */ |
606 | dev_info(&adapter->dev, | 783 | dev_dbg(&adapter->dev, |
607 | "Unsupported chip (man_id=0x%02X, " | 784 | "Unsupported chip at 0x%02x (man_id=0x%02X, " |
608 | "chip_id=0x%02X).\n", man_id, chip_id); | 785 | "chip_id=0x%02X)\n", address, man_id, chip_id); |
609 | return -ENODEV; | 786 | return -ENODEV; |
610 | } | 787 | } |
611 | } | 788 | } |
@@ -629,6 +806,8 @@ static int lm90_detect(struct i2c_client *new_client, int kind, | |||
629 | name = "max6680"; | 806 | name = "max6680"; |
630 | } else if (kind == adt7461) { | 807 | } else if (kind == adt7461) { |
631 | name = "adt7461"; | 808 | name = "adt7461"; |
809 | } else if (kind == max6646) { | ||
810 | name = "max6646"; | ||
632 | } | 811 | } |
633 | strlcpy(info->type, name, I2C_NAME_SIZE); | 812 | strlcpy(info->type, name, I2C_NAME_SIZE); |
634 | 813 | ||
@@ -668,7 +847,7 @@ static int lm90_probe(struct i2c_client *new_client, | |||
668 | &dev_attr_pec))) | 847 | &dev_attr_pec))) |
669 | goto exit_remove_files; | 848 | goto exit_remove_files; |
670 | } | 849 | } |
671 | if (data->kind != max6657) { | 850 | if (data->kind != max6657 && data->kind != max6646) { |
672 | if ((err = device_create_file(&new_client->dev, | 851 | if ((err = device_create_file(&new_client->dev, |
673 | &sensor_dev_attr_temp2_offset.dev_attr))) | 852 | &sensor_dev_attr_temp2_offset.dev_attr))) |
674 | goto exit_remove_files; | 853 | goto exit_remove_files; |
@@ -707,6 +886,12 @@ static void lm90_init_client(struct i2c_client *client) | |||
707 | } | 886 | } |
708 | config_orig = config; | 887 | config_orig = config; |
709 | 888 | ||
889 | /* Check Temperature Range Select */ | ||
890 | if (data->kind == adt7461) { | ||
891 | if (config & 0x04) | ||
892 | data->flags |= LM90_FLAG_ADT7461_EXT; | ||
893 | } | ||
894 | |||
710 | /* | 895 | /* |
711 | * Put MAX6680/MAX8881 into extended resolution (bit 0x10, | 896 | * Put MAX6680/MAX8881 into extended resolution (bit 0x10, |
712 | * 0.125 degree resolution) and range (0x08, extend range | 897 | * 0.125 degree resolution) and range (0x08, extend range |
@@ -728,7 +913,7 @@ static int lm90_remove(struct i2c_client *client) | |||
728 | hwmon_device_unregister(data->hwmon_dev); | 913 | hwmon_device_unregister(data->hwmon_dev); |
729 | sysfs_remove_group(&client->dev.kobj, &lm90_group); | 914 | sysfs_remove_group(&client->dev.kobj, &lm90_group); |
730 | device_remove_file(&client->dev, &dev_attr_pec); | 915 | device_remove_file(&client->dev, &dev_attr_pec); |
731 | if (data->kind != max6657) | 916 | if (data->kind != max6657 && data->kind != max6646) |
732 | device_remove_file(&client->dev, | 917 | device_remove_file(&client->dev, |
733 | &sensor_dev_attr_temp2_offset.dev_attr); | 918 | &sensor_dev_attr_temp2_offset.dev_attr); |
734 | 919 | ||
@@ -736,6 +921,38 @@ static int lm90_remove(struct i2c_client *client) | |||
736 | return 0; | 921 | return 0; |
737 | } | 922 | } |
738 | 923 | ||
924 | static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) | ||
925 | { | ||
926 | int err; | ||
927 | u8 oldh, newh, l; | ||
928 | |||
929 | /* | ||
930 | * There is a trick here. We have to read two registers to have the | ||
931 | * sensor temperature, but we have to beware a conversion could occur | ||
932 | * inbetween the readings. The datasheet says we should either use | ||
933 | * the one-shot conversion register, which we don't want to do | ||
934 | * (disables hardware monitoring) or monitor the busy bit, which is | ||
935 | * impossible (we can't read the values and monitor that bit at the | ||
936 | * exact same time). So the solution used here is to read the high | ||
937 | * byte once, then the low byte, then the high byte again. If the new | ||
938 | * high byte matches the old one, then we have a valid reading. Else | ||
939 | * we have to read the low byte again, and now we believe we have a | ||
940 | * correct reading. | ||
941 | */ | ||
942 | if ((err = lm90_read_reg(client, regh, &oldh)) | ||
943 | || (err = lm90_read_reg(client, regl, &l)) | ||
944 | || (err = lm90_read_reg(client, regh, &newh))) | ||
945 | return err; | ||
946 | if (oldh != newh) { | ||
947 | err = lm90_read_reg(client, regl, &l); | ||
948 | if (err) | ||
949 | return err; | ||
950 | } | ||
951 | *value = (newh << 8) | l; | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
739 | static struct lm90_data *lm90_update_device(struct device *dev) | 956 | static struct lm90_data *lm90_update_device(struct device *dev) |
740 | { | 957 | { |
741 | struct i2c_client *client = to_i2c_client(dev); | 958 | struct i2c_client *client = to_i2c_client(dev); |
@@ -744,49 +961,50 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
744 | mutex_lock(&data->update_lock); | 961 | mutex_lock(&data->update_lock); |
745 | 962 | ||
746 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 963 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { |
747 | u8 oldh, newh, l; | 964 | u8 h, l; |
748 | 965 | ||
749 | dev_dbg(&client->dev, "Updating lm90 data.\n"); | 966 | dev_dbg(&client->dev, "Updating lm90 data.\n"); |
750 | lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); | 967 | lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); |
751 | lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]); | 968 | lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]); |
752 | lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]); | 969 | lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]); |
753 | lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]); | 970 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); |
754 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]); | ||
755 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); | 971 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); |
756 | 972 | ||
757 | /* | 973 | if (data->kind == max6657 || data->kind == max6646) { |
758 | * There is a trick here. We have to read two registers to | 974 | lm90_read16(client, LM90_REG_R_LOCAL_TEMP, |
759 | * have the remote sensor temperature, but we have to beware | 975 | MAX6657_REG_R_LOCAL_TEMPL, |
760 | * a conversion could occur inbetween the readings. The | 976 | &data->temp11[4]); |
761 | * datasheet says we should either use the one-shot | 977 | } else { |
762 | * conversion register, which we don't want to do (disables | 978 | if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, |
763 | * hardware monitoring) or monitor the busy bit, which is | 979 | &h) == 0) |
764 | * impossible (we can't read the values and monitor that bit | 980 | data->temp11[4] = h << 8; |
765 | * at the exact same time). So the solution used here is to | 981 | } |
766 | * read the high byte once, then the low byte, then the high | 982 | lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, |
767 | * byte again. If the new high byte matches the old one, | 983 | LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); |
768 | * then we have a valid reading. Else we have to read the low | 984 | |
769 | * byte again, and now we believe we have a correct reading. | 985 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { |
770 | */ | 986 | data->temp11[1] = h << 8; |
771 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0 | 987 | if (data->kind != max6657 && data->kind != max6680 |
772 | && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0 | 988 | && data->kind != max6646 |
773 | && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0 | 989 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, |
774 | && (newh == oldh | 990 | &l) == 0) |
775 | || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0)) | 991 | data->temp11[1] |= l; |
776 | data->temp11[0] = (newh << 8) | l; | 992 | } |
777 | 993 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { | |
778 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0 | 994 | data->temp11[2] = h << 8; |
779 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) | 995 | if (data->kind != max6657 && data->kind != max6680 |
780 | data->temp11[1] = (newh << 8) | l; | 996 | && data->kind != max6646 |
781 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 | 997 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, |
782 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) | 998 | &l) == 0) |
783 | data->temp11[2] = (newh << 8) | l; | 999 | data->temp11[2] |= l; |
784 | if (data->kind != max6657) { | 1000 | } |
1001 | |||
1002 | if (data->kind != max6657 && data->kind != max6646) { | ||
785 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, | 1003 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, |
786 | &newh) == 0 | 1004 | &h) == 0 |
787 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, | 1005 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, |
788 | &l) == 0) | 1006 | &l) == 0) |
789 | data->temp11[3] = (newh << 8) | l; | 1007 | data->temp11[3] = (h << 8) | l; |
790 | } | 1008 | } |
791 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); | 1009 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); |
792 | 1010 | ||
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c new file mode 100644 index 000000000000..bfaa665ccf32 --- /dev/null +++ b/drivers/hwmon/max1111.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * max1111.c - +2.7V, Low-Power, Multichannel, Serial 8-bit ADCs | ||
3 | * | ||
4 | * Based on arch/arm/mach-pxa/corgi_ssp.c | ||
5 | * | ||
6 | * Copyright (C) 2004-2005 Richard Purdie | ||
7 | * | ||
8 | * Copyright (C) 2008 Marvell International Ltd. | ||
9 | * Eric Miao <eric.miao@marvell.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * publishhed by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/hwmon.h> | ||
21 | #include <linux/hwmon-sysfs.h> | ||
22 | #include <linux/spi/spi.h> | ||
23 | |||
24 | #define MAX1111_TX_BUF_SIZE 1 | ||
25 | #define MAX1111_RX_BUF_SIZE 2 | ||
26 | |||
27 | /* MAX1111 Commands */ | ||
28 | #define MAX1111_CTRL_PD0 (1u << 0) | ||
29 | #define MAX1111_CTRL_PD1 (1u << 1) | ||
30 | #define MAX1111_CTRL_SGL (1u << 2) | ||
31 | #define MAX1111_CTRL_UNI (1u << 3) | ||
32 | #define MAX1111_CTRL_SEL_SH (5) /* NOTE: bit 4 is ignored */ | ||
33 | #define MAX1111_CTRL_STR (1u << 7) | ||
34 | |||
35 | struct max1111_data { | ||
36 | struct spi_device *spi; | ||
37 | struct device *hwmon_dev; | ||
38 | struct spi_message msg; | ||
39 | struct spi_transfer xfer[2]; | ||
40 | uint8_t *tx_buf; | ||
41 | uint8_t *rx_buf; | ||
42 | }; | ||
43 | |||
44 | static int max1111_read(struct device *dev, int channel) | ||
45 | { | ||
46 | struct max1111_data *data = dev_get_drvdata(dev); | ||
47 | uint8_t v1, v2; | ||
48 | int err; | ||
49 | |||
50 | data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | | ||
51 | MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | | ||
52 | MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; | ||
53 | |||
54 | err = spi_sync(data->spi, &data->msg); | ||
55 | if (err < 0) { | ||
56 | dev_err(dev, "spi_sync failed with %d\n", err); | ||
57 | return err; | ||
58 | } | ||
59 | |||
60 | v1 = data->rx_buf[0]; | ||
61 | v2 = data->rx_buf[1]; | ||
62 | |||
63 | if ((v1 & 0xc0) || (v2 & 0x3f)) | ||
64 | return -EINVAL; | ||
65 | |||
66 | return (v1 << 2) | (v2 >> 6); | ||
67 | } | ||
68 | |||
69 | #ifdef CONFIG_SHARPSL_PM | ||
70 | static struct max1111_data *the_max1111; | ||
71 | |||
72 | int max1111_read_channel(int channel) | ||
73 | { | ||
74 | return max1111_read(&the_max1111->spi->dev, channel); | ||
75 | } | ||
76 | EXPORT_SYMBOL(max1111_read_channel); | ||
77 | #endif | ||
78 | |||
79 | /* | ||
80 | * NOTE: SPI devices do not have a default 'name' attribute, which is | ||
81 | * likely to be used by hwmon applications to distinguish between | ||
82 | * different devices, explicitly add a name attribute here. | ||
83 | */ | ||
84 | static ssize_t show_name(struct device *dev, | ||
85 | struct device_attribute *attr, char *buf) | ||
86 | { | ||
87 | return sprintf(buf, "max1111\n"); | ||
88 | } | ||
89 | |||
90 | static ssize_t show_adc(struct device *dev, | ||
91 | struct device_attribute *attr, char *buf) | ||
92 | { | ||
93 | int channel = to_sensor_dev_attr(attr)->index; | ||
94 | int ret; | ||
95 | |||
96 | ret = max1111_read(dev, channel); | ||
97 | if (ret < 0) | ||
98 | return ret; | ||
99 | |||
100 | return sprintf(buf, "%d\n", ret); | ||
101 | } | ||
102 | |||
103 | #define MAX1111_ADC_ATTR(_id) \ | ||
104 | SENSOR_DEVICE_ATTR(adc##_id##_in, S_IRUGO, show_adc, NULL, _id) | ||
105 | |||
106 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
107 | static MAX1111_ADC_ATTR(0); | ||
108 | static MAX1111_ADC_ATTR(1); | ||
109 | static MAX1111_ADC_ATTR(2); | ||
110 | static MAX1111_ADC_ATTR(3); | ||
111 | |||
112 | static struct attribute *max1111_attributes[] = { | ||
113 | &dev_attr_name.attr, | ||
114 | &sensor_dev_attr_adc0_in.dev_attr.attr, | ||
115 | &sensor_dev_attr_adc1_in.dev_attr.attr, | ||
116 | &sensor_dev_attr_adc2_in.dev_attr.attr, | ||
117 | &sensor_dev_attr_adc3_in.dev_attr.attr, | ||
118 | NULL, | ||
119 | }; | ||
120 | |||
121 | static const struct attribute_group max1111_attr_group = { | ||
122 | .attrs = max1111_attributes, | ||
123 | }; | ||
124 | |||
125 | static int setup_transfer(struct max1111_data *data) | ||
126 | { | ||
127 | struct spi_message *m; | ||
128 | struct spi_transfer *x; | ||
129 | |||
130 | data->tx_buf = kmalloc(MAX1111_TX_BUF_SIZE, GFP_KERNEL); | ||
131 | if (!data->tx_buf) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | data->rx_buf = kmalloc(MAX1111_RX_BUF_SIZE, GFP_KERNEL); | ||
135 | if (!data->rx_buf) { | ||
136 | kfree(data->tx_buf); | ||
137 | return -ENOMEM; | ||
138 | } | ||
139 | |||
140 | m = &data->msg; | ||
141 | x = &data->xfer[0]; | ||
142 | |||
143 | spi_message_init(m); | ||
144 | |||
145 | x->tx_buf = &data->tx_buf[0]; | ||
146 | x->len = 1; | ||
147 | spi_message_add_tail(x, m); | ||
148 | |||
149 | x++; | ||
150 | x->rx_buf = &data->rx_buf[0]; | ||
151 | x->len = 2; | ||
152 | spi_message_add_tail(x, m); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static int __devinit max1111_probe(struct spi_device *spi) | ||
158 | { | ||
159 | struct max1111_data *data; | ||
160 | int err; | ||
161 | |||
162 | spi->bits_per_word = 8; | ||
163 | spi->mode = SPI_MODE_0; | ||
164 | err = spi_setup(spi); | ||
165 | if (err < 0) | ||
166 | return err; | ||
167 | |||
168 | data = kzalloc(sizeof(struct max1111_data), GFP_KERNEL); | ||
169 | if (data == NULL) { | ||
170 | dev_err(&spi->dev, "failed to allocate memory\n"); | ||
171 | return -ENOMEM; | ||
172 | } | ||
173 | |||
174 | err = setup_transfer(data); | ||
175 | if (err) | ||
176 | goto err_free_data; | ||
177 | |||
178 | data->spi = spi; | ||
179 | spi_set_drvdata(spi, data); | ||
180 | |||
181 | err = sysfs_create_group(&spi->dev.kobj, &max1111_attr_group); | ||
182 | if (err) { | ||
183 | dev_err(&spi->dev, "failed to create attribute group\n"); | ||
184 | goto err_free_all; | ||
185 | } | ||
186 | |||
187 | data->hwmon_dev = hwmon_device_register(&spi->dev); | ||
188 | if (IS_ERR(data->hwmon_dev)) { | ||
189 | dev_err(&spi->dev, "failed to create hwmon device\n"); | ||
190 | err = PTR_ERR(data->hwmon_dev); | ||
191 | goto err_remove; | ||
192 | } | ||
193 | |||
194 | #ifdef CONFIG_SHARPSL_PM | ||
195 | the_max1111 = data; | ||
196 | #endif | ||
197 | return 0; | ||
198 | |||
199 | err_remove: | ||
200 | sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); | ||
201 | err_free_all: | ||
202 | kfree(data->rx_buf); | ||
203 | kfree(data->tx_buf); | ||
204 | err_free_data: | ||
205 | kfree(data); | ||
206 | return err; | ||
207 | } | ||
208 | |||
209 | static int __devexit max1111_remove(struct spi_device *spi) | ||
210 | { | ||
211 | struct max1111_data *data = spi_get_drvdata(spi); | ||
212 | |||
213 | hwmon_device_unregister(data->hwmon_dev); | ||
214 | sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); | ||
215 | kfree(data->rx_buf); | ||
216 | kfree(data->tx_buf); | ||
217 | kfree(data); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static struct spi_driver max1111_driver = { | ||
222 | .driver = { | ||
223 | .name = "max1111", | ||
224 | .owner = THIS_MODULE, | ||
225 | }, | ||
226 | .probe = max1111_probe, | ||
227 | .remove = __devexit_p(max1111_remove), | ||
228 | }; | ||
229 | |||
230 | static int __init max1111_init(void) | ||
231 | { | ||
232 | return spi_register_driver(&max1111_driver); | ||
233 | } | ||
234 | module_init(max1111_init); | ||
235 | |||
236 | static void __exit max1111_exit(void) | ||
237 | { | ||
238 | spi_unregister_driver(&max1111_driver); | ||
239 | } | ||
240 | module_exit(max1111_exit); | ||
241 | |||
242 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); | ||
243 | MODULE_DESCRIPTION("MAX1111 ADC Driver"); | ||
244 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 1ab1cacad598..7897754f3a5c 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -69,11 +69,18 @@ I2C_CLIENT_INSMOD_1(max1619); | |||
69 | #define MAX1619_REG_W_TCRIT_HYST 0x13 | 69 | #define MAX1619_REG_W_TCRIT_HYST 0x13 |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Conversions and various macros | 72 | * Conversions |
73 | */ | 73 | */ |
74 | 74 | ||
75 | #define TEMP_FROM_REG(val) ((val & 0x80 ? val-0x100 : val) * 1000) | 75 | static int temp_from_reg(int val) |
76 | #define TEMP_TO_REG(val) ((val < 0 ? val+0x100*1000 : val) / 1000) | 76 | { |
77 | return (val & 0x80 ? val-0x100 : val) * 1000; | ||
78 | } | ||
79 | |||
80 | static int temp_to_reg(int val) | ||
81 | { | ||
82 | return (val < 0 ? val+0x100*1000 : val) / 1000; | ||
83 | } | ||
77 | 84 | ||
78 | /* | 85 | /* |
79 | * Functions declaration | 86 | * Functions declaration |
@@ -135,7 +142,7 @@ struct max1619_data { | |||
135 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 142 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ |
136 | { \ | 143 | { \ |
137 | struct max1619_data *data = max1619_update_device(dev); \ | 144 | struct max1619_data *data = max1619_update_device(dev); \ |
138 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ | 145 | return sprintf(buf, "%d\n", temp_from_reg(data->value)); \ |
139 | } | 146 | } |
140 | show_temp(temp_input1); | 147 | show_temp(temp_input1); |
141 | show_temp(temp_input2); | 148 | show_temp(temp_input2); |
@@ -153,7 +160,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co | |||
153 | long val = simple_strtol(buf, NULL, 10); \ | 160 | long val = simple_strtol(buf, NULL, 10); \ |
154 | \ | 161 | \ |
155 | mutex_lock(&data->update_lock); \ | 162 | mutex_lock(&data->update_lock); \ |
156 | data->value = TEMP_TO_REG(val); \ | 163 | data->value = temp_to_reg(val); \ |
157 | i2c_smbus_write_byte_data(client, reg, data->value); \ | 164 | i2c_smbus_write_byte_data(client, reg, data->value); \ |
158 | mutex_unlock(&data->update_lock); \ | 165 | mutex_unlock(&data->update_lock); \ |
159 | return count; \ | 166 | return count; \ |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 9b462bb13fa3..5fbfa34c110e 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -75,7 +75,8 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); | |||
75 | #define FSCM 0x09 /* Logical device: fans */ | 75 | #define FSCM 0x09 /* Logical device: fans */ |
76 | #define VLM 0x0d /* Logical device: voltages */ | 76 | #define VLM 0x0d /* Logical device: voltages */ |
77 | #define TMS 0x0e /* Logical device: temperatures */ | 77 | #define TMS 0x0e /* Logical device: temperatures */ |
78 | static const u8 logdev[3] = { FSCM, VLM, TMS }; | 78 | #define LDNI_MAX 3 |
79 | static const u8 logdev[LDNI_MAX] = { FSCM, VLM, TMS }; | ||
79 | 80 | ||
80 | #define LD_FAN 0 | 81 | #define LD_FAN 0 |
81 | #define LD_IN 1 | 82 | #define LD_IN 1 |
@@ -489,11 +490,66 @@ static struct sensor_device_attribute in_max[] = { | |||
489 | SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10), | 490 | SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10), |
490 | }; | 491 | }; |
491 | 492 | ||
493 | /* (temp & vin) channel status register alarm bits (pdf sec.11.5.12) */ | ||
494 | #define CHAN_ALM_MIN 0x02 /* min limit crossed */ | ||
495 | #define CHAN_ALM_MAX 0x04 /* max limit exceeded */ | ||
496 | #define TEMP_ALM_CRIT 0x08 /* temp crit exceeded (temp only) */ | ||
497 | |||
498 | /* show_in_min/max_alarm() reads data from the per-channel status | ||
499 | register (sec 11.5.12), not the vin event status registers (sec | ||
500 | 11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) */ | ||
501 | |||
502 | static ssize_t show_in_min_alarm(struct device *dev, | ||
503 | struct device_attribute *devattr, char *buf) | ||
504 | { | ||
505 | struct pc87360_data *data = pc87360_update_device(dev); | ||
506 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
507 | |||
508 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN)); | ||
509 | } | ||
510 | static ssize_t show_in_max_alarm(struct device *dev, | ||
511 | struct device_attribute *devattr, char *buf) | ||
512 | { | ||
513 | struct pc87360_data *data = pc87360_update_device(dev); | ||
514 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
515 | |||
516 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX)); | ||
517 | } | ||
518 | |||
519 | static struct sensor_device_attribute in_min_alarm[] = { | ||
520 | SENSOR_ATTR(in0_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 0), | ||
521 | SENSOR_ATTR(in1_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 1), | ||
522 | SENSOR_ATTR(in2_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 2), | ||
523 | SENSOR_ATTR(in3_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 3), | ||
524 | SENSOR_ATTR(in4_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 4), | ||
525 | SENSOR_ATTR(in5_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 5), | ||
526 | SENSOR_ATTR(in6_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 6), | ||
527 | SENSOR_ATTR(in7_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 7), | ||
528 | SENSOR_ATTR(in8_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 8), | ||
529 | SENSOR_ATTR(in9_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 9), | ||
530 | SENSOR_ATTR(in10_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 10), | ||
531 | }; | ||
532 | static struct sensor_device_attribute in_max_alarm[] = { | ||
533 | SENSOR_ATTR(in0_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 0), | ||
534 | SENSOR_ATTR(in1_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 1), | ||
535 | SENSOR_ATTR(in2_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 2), | ||
536 | SENSOR_ATTR(in3_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 3), | ||
537 | SENSOR_ATTR(in4_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 4), | ||
538 | SENSOR_ATTR(in5_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 5), | ||
539 | SENSOR_ATTR(in6_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 6), | ||
540 | SENSOR_ATTR(in7_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 7), | ||
541 | SENSOR_ATTR(in8_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 8), | ||
542 | SENSOR_ATTR(in9_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 9), | ||
543 | SENSOR_ATTR(in10_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 10), | ||
544 | }; | ||
545 | |||
492 | #define VIN_UNIT_ATTRS(X) \ | 546 | #define VIN_UNIT_ATTRS(X) \ |
493 | &in_input[X].dev_attr.attr, \ | 547 | &in_input[X].dev_attr.attr, \ |
494 | &in_status[X].dev_attr.attr, \ | 548 | &in_status[X].dev_attr.attr, \ |
495 | &in_min[X].dev_attr.attr, \ | 549 | &in_min[X].dev_attr.attr, \ |
496 | &in_max[X].dev_attr.attr | 550 | &in_max[X].dev_attr.attr, \ |
551 | &in_min_alarm[X].dev_attr.attr, \ | ||
552 | &in_max_alarm[X].dev_attr.attr | ||
497 | 553 | ||
498 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) | 554 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) |
499 | { | 555 | { |
@@ -658,12 +714,68 @@ static struct sensor_device_attribute therm_crit[] = { | |||
658 | show_therm_crit, set_therm_crit, 2+11), | 714 | show_therm_crit, set_therm_crit, 2+11), |
659 | }; | 715 | }; |
660 | 716 | ||
717 | /* show_therm_min/max_alarm() reads data from the per-channel voltage | ||
718 | status register (sec 11.5.12) */ | ||
719 | |||
720 | static ssize_t show_therm_min_alarm(struct device *dev, | ||
721 | struct device_attribute *devattr, char *buf) | ||
722 | { | ||
723 | struct pc87360_data *data = pc87360_update_device(dev); | ||
724 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
725 | |||
726 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN)); | ||
727 | } | ||
728 | static ssize_t show_therm_max_alarm(struct device *dev, | ||
729 | struct device_attribute *devattr, char *buf) | ||
730 | { | ||
731 | struct pc87360_data *data = pc87360_update_device(dev); | ||
732 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
733 | |||
734 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX)); | ||
735 | } | ||
736 | static ssize_t show_therm_crit_alarm(struct device *dev, | ||
737 | struct device_attribute *devattr, char *buf) | ||
738 | { | ||
739 | struct pc87360_data *data = pc87360_update_device(dev); | ||
740 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
741 | |||
742 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & TEMP_ALM_CRIT)); | ||
743 | } | ||
744 | |||
745 | static struct sensor_device_attribute therm_min_alarm[] = { | ||
746 | SENSOR_ATTR(temp4_min_alarm, S_IRUGO, | ||
747 | show_therm_min_alarm, NULL, 0+11), | ||
748 | SENSOR_ATTR(temp5_min_alarm, S_IRUGO, | ||
749 | show_therm_min_alarm, NULL, 1+11), | ||
750 | SENSOR_ATTR(temp6_min_alarm, S_IRUGO, | ||
751 | show_therm_min_alarm, NULL, 2+11), | ||
752 | }; | ||
753 | static struct sensor_device_attribute therm_max_alarm[] = { | ||
754 | SENSOR_ATTR(temp4_max_alarm, S_IRUGO, | ||
755 | show_therm_max_alarm, NULL, 0+11), | ||
756 | SENSOR_ATTR(temp5_max_alarm, S_IRUGO, | ||
757 | show_therm_max_alarm, NULL, 1+11), | ||
758 | SENSOR_ATTR(temp6_max_alarm, S_IRUGO, | ||
759 | show_therm_max_alarm, NULL, 2+11), | ||
760 | }; | ||
761 | static struct sensor_device_attribute therm_crit_alarm[] = { | ||
762 | SENSOR_ATTR(temp4_crit_alarm, S_IRUGO, | ||
763 | show_therm_crit_alarm, NULL, 0+11), | ||
764 | SENSOR_ATTR(temp5_crit_alarm, S_IRUGO, | ||
765 | show_therm_crit_alarm, NULL, 1+11), | ||
766 | SENSOR_ATTR(temp6_crit_alarm, S_IRUGO, | ||
767 | show_therm_crit_alarm, NULL, 2+11), | ||
768 | }; | ||
769 | |||
661 | #define THERM_UNIT_ATTRS(X) \ | 770 | #define THERM_UNIT_ATTRS(X) \ |
662 | &therm_input[X].dev_attr.attr, \ | 771 | &therm_input[X].dev_attr.attr, \ |
663 | &therm_status[X].dev_attr.attr, \ | 772 | &therm_status[X].dev_attr.attr, \ |
664 | &therm_min[X].dev_attr.attr, \ | 773 | &therm_min[X].dev_attr.attr, \ |
665 | &therm_max[X].dev_attr.attr, \ | 774 | &therm_max[X].dev_attr.attr, \ |
666 | &therm_crit[X].dev_attr.attr | 775 | &therm_crit[X].dev_attr.attr, \ |
776 | &therm_min_alarm[X].dev_attr.attr, \ | ||
777 | &therm_max_alarm[X].dev_attr.attr, \ | ||
778 | &therm_crit_alarm[X].dev_attr.attr | ||
667 | 779 | ||
668 | static struct attribute * pc8736x_therm_attr_array[] = { | 780 | static struct attribute * pc8736x_therm_attr_array[] = { |
669 | THERM_UNIT_ATTRS(0), | 781 | THERM_UNIT_ATTRS(0), |
@@ -790,12 +902,76 @@ static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *att | |||
790 | } | 902 | } |
791 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); | 903 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); |
792 | 904 | ||
905 | /* show_temp_min/max_alarm() reads data from the per-channel status | ||
906 | register (sec 12.3.7), not the temp event status registers (sec | ||
907 | 12.3.2) that show_temp_alarm() reads (via data->temp_alarms) */ | ||
908 | |||
909 | static ssize_t show_temp_min_alarm(struct device *dev, | ||
910 | struct device_attribute *devattr, char *buf) | ||
911 | { | ||
912 | struct pc87360_data *data = pc87360_update_device(dev); | ||
913 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
914 | |||
915 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MIN)); | ||
916 | } | ||
917 | static ssize_t show_temp_max_alarm(struct device *dev, | ||
918 | struct device_attribute *devattr, char *buf) | ||
919 | { | ||
920 | struct pc87360_data *data = pc87360_update_device(dev); | ||
921 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
922 | |||
923 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MAX)); | ||
924 | } | ||
925 | static ssize_t show_temp_crit_alarm(struct device *dev, | ||
926 | struct device_attribute *devattr, char *buf) | ||
927 | { | ||
928 | struct pc87360_data *data = pc87360_update_device(dev); | ||
929 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
930 | |||
931 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_ALM_CRIT)); | ||
932 | } | ||
933 | |||
934 | static struct sensor_device_attribute temp_min_alarm[] = { | ||
935 | SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 0), | ||
936 | SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 1), | ||
937 | SENSOR_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 2), | ||
938 | }; | ||
939 | static struct sensor_device_attribute temp_max_alarm[] = { | ||
940 | SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 0), | ||
941 | SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 1), | ||
942 | SENSOR_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 2), | ||
943 | }; | ||
944 | static struct sensor_device_attribute temp_crit_alarm[] = { | ||
945 | SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 0), | ||
946 | SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 1), | ||
947 | SENSOR_ATTR(temp3_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 2), | ||
948 | }; | ||
949 | |||
950 | #define TEMP_FAULT 0x40 /* open diode */ | ||
951 | static ssize_t show_temp_fault(struct device *dev, | ||
952 | struct device_attribute *devattr, char *buf) | ||
953 | { | ||
954 | struct pc87360_data *data = pc87360_update_device(dev); | ||
955 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
956 | |||
957 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_FAULT)); | ||
958 | } | ||
959 | static struct sensor_device_attribute temp_fault[] = { | ||
960 | SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0), | ||
961 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1), | ||
962 | SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2), | ||
963 | }; | ||
964 | |||
793 | #define TEMP_UNIT_ATTRS(X) \ | 965 | #define TEMP_UNIT_ATTRS(X) \ |
794 | &temp_input[X].dev_attr.attr, \ | 966 | &temp_input[X].dev_attr.attr, \ |
795 | &temp_status[X].dev_attr.attr, \ | 967 | &temp_status[X].dev_attr.attr, \ |
796 | &temp_min[X].dev_attr.attr, \ | 968 | &temp_min[X].dev_attr.attr, \ |
797 | &temp_max[X].dev_attr.attr, \ | 969 | &temp_max[X].dev_attr.attr, \ |
798 | &temp_crit[X].dev_attr.attr | 970 | &temp_crit[X].dev_attr.attr, \ |
971 | &temp_min_alarm[X].dev_attr.attr, \ | ||
972 | &temp_max_alarm[X].dev_attr.attr, \ | ||
973 | &temp_crit_alarm[X].dev_attr.attr, \ | ||
974 | &temp_fault[X].dev_attr.attr | ||
799 | 975 | ||
800 | static struct attribute * pc8736x_temp_attr_array[] = { | 976 | static struct attribute * pc8736x_temp_attr_array[] = { |
801 | TEMP_UNIT_ATTRS(0), | 977 | TEMP_UNIT_ATTRS(0), |
@@ -809,8 +985,8 @@ static const struct attribute_group pc8736x_temp_group = { | |||
809 | .attrs = pc8736x_temp_attr_array, | 985 | .attrs = pc8736x_temp_attr_array, |
810 | }; | 986 | }; |
811 | 987 | ||
812 | static ssize_t show_name(struct device *dev, struct device_attribute | 988 | static ssize_t show_name(struct device *dev, |
813 | *devattr, char *buf) | 989 | struct device_attribute *devattr, char *buf) |
814 | { | 990 | { |
815 | struct pc87360_data *data = dev_get_drvdata(dev); | 991 | struct pc87360_data *data = dev_get_drvdata(dev); |
816 | return sprintf(buf, "%s\n", data->name); | 992 | return sprintf(buf, "%s\n", data->name); |
@@ -955,7 +1131,7 @@ static int __devinit pc87360_probe(struct platform_device *pdev) | |||
955 | mutex_init(&data->update_lock); | 1131 | mutex_init(&data->update_lock); |
956 | platform_set_drvdata(pdev, data); | 1132 | platform_set_drvdata(pdev, data); |
957 | 1133 | ||
958 | for (i = 0; i < 3; i++) { | 1134 | for (i = 0; i < LDNI_MAX; i++) { |
959 | if (((data->address[i] = extra_isa[i])) | 1135 | if (((data->address[i] = extra_isa[i])) |
960 | && !request_region(extra_isa[i], PC87360_EXTENT, | 1136 | && !request_region(extra_isa[i], PC87360_EXTENT, |
961 | pc87360_driver.driver.name)) { | 1137 | pc87360_driver.driver.name)) { |
@@ -1031,7 +1207,15 @@ static int __devinit pc87360_probe(struct platform_device *pdev) | |||
1031 | || (err = device_create_file(dev, | 1207 | || (err = device_create_file(dev, |
1032 | &temp_crit[i].dev_attr)) | 1208 | &temp_crit[i].dev_attr)) |
1033 | || (err = device_create_file(dev, | 1209 | || (err = device_create_file(dev, |
1034 | &temp_status[i].dev_attr))) | 1210 | &temp_status[i].dev_attr)) |
1211 | || (err = device_create_file(dev, | ||
1212 | &temp_min_alarm[i].dev_attr)) | ||
1213 | || (err = device_create_file(dev, | ||
1214 | &temp_max_alarm[i].dev_attr)) | ||
1215 | || (err = device_create_file(dev, | ||
1216 | &temp_crit_alarm[i].dev_attr)) | ||
1217 | || (err = device_create_file(dev, | ||
1218 | &temp_fault[i].dev_attr))) | ||
1035 | goto ERROR3; | 1219 | goto ERROR3; |
1036 | } | 1220 | } |
1037 | if ((err = device_create_file(dev, &dev_attr_alarms_temp))) | 1221 | if ((err = device_create_file(dev, &dev_attr_alarms_temp))) |
@@ -1131,6 +1315,16 @@ static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | |||
1131 | mutex_unlock(&(data->lock)); | 1315 | mutex_unlock(&(data->lock)); |
1132 | } | 1316 | } |
1133 | 1317 | ||
1318 | /* (temp & vin) channel conversion status register flags (pdf sec.11.5.12) */ | ||
1319 | #define CHAN_CNVRTD 0x80 /* new data ready */ | ||
1320 | #define CHAN_ENA 0x01 /* enabled channel (temp or vin) */ | ||
1321 | #define CHAN_ALM_ENA 0x10 /* propagate to alarms-reg ?? (chk val!) */ | ||
1322 | #define CHAN_READY (CHAN_ENA|CHAN_CNVRTD) /* sample ready mask */ | ||
1323 | |||
1324 | #define TEMP_OTS_OE 0x20 /* OTS Output Enable */ | ||
1325 | #define VIN_RW1C_MASK (CHAN_READY|CHAN_ALM_MAX|CHAN_ALM_MIN) /* 0x87 */ | ||
1326 | #define TEMP_RW1C_MASK (VIN_RW1C_MASK|TEMP_ALM_CRIT|TEMP_FAULT) /* 0xCF */ | ||
1327 | |||
1134 | static void pc87360_init_device(struct platform_device *pdev, | 1328 | static void pc87360_init_device(struct platform_device *pdev, |
1135 | int use_thermistors) | 1329 | int use_thermistors) |
1136 | { | 1330 | { |
@@ -1152,11 +1346,12 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1152 | 1346 | ||
1153 | nr = data->innr < 11 ? data->innr : 11; | 1347 | nr = data->innr < 11 ? data->innr : 11; |
1154 | for (i = 0; i < nr; i++) { | 1348 | for (i = 0; i < nr; i++) { |
1349 | reg = pc87360_read_value(data, LD_IN, i, | ||
1350 | PC87365_REG_IN_STATUS); | ||
1351 | dev_dbg(&pdev->dev, "bios in%d status:0x%02x\n", i, reg); | ||
1155 | if (init >= init_in[i]) { | 1352 | if (init >= init_in[i]) { |
1156 | /* Forcibly enable voltage channel */ | 1353 | /* Forcibly enable voltage channel */ |
1157 | reg = pc87360_read_value(data, LD_IN, i, | 1354 | if (!(reg & CHAN_ENA)) { |
1158 | PC87365_REG_IN_STATUS); | ||
1159 | if (!(reg & 0x01)) { | ||
1160 | dev_dbg(&pdev->dev, "Forcibly " | 1355 | dev_dbg(&pdev->dev, "Forcibly " |
1161 | "enabling in%d\n", i); | 1356 | "enabling in%d\n", i); |
1162 | pc87360_write_value(data, LD_IN, i, | 1357 | pc87360_write_value(data, LD_IN, i, |
@@ -1168,19 +1363,24 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1168 | 1363 | ||
1169 | /* We can't blindly trust the Super-I/O space configuration bit, | 1364 | /* We can't blindly trust the Super-I/O space configuration bit, |
1170 | most BIOS won't set it properly */ | 1365 | most BIOS won't set it properly */ |
1366 | dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors); | ||
1171 | for (i = 11; i < data->innr; i++) { | 1367 | for (i = 11; i < data->innr; i++) { |
1172 | reg = pc87360_read_value(data, LD_IN, i, | 1368 | reg = pc87360_read_value(data, LD_IN, i, |
1173 | PC87365_REG_TEMP_STATUS); | 1369 | PC87365_REG_TEMP_STATUS); |
1174 | use_thermistors = use_thermistors || (reg & 0x01); | 1370 | use_thermistors = use_thermistors || (reg & CHAN_ENA); |
1371 | /* thermistors are temp[4-6], measured on vin[11-14] */ | ||
1372 | dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i-7, reg); | ||
1175 | } | 1373 | } |
1374 | dev_dbg(&pdev->dev, "using thermistors:%d\n", use_thermistors); | ||
1176 | 1375 | ||
1177 | i = use_thermistors ? 2 : 0; | 1376 | i = use_thermistors ? 2 : 0; |
1178 | for (; i < data->tempnr; i++) { | 1377 | for (; i < data->tempnr; i++) { |
1378 | reg = pc87360_read_value(data, LD_TEMP, i, | ||
1379 | PC87365_REG_TEMP_STATUS); | ||
1380 | dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg); | ||
1179 | if (init >= init_temp[i]) { | 1381 | if (init >= init_temp[i]) { |
1180 | /* Forcibly enable temperature channel */ | 1382 | /* Forcibly enable temperature channel */ |
1181 | reg = pc87360_read_value(data, LD_TEMP, i, | 1383 | if (!(reg & CHAN_ENA)) { |
1182 | PC87365_REG_TEMP_STATUS); | ||
1183 | if (!(reg & 0x01)) { | ||
1184 | dev_dbg(&pdev->dev, "Forcibly " | 1384 | dev_dbg(&pdev->dev, "Forcibly " |
1185 | "enabling temp%d\n", i+1); | 1385 | "enabling temp%d\n", i+1); |
1186 | pc87360_write_value(data, LD_TEMP, i, | 1386 | pc87360_write_value(data, LD_TEMP, i, |
@@ -1197,7 +1397,7 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1197 | diodes */ | 1397 | diodes */ |
1198 | reg = pc87360_read_value(data, LD_TEMP, | 1398 | reg = pc87360_read_value(data, LD_TEMP, |
1199 | (i-11)/2, PC87365_REG_TEMP_STATUS); | 1399 | (i-11)/2, PC87365_REG_TEMP_STATUS); |
1200 | if (reg & 0x01) { | 1400 | if (reg & CHAN_ENA) { |
1201 | dev_dbg(&pdev->dev, "Skipping " | 1401 | dev_dbg(&pdev->dev, "Skipping " |
1202 | "temp%d, pin already in use " | 1402 | "temp%d, pin already in use " |
1203 | "by temp%d\n", i-7, (i-11)/2); | 1403 | "by temp%d\n", i-7, (i-11)/2); |
@@ -1207,7 +1407,7 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1207 | /* Forcibly enable thermistor channel */ | 1407 | /* Forcibly enable thermistor channel */ |
1208 | reg = pc87360_read_value(data, LD_IN, i, | 1408 | reg = pc87360_read_value(data, LD_IN, i, |
1209 | PC87365_REG_IN_STATUS); | 1409 | PC87365_REG_IN_STATUS); |
1210 | if (!(reg & 0x01)) { | 1410 | if (!(reg & CHAN_ENA)) { |
1211 | dev_dbg(&pdev->dev, "Forcibly " | 1411 | dev_dbg(&pdev->dev, "Forcibly " |
1212 | "enabling temp%d\n", i-7); | 1412 | "enabling temp%d\n", i-7); |
1213 | pc87360_write_value(data, LD_IN, i, | 1413 | pc87360_write_value(data, LD_IN, i, |
@@ -1221,7 +1421,8 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1221 | if (data->innr) { | 1421 | if (data->innr) { |
1222 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1422 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
1223 | PC87365_REG_IN_CONFIG); | 1423 | PC87365_REG_IN_CONFIG); |
1224 | if (reg & 0x01) { | 1424 | dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg); |
1425 | if (reg & CHAN_ENA) { | ||
1225 | dev_dbg(&pdev->dev, "Forcibly " | 1426 | dev_dbg(&pdev->dev, "Forcibly " |
1226 | "enabling monitoring (VLM)\n"); | 1427 | "enabling monitoring (VLM)\n"); |
1227 | pc87360_write_value(data, LD_IN, NO_BANK, | 1428 | pc87360_write_value(data, LD_IN, NO_BANK, |
@@ -1233,7 +1434,8 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1233 | if (data->tempnr) { | 1434 | if (data->tempnr) { |
1234 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, | 1435 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, |
1235 | PC87365_REG_TEMP_CONFIG); | 1436 | PC87365_REG_TEMP_CONFIG); |
1236 | if (reg & 0x01) { | 1437 | dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg); |
1438 | if (reg & CHAN_ENA) { | ||
1237 | dev_dbg(&pdev->dev, "Forcibly enabling " | 1439 | dev_dbg(&pdev->dev, "Forcibly enabling " |
1238 | "monitoring (TMS)\n"); | 1440 | "monitoring (TMS)\n"); |
1239 | pc87360_write_value(data, LD_TEMP, NO_BANK, | 1441 | pc87360_write_value(data, LD_TEMP, NO_BANK, |
@@ -1336,11 +1538,11 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1336 | pc87360_write_value(data, LD_IN, i, | 1538 | pc87360_write_value(data, LD_IN, i, |
1337 | PC87365_REG_IN_STATUS, | 1539 | PC87365_REG_IN_STATUS, |
1338 | data->in_status[i]); | 1540 | data->in_status[i]); |
1339 | if ((data->in_status[i] & 0x81) == 0x81) { | 1541 | if ((data->in_status[i] & CHAN_READY) == CHAN_READY) { |
1340 | data->in[i] = pc87360_read_value(data, LD_IN, | 1542 | data->in[i] = pc87360_read_value(data, LD_IN, |
1341 | i, PC87365_REG_IN); | 1543 | i, PC87365_REG_IN); |
1342 | } | 1544 | } |
1343 | if (data->in_status[i] & 0x01) { | 1545 | if (data->in_status[i] & CHAN_ENA) { |
1344 | data->in_min[i] = pc87360_read_value(data, | 1546 | data->in_min[i] = pc87360_read_value(data, |
1345 | LD_IN, i, | 1547 | LD_IN, i, |
1346 | PC87365_REG_IN_MIN); | 1548 | PC87365_REG_IN_MIN); |
@@ -1373,12 +1575,12 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1373 | pc87360_write_value(data, LD_TEMP, i, | 1575 | pc87360_write_value(data, LD_TEMP, i, |
1374 | PC87365_REG_TEMP_STATUS, | 1576 | PC87365_REG_TEMP_STATUS, |
1375 | data->temp_status[i]); | 1577 | data->temp_status[i]); |
1376 | if ((data->temp_status[i] & 0x81) == 0x81) { | 1578 | if ((data->temp_status[i] & CHAN_READY) == CHAN_READY) { |
1377 | data->temp[i] = pc87360_read_value(data, | 1579 | data->temp[i] = pc87360_read_value(data, |
1378 | LD_TEMP, i, | 1580 | LD_TEMP, i, |
1379 | PC87365_REG_TEMP); | 1581 | PC87365_REG_TEMP); |
1380 | } | 1582 | } |
1381 | if (data->temp_status[i] & 0x01) { | 1583 | if (data->temp_status[i] & CHAN_ENA) { |
1382 | data->temp_min[i] = pc87360_read_value(data, | 1584 | data->temp_min[i] = pc87360_read_value(data, |
1383 | LD_TEMP, i, | 1585 | LD_TEMP, i, |
1384 | PC87365_REG_TEMP_MIN); | 1586 | PC87365_REG_TEMP_MIN); |
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 3b01001108c1..7d97431e132f 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c | |||
@@ -55,8 +55,11 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " | |||
55 | static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; | 55 | static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
56 | static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; | 56 | static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
57 | static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; | 57 | static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; |
58 | static const u8 THMC50_REG_TEMP_CRITICAL[] = { 0x13, 0x14, 0x14 }; | ||
59 | static const u8 THMC50_REG_TEMP_DEFAULT[] = { 0x17, 0x18, 0x18 }; | ||
58 | 60 | ||
59 | #define THMC50_REG_CONF_nFANOFF 0x20 | 61 | #define THMC50_REG_CONF_nFANOFF 0x20 |
62 | #define THMC50_REG_CONF_PROGRAMMED 0x08 | ||
60 | 63 | ||
61 | /* Each client has this additional data */ | 64 | /* Each client has this additional data */ |
62 | struct thmc50_data { | 65 | struct thmc50_data { |
@@ -72,6 +75,7 @@ struct thmc50_data { | |||
72 | s8 temp_input[3]; | 75 | s8 temp_input[3]; |
73 | s8 temp_max[3]; | 76 | s8 temp_max[3]; |
74 | s8 temp_min[3]; | 77 | s8 temp_min[3]; |
78 | s8 temp_critical[3]; | ||
75 | u8 analog_out; | 79 | u8 analog_out; |
76 | u8 alarms; | 80 | u8 alarms; |
77 | }; | 81 | }; |
@@ -199,6 +203,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
199 | return count; | 203 | return count; |
200 | } | 204 | } |
201 | 205 | ||
206 | static ssize_t show_temp_critical(struct device *dev, | ||
207 | struct device_attribute *attr, | ||
208 | char *buf) | ||
209 | { | ||
210 | int nr = to_sensor_dev_attr(attr)->index; | ||
211 | struct thmc50_data *data = thmc50_update_device(dev); | ||
212 | return sprintf(buf, "%d\n", data->temp_critical[nr] * 1000); | ||
213 | } | ||
214 | |||
202 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | 215 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
203 | char *buf) | 216 | char *buf) |
204 | { | 217 | { |
@@ -214,7 +227,9 @@ static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ | |||
214 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | 227 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ |
215 | show_temp_min, set_temp_min, offset - 1); \ | 228 | show_temp_min, set_temp_min, offset - 1); \ |
216 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | 229 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
217 | show_temp_max, set_temp_max, offset - 1); | 230 | show_temp_max, set_temp_max, offset - 1); \ |
231 | static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO, \ | ||
232 | show_temp_critical, NULL, offset - 1); | ||
218 | 233 | ||
219 | temp_reg(1); | 234 | temp_reg(1); |
220 | temp_reg(2); | 235 | temp_reg(2); |
@@ -234,10 +249,12 @@ static struct attribute *thmc50_attributes[] = { | |||
234 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 249 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
235 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 250 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
236 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 251 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
252 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
237 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | 253 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, |
238 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 254 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
239 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 255 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
240 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 256 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
257 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
241 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 258 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
242 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | 259 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
243 | &sensor_dev_attr_pwm1.dev_attr.attr, | 260 | &sensor_dev_attr_pwm1.dev_attr.attr, |
@@ -254,6 +271,7 @@ static struct attribute *temp3_attributes[] = { | |||
254 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 271 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
255 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 272 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
256 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 273 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
274 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
257 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 275 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
258 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | 276 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
259 | NULL | 277 | NULL |
@@ -429,6 +447,10 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) | |||
429 | 447 | ||
430 | int temps = data->has_temp3 ? 3 : 2; | 448 | int temps = data->has_temp3 ? 3 : 2; |
431 | int i; | 449 | int i; |
450 | int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF); | ||
451 | |||
452 | prog &= THMC50_REG_CONF_PROGRAMMED; | ||
453 | |||
432 | for (i = 0; i < temps; i++) { | 454 | for (i = 0; i < temps; i++) { |
433 | data->temp_input[i] = i2c_smbus_read_byte_data(client, | 455 | data->temp_input[i] = i2c_smbus_read_byte_data(client, |
434 | THMC50_REG_TEMP[i]); | 456 | THMC50_REG_TEMP[i]); |
@@ -436,6 +458,10 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) | |||
436 | THMC50_REG_TEMP_MAX[i]); | 458 | THMC50_REG_TEMP_MAX[i]); |
437 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | 459 | data->temp_min[i] = i2c_smbus_read_byte_data(client, |
438 | THMC50_REG_TEMP_MIN[i]); | 460 | THMC50_REG_TEMP_MIN[i]); |
461 | data->temp_critical[i] = | ||
462 | i2c_smbus_read_byte_data(client, | ||
463 | prog ? THMC50_REG_TEMP_CRITICAL[i] | ||
464 | : THMC50_REG_TEMP_DEFAULT[i]); | ||
439 | } | 465 | } |
440 | data->analog_out = | 466 | data->analog_out = |
441 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); | 467 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); |
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c new file mode 100644 index 000000000000..68e90abeba96 --- /dev/null +++ b/drivers/hwmon/ultra45_env.c | |||
@@ -0,0 +1,320 @@ | |||
1 | /* ultra45_env.c: Driver for Ultra45 PIC16F747 environmental monitor. | ||
2 | * | ||
3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <linux/of_device.h> | ||
10 | #include <linux/io.h> | ||
11 | #include <linux/hwmon.h> | ||
12 | #include <linux/hwmon-sysfs.h> | ||
13 | |||
14 | #define DRV_MODULE_VERSION "0.1" | ||
15 | |||
16 | MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); | ||
17 | MODULE_DESCRIPTION("Ultra45 environmental monitor driver"); | ||
18 | MODULE_LICENSE("GPL"); | ||
19 | MODULE_VERSION(DRV_MODULE_VERSION); | ||
20 | |||
21 | /* PIC device registers */ | ||
22 | #define REG_CMD 0x00UL | ||
23 | #define REG_CMD_RESET 0x80 | ||
24 | #define REG_CMD_ESTAR 0x01 | ||
25 | #define REG_STAT 0x01UL | ||
26 | #define REG_STAT_FWVER 0xf0 | ||
27 | #define REG_STAT_TGOOD 0x08 | ||
28 | #define REG_STAT_STALE 0x04 | ||
29 | #define REG_STAT_BUSY 0x02 | ||
30 | #define REG_STAT_FAULT 0x01 | ||
31 | #define REG_DATA 0x40UL | ||
32 | #define REG_ADDR 0x41UL | ||
33 | #define REG_SIZE 0x42UL | ||
34 | |||
35 | /* Registers accessed indirectly via REG_DATA/REG_ADDR */ | ||
36 | #define IREG_FAN0 0x00 | ||
37 | #define IREG_FAN1 0x01 | ||
38 | #define IREG_FAN2 0x02 | ||
39 | #define IREG_FAN3 0x03 | ||
40 | #define IREG_FAN4 0x04 | ||
41 | #define IREG_FAN5 0x05 | ||
42 | #define IREG_LCL_TEMP 0x06 | ||
43 | #define IREG_RMT1_TEMP 0x07 | ||
44 | #define IREG_RMT2_TEMP 0x08 | ||
45 | #define IREG_RMT3_TEMP 0x09 | ||
46 | #define IREG_LM95221_TEMP 0x0a | ||
47 | #define IREG_FIRE_TEMP 0x0b | ||
48 | #define IREG_LSI1064_TEMP 0x0c | ||
49 | #define IREG_FRONT_TEMP 0x0d | ||
50 | #define IREG_FAN_STAT 0x0e | ||
51 | #define IREG_VCORE0 0x0f | ||
52 | #define IREG_VCORE1 0x10 | ||
53 | #define IREG_VMEM0 0x11 | ||
54 | #define IREG_VMEM1 0x12 | ||
55 | #define IREG_PSU_TEMP 0x13 | ||
56 | |||
57 | struct env { | ||
58 | void __iomem *regs; | ||
59 | spinlock_t lock; | ||
60 | |||
61 | struct device *hwmon_dev; | ||
62 | }; | ||
63 | |||
64 | static u8 env_read(struct env *p, u8 ireg) | ||
65 | { | ||
66 | u8 ret; | ||
67 | |||
68 | spin_lock(&p->lock); | ||
69 | writeb(ireg, p->regs + REG_ADDR); | ||
70 | ret = readb(p->regs + REG_DATA); | ||
71 | spin_unlock(&p->lock); | ||
72 | |||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | static void env_write(struct env *p, u8 ireg, u8 val) | ||
77 | { | ||
78 | spin_lock(&p->lock); | ||
79 | writeb(ireg, p->regs + REG_ADDR); | ||
80 | writeb(val, p->regs + REG_DATA); | ||
81 | spin_unlock(&p->lock); | ||
82 | } | ||
83 | |||
84 | /* There seems to be a adr7462 providing these values, thus a lot | ||
85 | * of these calculations are borrowed from the adt7470 driver. | ||
86 | */ | ||
87 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | ||
88 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM | ||
89 | #define FAN_PERIOD_INVALID (0xff << 8) | ||
90 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | ||
91 | |||
92 | static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf) | ||
93 | { | ||
94 | int fan_nr = to_sensor_dev_attr(attr)->index; | ||
95 | struct env *p = dev_get_drvdata(dev); | ||
96 | int rpm, period; | ||
97 | u8 val; | ||
98 | |||
99 | val = env_read(p, IREG_FAN0 + fan_nr); | ||
100 | period = (int) val << 8; | ||
101 | if (FAN_DATA_VALID(period)) | ||
102 | rpm = FAN_PERIOD_TO_RPM(period); | ||
103 | else | ||
104 | rpm = 0; | ||
105 | |||
106 | return sprintf(buf, "%d\n", rpm); | ||
107 | } | ||
108 | |||
109 | static ssize_t set_fan_speed(struct device *dev, struct device_attribute *attr, | ||
110 | const char *buf, size_t count) | ||
111 | { | ||
112 | int fan_nr = to_sensor_dev_attr(attr)->index; | ||
113 | int rpm = simple_strtol(buf, NULL, 10); | ||
114 | struct env *p = dev_get_drvdata(dev); | ||
115 | int period; | ||
116 | u8 val; | ||
117 | |||
118 | if (!rpm) | ||
119 | return -EINVAL; | ||
120 | |||
121 | period = FAN_RPM_TO_PERIOD(rpm); | ||
122 | val = period >> 8; | ||
123 | env_write(p, IREG_FAN0 + fan_nr, val); | ||
124 | |||
125 | return count; | ||
126 | } | ||
127 | |||
128 | static ssize_t show_fan_fault(struct device *dev, struct device_attribute *attr, char *buf) | ||
129 | { | ||
130 | int fan_nr = to_sensor_dev_attr(attr)->index; | ||
131 | struct env *p = dev_get_drvdata(dev); | ||
132 | u8 val = env_read(p, IREG_FAN_STAT); | ||
133 | return sprintf(buf, "%d\n", (val & (1 << fan_nr)) ? 1 : 0); | ||
134 | } | ||
135 | |||
136 | #define fan(index) \ | ||
137 | static SENSOR_DEVICE_ATTR(fan##index##_speed, S_IRUGO | S_IWUSR, \ | ||
138 | show_fan_speed, set_fan_speed, index); \ | ||
139 | static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, \ | ||
140 | show_fan_fault, NULL, index) | ||
141 | |||
142 | fan(0); | ||
143 | fan(1); | ||
144 | fan(2); | ||
145 | fan(3); | ||
146 | fan(4); | ||
147 | |||
148 | static SENSOR_DEVICE_ATTR(psu_fan_fault, S_IRUGO, show_fan_fault, NULL, 6); | ||
149 | |||
150 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) | ||
151 | { | ||
152 | int temp_nr = to_sensor_dev_attr(attr)->index; | ||
153 | struct env *p = dev_get_drvdata(dev); | ||
154 | s8 val; | ||
155 | |||
156 | val = env_read(p, IREG_LCL_TEMP + temp_nr); | ||
157 | return sprintf(buf, "%d\n", ((int) val) - 64); | ||
158 | } | ||
159 | |||
160 | static SENSOR_DEVICE_ATTR(adt7462_local_temp, S_IRUGO, show_temp, NULL, 0); | ||
161 | static SENSOR_DEVICE_ATTR(cpu0_temp, S_IRUGO, show_temp, NULL, 1); | ||
162 | static SENSOR_DEVICE_ATTR(cpu1_temp, S_IRUGO, show_temp, NULL, 2); | ||
163 | static SENSOR_DEVICE_ATTR(motherboard_temp, S_IRUGO, show_temp, NULL, 3); | ||
164 | static SENSOR_DEVICE_ATTR(lm95221_local_temp, S_IRUGO, show_temp, NULL, 4); | ||
165 | static SENSOR_DEVICE_ATTR(fire_temp, S_IRUGO, show_temp, NULL, 5); | ||
166 | static SENSOR_DEVICE_ATTR(lsi1064_local_temp, S_IRUGO, show_temp, NULL, 6); | ||
167 | static SENSOR_DEVICE_ATTR(front_panel_temp, S_IRUGO, show_temp, NULL, 7); | ||
168 | static SENSOR_DEVICE_ATTR(psu_temp, S_IRUGO, show_temp, NULL, 13); | ||
169 | |||
170 | static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr, char *buf) | ||
171 | { | ||
172 | int index = to_sensor_dev_attr(attr)->index; | ||
173 | struct env *p = dev_get_drvdata(dev); | ||
174 | u8 val; | ||
175 | |||
176 | val = readb(p->regs + REG_STAT); | ||
177 | return sprintf(buf, "%d\n", (val & (1 << index)) ? 1 : 0); | ||
178 | } | ||
179 | |||
180 | static SENSOR_DEVICE_ATTR(fan_failure, S_IRUGO, show_stat_bit, NULL, 0); | ||
181 | static SENSOR_DEVICE_ATTR(env_bus_busy, S_IRUGO, show_stat_bit, NULL, 1); | ||
182 | static SENSOR_DEVICE_ATTR(env_data_stale, S_IRUGO, show_stat_bit, NULL, 2); | ||
183 | static SENSOR_DEVICE_ATTR(tpm_self_test_passed, S_IRUGO, show_stat_bit, NULL, 3); | ||
184 | |||
185 | static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, char *buf) | ||
186 | { | ||
187 | struct env *p = dev_get_drvdata(dev); | ||
188 | u8 val; | ||
189 | |||
190 | val = readb(p->regs + REG_STAT); | ||
191 | return sprintf(buf, "%d\n", val >> 4); | ||
192 | } | ||
193 | |||
194 | static SENSOR_DEVICE_ATTR(firmware_version, S_IRUGO, show_fwver, NULL, 0); | ||
195 | |||
196 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) | ||
197 | { | ||
198 | return sprintf(buf, "ultra45\n"); | ||
199 | } | ||
200 | |||
201 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); | ||
202 | |||
203 | static struct attribute *env_attributes[] = { | ||
204 | &sensor_dev_attr_fan0_speed.dev_attr.attr, | ||
205 | &sensor_dev_attr_fan0_fault.dev_attr.attr, | ||
206 | &sensor_dev_attr_fan1_speed.dev_attr.attr, | ||
207 | &sensor_dev_attr_fan1_fault.dev_attr.attr, | ||
208 | &sensor_dev_attr_fan2_speed.dev_attr.attr, | ||
209 | &sensor_dev_attr_fan2_fault.dev_attr.attr, | ||
210 | &sensor_dev_attr_fan3_speed.dev_attr.attr, | ||
211 | &sensor_dev_attr_fan3_fault.dev_attr.attr, | ||
212 | &sensor_dev_attr_fan4_speed.dev_attr.attr, | ||
213 | &sensor_dev_attr_fan4_fault.dev_attr.attr, | ||
214 | &sensor_dev_attr_psu_fan_fault.dev_attr.attr, | ||
215 | &sensor_dev_attr_adt7462_local_temp.dev_attr.attr, | ||
216 | &sensor_dev_attr_cpu0_temp.dev_attr.attr, | ||
217 | &sensor_dev_attr_cpu1_temp.dev_attr.attr, | ||
218 | &sensor_dev_attr_motherboard_temp.dev_attr.attr, | ||
219 | &sensor_dev_attr_lm95221_local_temp.dev_attr.attr, | ||
220 | &sensor_dev_attr_fire_temp.dev_attr.attr, | ||
221 | &sensor_dev_attr_lsi1064_local_temp.dev_attr.attr, | ||
222 | &sensor_dev_attr_front_panel_temp.dev_attr.attr, | ||
223 | &sensor_dev_attr_psu_temp.dev_attr.attr, | ||
224 | &sensor_dev_attr_fan_failure.dev_attr.attr, | ||
225 | &sensor_dev_attr_env_bus_busy.dev_attr.attr, | ||
226 | &sensor_dev_attr_env_data_stale.dev_attr.attr, | ||
227 | &sensor_dev_attr_tpm_self_test_passed.dev_attr.attr, | ||
228 | &sensor_dev_attr_firmware_version.dev_attr.attr, | ||
229 | &sensor_dev_attr_name.dev_attr.attr, | ||
230 | NULL, | ||
231 | }; | ||
232 | |||
233 | static const struct attribute_group env_group = { | ||
234 | .attrs = env_attributes, | ||
235 | }; | ||
236 | |||
237 | static int __devinit env_probe(struct of_device *op, | ||
238 | const struct of_device_id *match) | ||
239 | { | ||
240 | struct env *p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
241 | int err = -ENOMEM; | ||
242 | |||
243 | if (!p) | ||
244 | goto out; | ||
245 | |||
246 | spin_lock_init(&p->lock); | ||
247 | |||
248 | p->regs = of_ioremap(&op->resource[0], 0, REG_SIZE, "pic16f747"); | ||
249 | if (!p->regs) | ||
250 | goto out_free; | ||
251 | |||
252 | err = sysfs_create_group(&op->dev.kobj, &env_group); | ||
253 | if (err) | ||
254 | goto out_iounmap; | ||
255 | |||
256 | p->hwmon_dev = hwmon_device_register(&op->dev); | ||
257 | if (IS_ERR(p->hwmon_dev)) { | ||
258 | err = PTR_ERR(p->hwmon_dev); | ||
259 | goto out_sysfs_remove_group; | ||
260 | } | ||
261 | |||
262 | dev_set_drvdata(&op->dev, p); | ||
263 | err = 0; | ||
264 | |||
265 | out: | ||
266 | return err; | ||
267 | |||
268 | out_sysfs_remove_group: | ||
269 | sysfs_remove_group(&op->dev.kobj, &env_group); | ||
270 | |||
271 | out_iounmap: | ||
272 | of_iounmap(&op->resource[0], p->regs, REG_SIZE); | ||
273 | |||
274 | out_free: | ||
275 | kfree(p); | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | static int __devexit env_remove(struct of_device *op) | ||
280 | { | ||
281 | struct env *p = dev_get_drvdata(&op->dev); | ||
282 | |||
283 | if (p) { | ||
284 | sysfs_remove_group(&op->dev.kobj, &env_group); | ||
285 | hwmon_device_unregister(p->hwmon_dev); | ||
286 | of_iounmap(&op->resource[0], p->regs, REG_SIZE); | ||
287 | kfree(p); | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static const struct of_device_id env_match[] = { | ||
294 | { | ||
295 | .name = "env-monitor", | ||
296 | .compatible = "SUNW,ebus-pic16f747-env", | ||
297 | }, | ||
298 | {}, | ||
299 | }; | ||
300 | MODULE_DEVICE_TABLE(of, env_match); | ||
301 | |||
302 | static struct of_platform_driver env_driver = { | ||
303 | .name = "ultra45_env", | ||
304 | .match_table = env_match, | ||
305 | .probe = env_probe, | ||
306 | .remove = __devexit_p(env_remove), | ||
307 | }; | ||
308 | |||
309 | static int __init env_init(void) | ||
310 | { | ||
311 | return of_register_driver(&env_driver, &of_bus_type); | ||
312 | } | ||
313 | |||
314 | static void __exit env_exit(void) | ||
315 | { | ||
316 | of_unregister_driver(&env_driver); | ||
317 | } | ||
318 | |||
319 | module_init(env_init); | ||
320 | module_exit(env_exit); | ||
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 9564fb069957..b30e5796cb26 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -67,10 +67,6 @@ module_param(force_i2c, byte, 0); | |||
67 | MODULE_PARM_DESC(force_i2c, | 67 | MODULE_PARM_DESC(force_i2c, |
68 | "Initialize the i2c address of the sensors"); | 68 | "Initialize the i2c address of the sensors"); |
69 | 69 | ||
70 | static int reset; | ||
71 | module_param(reset, bool, 0); | ||
72 | MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); | ||
73 | |||
74 | static int init = 1; | 70 | static int init = 1; |
75 | module_param(init, bool, 0); | 71 | module_param(init, bool, 0); |
76 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | 72 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); |
@@ -209,6 +205,13 @@ static const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; | |||
209 | #define W83627HF_REG_PWM1 0x5A | 205 | #define W83627HF_REG_PWM1 0x5A |
210 | #define W83627HF_REG_PWM2 0x5B | 206 | #define W83627HF_REG_PWM2 0x5B |
211 | 207 | ||
208 | static const u8 W83627THF_REG_PWM_ENABLE[] = { | ||
209 | 0x04, /* FAN 1 mode */ | ||
210 | 0x04, /* FAN 2 mode */ | ||
211 | 0x12, /* FAN AUX mode */ | ||
212 | }; | ||
213 | static const u8 W83627THF_PWM_ENABLE_SHIFT[] = { 2, 4, 1 }; | ||
214 | |||
212 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ | 215 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ |
213 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ | 216 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ |
214 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ | 217 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ |
@@ -366,6 +369,9 @@ struct w83627hf_data { | |||
366 | u32 alarms; /* Register encoding, combined */ | 369 | u32 alarms; /* Register encoding, combined */ |
367 | u32 beep_mask; /* Register encoding, combined */ | 370 | u32 beep_mask; /* Register encoding, combined */ |
368 | u8 pwm[3]; /* Register value */ | 371 | u8 pwm[3]; /* Register value */ |
372 | u8 pwm_enable[3]; /* 1 = manual | ||
373 | 2 = thermal cruise (also called SmartFan I) | ||
374 | 3 = fan speed cruise */ | ||
369 | u8 pwm_freq[3]; /* Register value */ | 375 | u8 pwm_freq[3]; /* Register value */ |
370 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; | 376 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; |
371 | 4 = thermistor */ | 377 | 4 = thermistor */ |
@@ -957,6 +963,42 @@ static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1); | |||
957 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); | 963 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); |
958 | 964 | ||
959 | static ssize_t | 965 | static ssize_t |
966 | show_pwm_enable(struct device *dev, struct device_attribute *devattr, char *buf) | ||
967 | { | ||
968 | int nr = to_sensor_dev_attr(devattr)->index; | ||
969 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
970 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | ||
971 | } | ||
972 | |||
973 | static ssize_t | ||
974 | store_pwm_enable(struct device *dev, struct device_attribute *devattr, | ||
975 | const char *buf, size_t count) | ||
976 | { | ||
977 | int nr = to_sensor_dev_attr(devattr)->index; | ||
978 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
979 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
980 | u8 reg; | ||
981 | |||
982 | if (!val || (val > 3)) /* modes 1, 2 and 3 are supported */ | ||
983 | return -EINVAL; | ||
984 | mutex_lock(&data->update_lock); | ||
985 | data->pwm_enable[nr] = val; | ||
986 | reg = w83627hf_read_value(data, W83627THF_REG_PWM_ENABLE[nr]); | ||
987 | reg &= ~(0x03 << W83627THF_PWM_ENABLE_SHIFT[nr]); | ||
988 | reg |= (val - 1) << W83627THF_PWM_ENABLE_SHIFT[nr]; | ||
989 | w83627hf_write_value(data, W83627THF_REG_PWM_ENABLE[nr], reg); | ||
990 | mutex_unlock(&data->update_lock); | ||
991 | return count; | ||
992 | } | ||
993 | |||
994 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
995 | store_pwm_enable, 0); | ||
996 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
997 | store_pwm_enable, 1); | ||
998 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
999 | store_pwm_enable, 2); | ||
1000 | |||
1001 | static ssize_t | ||
960 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) | 1002 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) |
961 | { | 1003 | { |
962 | int nr = to_sensor_dev_attr(devattr)->index; | 1004 | int nr = to_sensor_dev_attr(devattr)->index; |
@@ -1223,6 +1265,11 @@ static struct attribute *w83627hf_attributes_opt[] = { | |||
1223 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | 1265 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
1224 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | 1266 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
1225 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | 1267 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
1268 | |||
1269 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
1270 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
1271 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
1272 | |||
1226 | NULL | 1273 | NULL |
1227 | }; | 1274 | }; |
1228 | 1275 | ||
@@ -1366,6 +1413,19 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1366 | &sensor_dev_attr_pwm3_freq.dev_attr))) | 1413 | &sensor_dev_attr_pwm3_freq.dev_attr))) |
1367 | goto ERROR4; | 1414 | goto ERROR4; |
1368 | 1415 | ||
1416 | if (data->type != w83627hf) | ||
1417 | if ((err = device_create_file(dev, | ||
1418 | &sensor_dev_attr_pwm1_enable.dev_attr)) | ||
1419 | || (err = device_create_file(dev, | ||
1420 | &sensor_dev_attr_pwm2_enable.dev_attr))) | ||
1421 | goto ERROR4; | ||
1422 | |||
1423 | if (data->type == w83627thf || data->type == w83637hf | ||
1424 | || data->type == w83687thf) | ||
1425 | if ((err = device_create_file(dev, | ||
1426 | &sensor_dev_attr_pwm3_enable.dev_attr))) | ||
1427 | goto ERROR4; | ||
1428 | |||
1369 | data->hwmon_dev = hwmon_device_register(dev); | 1429 | data->hwmon_dev = hwmon_device_register(dev); |
1370 | if (IS_ERR(data->hwmon_dev)) { | 1430 | if (IS_ERR(data->hwmon_dev)) { |
1371 | err = PTR_ERR(data->hwmon_dev); | 1431 | err = PTR_ERR(data->hwmon_dev); |
@@ -1536,29 +1596,6 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
1536 | enum chips type = data->type; | 1596 | enum chips type = data->type; |
1537 | u8 tmp; | 1597 | u8 tmp; |
1538 | 1598 | ||
1539 | if (reset) { | ||
1540 | /* Resetting the chip has been the default for a long time, | ||
1541 | but repeatedly caused problems (fans going to full | ||
1542 | speed...) so it is now optional. It might even go away if | ||
1543 | nobody reports it as being useful, as I see very little | ||
1544 | reason why this would be needed at all. */ | ||
1545 | dev_info(&pdev->dev, "If reset=1 solved a problem you were " | ||
1546 | "having, please report!\n"); | ||
1547 | |||
1548 | /* save this register */ | ||
1549 | i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG); | ||
1550 | /* Reset all except Watchdog values and last conversion values | ||
1551 | This sets fan-divs to 2, among others */ | ||
1552 | w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80); | ||
1553 | /* Restore the register and disable power-on abnormal beep. | ||
1554 | This saves FAN 1/2/3 input/output values set by BIOS. */ | ||
1555 | w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); | ||
1556 | /* Disable master beep-enable (reset turns it on). | ||
1557 | Individual beeps should be reset to off but for some reason | ||
1558 | disabling this bit helps some people not get beeped */ | ||
1559 | w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0); | ||
1560 | } | ||
1561 | |||
1562 | /* Minimize conflicts with other winbond i2c-only clients... */ | 1599 | /* Minimize conflicts with other winbond i2c-only clients... */ |
1563 | /* disable i2c subclients... how to disable main i2c client?? */ | 1600 | /* disable i2c subclients... how to disable main i2c client?? */ |
1564 | /* force i2c address to relatively uncommon address */ | 1601 | /* force i2c address to relatively uncommon address */ |
@@ -1655,6 +1692,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1655 | { | 1692 | { |
1656 | struct w83627hf_data *data = dev_get_drvdata(dev); | 1693 | struct w83627hf_data *data = dev_get_drvdata(dev); |
1657 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; | 1694 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; |
1695 | int num_pwms = (data->type == w83697hf) ? 2 : 3; | ||
1658 | 1696 | ||
1659 | mutex_lock(&data->update_lock); | 1697 | mutex_lock(&data->update_lock); |
1660 | 1698 | ||
@@ -1707,6 +1745,15 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1707 | break; | 1745 | break; |
1708 | } | 1746 | } |
1709 | } | 1747 | } |
1748 | if (data->type != w83627hf) { | ||
1749 | for (i = 0; i < num_pwms; i++) { | ||
1750 | u8 tmp = w83627hf_read_value(data, | ||
1751 | W83627THF_REG_PWM_ENABLE[i]); | ||
1752 | data->pwm_enable[i] = | ||
1753 | ((tmp >> W83627THF_PWM_ENABLE_SHIFT[i]) | ||
1754 | & 0x03) + 1; | ||
1755 | } | ||
1756 | } | ||
1710 | for (i = 0; i < num_temps; i++) { | 1757 | for (i = 0; i < num_temps; i++) { |
1711 | data->temp[i] = w83627hf_read_value( | 1758 | data->temp[i] = w83627hf_read_value( |
1712 | data, w83627hf_reg_temp[i]); | 1759 | data, w83627hf_reg_temp[i]); |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index f942ecdd47c8..fc12bd412e3a 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -4,7 +4,7 @@ | |||
4 | Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, | 4 | Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, |
5 | Philip Edelbrock <phil@netroedge.com>, | 5 | Philip Edelbrock <phil@netroedge.com>, |
6 | and Mark Studebaker <mdsxyz123@yahoo.com> | 6 | and Mark Studebaker <mdsxyz123@yahoo.com> |
7 | Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> | 7 | Copyright (c) 2007 - 2008 Jean Delvare <khali@linux-fr.org> |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
@@ -38,25 +38,24 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/platform_device.h> | ||
42 | #include <linux/ioport.h> | ||
43 | #include <linux/hwmon.h> | 41 | #include <linux/hwmon.h> |
44 | #include <linux/hwmon-vid.h> | 42 | #include <linux/hwmon-vid.h> |
45 | #include <linux/hwmon-sysfs.h> | 43 | #include <linux/hwmon-sysfs.h> |
46 | #include <linux/sysfs.h> | 44 | #include <linux/sysfs.h> |
47 | #include <linux/err.h> | 45 | #include <linux/err.h> |
48 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
47 | |||
48 | #ifdef CONFIG_ISA | ||
49 | #include <linux/platform_device.h> | ||
50 | #include <linux/ioport.h> | ||
49 | #include <asm/io.h> | 51 | #include <asm/io.h> |
50 | #include "lm75.h" | 52 | #endif |
51 | 53 | ||
52 | /* ISA device, if found */ | 54 | #include "lm75.h" |
53 | static struct platform_device *pdev; | ||
54 | 55 | ||
55 | /* Addresses to scan */ | 56 | /* Addresses to scan */ |
56 | static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, | 57 | static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, |
57 | 0x2e, 0x2f, I2C_CLIENT_END }; | 58 | 0x2e, 0x2f, I2C_CLIENT_END }; |
58 | static unsigned short isa_address = 0x290; | ||
59 | |||
60 | /* Insmod parameters */ | 59 | /* Insmod parameters */ |
61 | I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f); | 60 | I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f); |
62 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " | 61 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " |
@@ -178,9 +177,9 @@ FAN_FROM_REG(u8 val, int div) | |||
178 | #define TEMP_FROM_REG(val) ((val) * 1000) | 177 | #define TEMP_FROM_REG(val) ((val) * 1000) |
179 | 178 | ||
180 | #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ | 179 | #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ |
181 | (val) ^ 0x7fff : (val)) | 180 | (~(val)) & 0x7fff : (val) & 0xff7fff) |
182 | #define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ | 181 | #define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ |
183 | (~(val)) & 0x7fff : (val) & 0xffffff) | 182 | (~(val)) & 0x7fff : (val) & 0xff7fff) |
184 | 183 | ||
185 | #define DIV_FROM_REG(val) (1 << (val)) | 184 | #define DIV_FROM_REG(val) (1 << (val)) |
186 | 185 | ||
@@ -199,25 +198,16 @@ DIV_TO_REG(long val, enum chips type) | |||
199 | return i; | 198 | return i; |
200 | } | 199 | } |
201 | 200 | ||
202 | /* There are some complications in a module like this. First off, W83781D chips | ||
203 | may be both present on the SMBus and the ISA bus, and we have to handle | ||
204 | those cases separately at some places. Second, there might be several | ||
205 | W83781D chips available (well, actually, that is probably never done; but | ||
206 | it is a clean illustration of how to handle a case like that). Finally, | ||
207 | a specific chip may be attached to *both* ISA and SMBus, and we would | ||
208 | not like to detect it double. Fortunately, in the case of the W83781D at | ||
209 | least, a register tells us what SMBus address we are on, so that helps | ||
210 | a bit - except if there could be more than one SMBus. Groan. No solution | ||
211 | for this yet. */ | ||
212 | |||
213 | /* For ISA chips, we abuse the i2c_client addr and name fields. We also use | ||
214 | the driver field to differentiate between I2C and ISA chips. */ | ||
215 | struct w83781d_data { | 201 | struct w83781d_data { |
216 | struct i2c_client client; | 202 | struct i2c_client *client; |
217 | struct device *hwmon_dev; | 203 | struct device *hwmon_dev; |
218 | struct mutex lock; | 204 | struct mutex lock; |
219 | enum chips type; | 205 | enum chips type; |
220 | 206 | ||
207 | /* For ISA device only */ | ||
208 | const char *name; | ||
209 | int isa_addr; | ||
210 | |||
221 | struct mutex update_lock; | 211 | struct mutex update_lock; |
222 | char valid; /* !=0 if following fields are valid */ | 212 | char valid; /* !=0 if following fields are valid */ |
223 | unsigned long last_updated; /* In jiffies */ | 213 | unsigned long last_updated; /* In jiffies */ |
@@ -240,7 +230,6 @@ struct w83781d_data { | |||
240 | u8 vid; /* Register encoding, combined */ | 230 | u8 vid; /* Register encoding, combined */ |
241 | u32 alarms; /* Register encoding, combined */ | 231 | u32 alarms; /* Register encoding, combined */ |
242 | u32 beep_mask; /* Register encoding, combined */ | 232 | u32 beep_mask; /* Register encoding, combined */ |
243 | u8 beep_enable; /* Boolean */ | ||
244 | u8 pwm[4]; /* Register value */ | 233 | u8 pwm[4]; /* Register value */ |
245 | u8 pwm2_enable; /* Boolean */ | 234 | u8 pwm2_enable; /* Boolean */ |
246 | u16 sens[3]; /* 782D/783S only. | 235 | u16 sens[3]; /* 782D/783S only. |
@@ -249,36 +238,14 @@ struct w83781d_data { | |||
249 | u8 vrm; | 238 | u8 vrm; |
250 | }; | 239 | }; |
251 | 240 | ||
252 | static int w83781d_attach_adapter(struct i2c_adapter *adapter); | 241 | static struct w83781d_data *w83781d_data_if_isa(void); |
253 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); | 242 | static int w83781d_alias_detect(struct i2c_client *client, u8 chipid); |
254 | static int w83781d_detach_client(struct i2c_client *client); | ||
255 | |||
256 | static int __devinit w83781d_isa_probe(struct platform_device *pdev); | ||
257 | static int __devexit w83781d_isa_remove(struct platform_device *pdev); | ||
258 | 243 | ||
259 | static int w83781d_read_value(struct w83781d_data *data, u16 reg); | 244 | static int w83781d_read_value(struct w83781d_data *data, u16 reg); |
260 | static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value); | 245 | static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value); |
261 | static struct w83781d_data *w83781d_update_device(struct device *dev); | 246 | static struct w83781d_data *w83781d_update_device(struct device *dev); |
262 | static void w83781d_init_device(struct device *dev); | 247 | static void w83781d_init_device(struct device *dev); |
263 | 248 | ||
264 | static struct i2c_driver w83781d_driver = { | ||
265 | .driver = { | ||
266 | .name = "w83781d", | ||
267 | }, | ||
268 | .attach_adapter = w83781d_attach_adapter, | ||
269 | .detach_client = w83781d_detach_client, | ||
270 | }; | ||
271 | |||
272 | static struct platform_driver w83781d_isa_driver = { | ||
273 | .driver = { | ||
274 | .owner = THIS_MODULE, | ||
275 | .name = "w83781d", | ||
276 | }, | ||
277 | .probe = w83781d_isa_probe, | ||
278 | .remove = w83781d_isa_remove, | ||
279 | }; | ||
280 | |||
281 | |||
282 | /* following are the sysfs callback functions */ | 249 | /* following are the sysfs callback functions */ |
283 | #define show_in_reg(reg) \ | 250 | #define show_in_reg(reg) \ |
284 | static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ | 251 | static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ |
@@ -513,11 +480,6 @@ static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr | |||
513 | return sprintf(buf, "%ld\n", | 480 | return sprintf(buf, "%ld\n", |
514 | (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type)); | 481 | (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type)); |
515 | } | 482 | } |
516 | static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf) | ||
517 | { | ||
518 | struct w83781d_data *data = w83781d_update_device(dev); | ||
519 | return sprintf(buf, "%ld\n", (long)data->beep_enable); | ||
520 | } | ||
521 | 483 | ||
522 | static ssize_t | 484 | static ssize_t |
523 | store_beep_mask(struct device *dev, struct device_attribute *attr, | 485 | store_beep_mask(struct device *dev, struct device_attribute *attr, |
@@ -529,12 +491,12 @@ store_beep_mask(struct device *dev, struct device_attribute *attr, | |||
529 | val = simple_strtoul(buf, NULL, 10); | 491 | val = simple_strtoul(buf, NULL, 10); |
530 | 492 | ||
531 | mutex_lock(&data->update_lock); | 493 | mutex_lock(&data->update_lock); |
532 | data->beep_mask = BEEP_MASK_TO_REG(val, data->type); | 494 | data->beep_mask &= 0x8000; /* preserve beep enable */ |
495 | data->beep_mask |= BEEP_MASK_TO_REG(val, data->type); | ||
533 | w83781d_write_value(data, W83781D_REG_BEEP_INTS1, | 496 | w83781d_write_value(data, W83781D_REG_BEEP_INTS1, |
534 | data->beep_mask & 0xff); | 497 | data->beep_mask & 0xff); |
535 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, | 498 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, |
536 | ((data->beep_mask >> 8) & 0x7f) | 499 | (data->beep_mask >> 8) & 0xff); |
537 | | data->beep_enable << 7); | ||
538 | if (data->type != w83781d && data->type != as99127f) { | 500 | if (data->type != w83781d && data->type != as99127f) { |
539 | w83781d_write_value(data, W83781D_REG_BEEP_INTS3, | 501 | w83781d_write_value(data, W83781D_REG_BEEP_INTS3, |
540 | ((data->beep_mask) >> 16) & 0xff); | 502 | ((data->beep_mask) >> 16) & 0xff); |
@@ -544,31 +506,8 @@ store_beep_mask(struct device *dev, struct device_attribute *attr, | |||
544 | return count; | 506 | return count; |
545 | } | 507 | } |
546 | 508 | ||
547 | static ssize_t | ||
548 | store_beep_enable(struct device *dev, struct device_attribute *attr, | ||
549 | const char *buf, size_t count) | ||
550 | { | ||
551 | struct w83781d_data *data = dev_get_drvdata(dev); | ||
552 | u32 val; | ||
553 | |||
554 | val = simple_strtoul(buf, NULL, 10); | ||
555 | if (val != 0 && val != 1) | ||
556 | return -EINVAL; | ||
557 | |||
558 | mutex_lock(&data->update_lock); | ||
559 | data->beep_enable = val; | ||
560 | val = w83781d_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f; | ||
561 | val |= data->beep_enable << 7; | ||
562 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, val); | ||
563 | mutex_unlock(&data->update_lock); | ||
564 | |||
565 | return count; | ||
566 | } | ||
567 | |||
568 | static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, | 509 | static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, |
569 | show_beep_mask, store_beep_mask); | 510 | show_beep_mask, store_beep_mask); |
570 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, | ||
571 | show_beep_enable, store_beep_enable); | ||
572 | 511 | ||
573 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, | 512 | static ssize_t show_beep(struct device *dev, struct device_attribute *attr, |
574 | char *buf) | 513 | char *buf) |
@@ -663,6 +602,8 @@ static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR, | |||
663 | show_beep, store_beep, 5); | 602 | show_beep, store_beep, 5); |
664 | static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, | 603 | static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, |
665 | show_temp3_beep, store_beep, 13); | 604 | show_temp3_beep, store_beep, 13); |
605 | static SENSOR_DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, | ||
606 | show_beep, store_beep, 15); | ||
666 | 607 | ||
667 | static ssize_t | 608 | static ssize_t |
668 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) | 609 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) |
@@ -866,45 +807,19 @@ static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, | |||
866 | static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, | 807 | static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, |
867 | show_sensor, store_sensor, 2); | 808 | show_sensor, store_sensor, 2); |
868 | 809 | ||
869 | /* I2C devices get this name attribute automatically, but for ISA devices | ||
870 | we must create it by ourselves. */ | ||
871 | static ssize_t | ||
872 | show_name(struct device *dev, struct device_attribute *devattr, char *buf) | ||
873 | { | ||
874 | struct w83781d_data *data = dev_get_drvdata(dev); | ||
875 | return sprintf(buf, "%s\n", data->client.name); | ||
876 | } | ||
877 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
878 | |||
879 | /* This function is called when: | ||
880 | * w83781d_driver is inserted (when this module is loaded), for each | ||
881 | available adapter | ||
882 | * when a new adapter is inserted (and w83781d_driver is still present) */ | ||
883 | static int | ||
884 | w83781d_attach_adapter(struct i2c_adapter *adapter) | ||
885 | { | ||
886 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
887 | return 0; | ||
888 | return i2c_probe(adapter, &addr_data, w83781d_detect); | ||
889 | } | ||
890 | |||
891 | /* Assumes that adapter is of I2C, not ISA variety. | 810 | /* Assumes that adapter is of I2C, not ISA variety. |
892 | * OTHERWISE DON'T CALL THIS | 811 | * OTHERWISE DON'T CALL THIS |
893 | */ | 812 | */ |
894 | static int | 813 | static int |
895 | w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, | 814 | w83781d_detect_subclients(struct i2c_client *new_client) |
896 | struct i2c_client *new_client) | ||
897 | { | 815 | { |
898 | int i, val1 = 0, id; | 816 | int i, val1 = 0, id; |
899 | int err; | 817 | int err; |
900 | const char *client_name = ""; | 818 | int address = new_client->addr; |
819 | unsigned short sc_addr[2]; | ||
820 | struct i2c_adapter *adapter = new_client->adapter; | ||
901 | struct w83781d_data *data = i2c_get_clientdata(new_client); | 821 | struct w83781d_data *data = i2c_get_clientdata(new_client); |
902 | 822 | enum chips kind = data->type; | |
903 | data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
904 | if (!(data->lm75[0])) { | ||
905 | err = -ENOMEM; | ||
906 | goto ERROR_SC_0; | ||
907 | } | ||
908 | 823 | ||
909 | id = i2c_adapter_id(adapter); | 824 | id = i2c_adapter_id(adapter); |
910 | 825 | ||
@@ -922,55 +837,35 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, | |||
922 | w83781d_write_value(data, W83781D_REG_I2C_SUBADDR, | 837 | w83781d_write_value(data, W83781D_REG_I2C_SUBADDR, |
923 | (force_subclients[2] & 0x07) | | 838 | (force_subclients[2] & 0x07) | |
924 | ((force_subclients[3] & 0x07) << 4)); | 839 | ((force_subclients[3] & 0x07) << 4)); |
925 | data->lm75[0]->addr = force_subclients[2]; | 840 | sc_addr[0] = force_subclients[2]; |
926 | } else { | 841 | } else { |
927 | val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR); | 842 | val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR); |
928 | data->lm75[0]->addr = 0x48 + (val1 & 0x07); | 843 | sc_addr[0] = 0x48 + (val1 & 0x07); |
929 | } | 844 | } |
930 | 845 | ||
931 | if (kind != w83783s) { | 846 | if (kind != w83783s) { |
932 | data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
933 | if (!(data->lm75[1])) { | ||
934 | err = -ENOMEM; | ||
935 | goto ERROR_SC_1; | ||
936 | } | ||
937 | |||
938 | if (force_subclients[0] == id && | 847 | if (force_subclients[0] == id && |
939 | force_subclients[1] == address) { | 848 | force_subclients[1] == address) { |
940 | data->lm75[1]->addr = force_subclients[3]; | 849 | sc_addr[1] = force_subclients[3]; |
941 | } else { | 850 | } else { |
942 | data->lm75[1]->addr = 0x48 + ((val1 >> 4) & 0x07); | 851 | sc_addr[1] = 0x48 + ((val1 >> 4) & 0x07); |
943 | } | 852 | } |
944 | if (data->lm75[0]->addr == data->lm75[1]->addr) { | 853 | if (sc_addr[0] == sc_addr[1]) { |
945 | dev_err(&new_client->dev, | 854 | dev_err(&new_client->dev, |
946 | "Duplicate addresses 0x%x for subclients.\n", | 855 | "Duplicate addresses 0x%x for subclients.\n", |
947 | data->lm75[0]->addr); | 856 | sc_addr[0]); |
948 | err = -EBUSY; | 857 | err = -EBUSY; |
949 | goto ERROR_SC_2; | 858 | goto ERROR_SC_2; |
950 | } | 859 | } |
951 | } | 860 | } |
952 | 861 | ||
953 | if (kind == w83781d) | ||
954 | client_name = "w83781d subclient"; | ||
955 | else if (kind == w83782d) | ||
956 | client_name = "w83782d subclient"; | ||
957 | else if (kind == w83783s) | ||
958 | client_name = "w83783s subclient"; | ||
959 | else if (kind == as99127f) | ||
960 | client_name = "as99127f subclient"; | ||
961 | |||
962 | for (i = 0; i <= 1; i++) { | 862 | for (i = 0; i <= 1; i++) { |
963 | /* store all data in w83781d */ | 863 | data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]); |
964 | i2c_set_clientdata(data->lm75[i], NULL); | 864 | if (!data->lm75[i]) { |
965 | data->lm75[i]->adapter = adapter; | ||
966 | data->lm75[i]->driver = &w83781d_driver; | ||
967 | data->lm75[i]->flags = 0; | ||
968 | strlcpy(data->lm75[i]->name, client_name, | ||
969 | I2C_NAME_SIZE); | ||
970 | if ((err = i2c_attach_client(data->lm75[i]))) { | ||
971 | dev_err(&new_client->dev, "Subclient %d " | 865 | dev_err(&new_client->dev, "Subclient %d " |
972 | "registration at address 0x%x " | 866 | "registration at address 0x%x " |
973 | "failed.\n", i, data->lm75[i]->addr); | 867 | "failed.\n", i, sc_addr[i]); |
868 | err = -ENOMEM; | ||
974 | if (i == 1) | 869 | if (i == 1) |
975 | goto ERROR_SC_3; | 870 | goto ERROR_SC_3; |
976 | goto ERROR_SC_2; | 871 | goto ERROR_SC_2; |
@@ -983,12 +878,9 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, | |||
983 | 878 | ||
984 | /* Undo inits in case of errors */ | 879 | /* Undo inits in case of errors */ |
985 | ERROR_SC_3: | 880 | ERROR_SC_3: |
986 | i2c_detach_client(data->lm75[0]); | 881 | i2c_unregister_device(data->lm75[0]); |
987 | ERROR_SC_2: | 882 | ERROR_SC_2: |
988 | kfree(data->lm75[1]); | ||
989 | ERROR_SC_1: | 883 | ERROR_SC_1: |
990 | kfree(data->lm75[0]); | ||
991 | ERROR_SC_0: | ||
992 | return err; | 884 | return err; |
993 | } | 885 | } |
994 | 886 | ||
@@ -1029,7 +921,7 @@ static struct attribute* w83781d_attributes[] = { | |||
1029 | &dev_attr_vrm.attr, | 921 | &dev_attr_vrm.attr, |
1030 | &dev_attr_alarms.attr, | 922 | &dev_attr_alarms.attr, |
1031 | &dev_attr_beep_mask.attr, | 923 | &dev_attr_beep_mask.attr, |
1032 | &dev_attr_beep_enable.attr, | 924 | &sensor_dev_attr_beep_enable.dev_attr.attr, |
1033 | NULL | 925 | NULL |
1034 | }; | 926 | }; |
1035 | static const struct attribute_group w83781d_group = { | 927 | static const struct attribute_group w83781d_group = { |
@@ -1151,96 +1043,74 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
1151 | } | 1043 | } |
1152 | } | 1044 | } |
1153 | 1045 | ||
1154 | if (is_isa) { | ||
1155 | err = device_create_file(&pdev->dev, &dev_attr_name); | ||
1156 | if (err) | ||
1157 | return err; | ||
1158 | } | ||
1159 | |||
1160 | return 0; | 1046 | return 0; |
1161 | } | 1047 | } |
1162 | 1048 | ||
1049 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
1163 | static int | 1050 | static int |
1164 | w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | 1051 | w83781d_detect(struct i2c_client *client, int kind, |
1052 | struct i2c_board_info *info) | ||
1165 | { | 1053 | { |
1166 | int val1 = 0, val2; | 1054 | int val1 = 0, val2; |
1167 | struct i2c_client *client; | 1055 | struct w83781d_data *isa = w83781d_data_if_isa(); |
1168 | struct device *dev; | 1056 | struct i2c_adapter *adapter = client->adapter; |
1169 | struct w83781d_data *data; | 1057 | int address = client->addr; |
1170 | int err; | ||
1171 | const char *client_name = ""; | 1058 | const char *client_name = ""; |
1172 | enum vendor { winbond, asus } vendid; | 1059 | enum vendor { winbond, asus } vendid; |
1173 | 1060 | ||
1174 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1061 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1175 | err = -EINVAL; | 1062 | return -ENODEV; |
1176 | goto ERROR1; | ||
1177 | } | ||
1178 | |||
1179 | /* OK. For now, we presume we have a valid client. We now create the | ||
1180 | client structure, even though we cannot fill it completely yet. | ||
1181 | But it allows us to access w83781d_{read,write}_value. */ | ||
1182 | |||
1183 | if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { | ||
1184 | err = -ENOMEM; | ||
1185 | goto ERROR1; | ||
1186 | } | ||
1187 | |||
1188 | client = &data->client; | ||
1189 | i2c_set_clientdata(client, data); | ||
1190 | client->addr = address; | ||
1191 | mutex_init(&data->lock); | ||
1192 | client->adapter = adapter; | ||
1193 | client->driver = &w83781d_driver; | ||
1194 | dev = &client->dev; | ||
1195 | 1063 | ||
1196 | /* Now, we do the remaining detection. */ | 1064 | /* We block updates of the ISA device to minimize the risk of |
1065 | concurrent access to the same W83781D chip through different | ||
1066 | interfaces. */ | ||
1067 | if (isa) | ||
1068 | mutex_lock(&isa->update_lock); | ||
1197 | 1069 | ||
1198 | /* The w8378?d may be stuck in some other bank than bank 0. This may | 1070 | /* The w8378?d may be stuck in some other bank than bank 0. This may |
1199 | make reading other information impossible. Specify a force=... or | 1071 | make reading other information impossible. Specify a force=... or |
1200 | force_*=... parameter, and the Winbond will be reset to the right | 1072 | force_*=... parameter, and the Winbond will be reset to the right |
1201 | bank. */ | 1073 | bank. */ |
1202 | if (kind < 0) { | 1074 | if (kind < 0) { |
1203 | if (w83781d_read_value(data, W83781D_REG_CONFIG) & 0x80) { | 1075 | if (i2c_smbus_read_byte_data |
1076 | (client, W83781D_REG_CONFIG) & 0x80) { | ||
1204 | dev_dbg(&adapter->dev, "Detection of w83781d chip " | 1077 | dev_dbg(&adapter->dev, "Detection of w83781d chip " |
1205 | "failed at step 3\n"); | 1078 | "failed at step 3\n"); |
1206 | err = -ENODEV; | 1079 | goto err_nodev; |
1207 | goto ERROR2; | ||
1208 | } | 1080 | } |
1209 | val1 = w83781d_read_value(data, W83781D_REG_BANK); | 1081 | val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK); |
1210 | val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN); | 1082 | val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN); |
1211 | /* Check for Winbond or Asus ID if in bank 0 */ | 1083 | /* Check for Winbond or Asus ID if in bank 0 */ |
1212 | if ((!(val1 & 0x07)) && | 1084 | if ((!(val1 & 0x07)) && |
1213 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) | 1085 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) |
1214 | || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { | 1086 | || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { |
1215 | dev_dbg(&adapter->dev, "Detection of w83781d chip " | 1087 | dev_dbg(&adapter->dev, "Detection of w83781d chip " |
1216 | "failed at step 4\n"); | 1088 | "failed at step 4\n"); |
1217 | err = -ENODEV; | 1089 | goto err_nodev; |
1218 | goto ERROR2; | ||
1219 | } | 1090 | } |
1220 | /* If Winbond SMBus, check address at 0x48. | 1091 | /* If Winbond SMBus, check address at 0x48. |
1221 | Asus doesn't support, except for as99127f rev.2 */ | 1092 | Asus doesn't support, except for as99127f rev.2 */ |
1222 | if ((!(val1 & 0x80) && (val2 == 0xa3)) || | 1093 | if ((!(val1 & 0x80) && (val2 == 0xa3)) || |
1223 | ((val1 & 0x80) && (val2 == 0x5c))) { | 1094 | ((val1 & 0x80) && (val2 == 0x5c))) { |
1224 | if (w83781d_read_value | 1095 | if (i2c_smbus_read_byte_data |
1225 | (data, W83781D_REG_I2C_ADDR) != address) { | 1096 | (client, W83781D_REG_I2C_ADDR) != address) { |
1226 | dev_dbg(&adapter->dev, "Detection of w83781d " | 1097 | dev_dbg(&adapter->dev, "Detection of w83781d " |
1227 | "chip failed at step 5\n"); | 1098 | "chip failed at step 5\n"); |
1228 | err = -ENODEV; | 1099 | goto err_nodev; |
1229 | goto ERROR2; | ||
1230 | } | 1100 | } |
1231 | } | 1101 | } |
1232 | } | 1102 | } |
1233 | 1103 | ||
1234 | /* We have either had a force parameter, or we have already detected the | 1104 | /* We have either had a force parameter, or we have already detected the |
1235 | Winbond. Put it now into bank 0 and Vendor ID High Byte */ | 1105 | Winbond. Put it now into bank 0 and Vendor ID High Byte */ |
1236 | w83781d_write_value(data, W83781D_REG_BANK, | 1106 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, |
1237 | (w83781d_read_value(data, W83781D_REG_BANK) | 1107 | (i2c_smbus_read_byte_data(client, W83781D_REG_BANK) |
1238 | & 0x78) | 0x80); | 1108 | & 0x78) | 0x80); |
1239 | 1109 | ||
1240 | /* Determine the chip type. */ | 1110 | /* Determine the chip type. */ |
1241 | if (kind <= 0) { | 1111 | if (kind <= 0) { |
1242 | /* get vendor ID */ | 1112 | /* get vendor ID */ |
1243 | val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN); | 1113 | val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN); |
1244 | if (val2 == 0x5c) | 1114 | if (val2 == 0x5c) |
1245 | vendid = winbond; | 1115 | vendid = winbond; |
1246 | else if (val2 == 0x12) | 1116 | else if (val2 == 0x12) |
@@ -1248,11 +1118,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1248 | else { | 1118 | else { |
1249 | dev_dbg(&adapter->dev, "w83781d chip vendor is " | 1119 | dev_dbg(&adapter->dev, "w83781d chip vendor is " |
1250 | "neither Winbond nor Asus\n"); | 1120 | "neither Winbond nor Asus\n"); |
1251 | err = -ENODEV; | 1121 | goto err_nodev; |
1252 | goto ERROR2; | ||
1253 | } | 1122 | } |
1254 | 1123 | ||
1255 | val1 = w83781d_read_value(data, W83781D_REG_WCHIPID); | 1124 | val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID); |
1256 | if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) | 1125 | if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) |
1257 | kind = w83781d; | 1126 | kind = w83781d; |
1258 | else if (val1 == 0x30 && vendid == winbond) | 1127 | else if (val1 == 0x30 && vendid == winbond) |
@@ -1266,11 +1135,20 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1266 | dev_warn(&adapter->dev, "Ignoring 'force' " | 1135 | dev_warn(&adapter->dev, "Ignoring 'force' " |
1267 | "parameter for unknown chip at " | 1136 | "parameter for unknown chip at " |
1268 | "address 0x%02x\n", address); | 1137 | "address 0x%02x\n", address); |
1269 | err = -EINVAL; | 1138 | goto err_nodev; |
1270 | goto ERROR2; | 1139 | } |
1140 | |||
1141 | if ((kind == w83781d || kind == w83782d) | ||
1142 | && w83781d_alias_detect(client, val1)) { | ||
1143 | dev_dbg(&adapter->dev, "Device at 0x%02x appears to " | ||
1144 | "be the same as ISA device\n", address); | ||
1145 | goto err_nodev; | ||
1271 | } | 1146 | } |
1272 | } | 1147 | } |
1273 | 1148 | ||
1149 | if (isa) | ||
1150 | mutex_unlock(&isa->update_lock); | ||
1151 | |||
1274 | if (kind == w83781d) { | 1152 | if (kind == w83781d) { |
1275 | client_name = "w83781d"; | 1153 | client_name = "w83781d"; |
1276 | } else if (kind == w83782d) { | 1154 | } else if (kind == w83782d) { |
@@ -1281,24 +1159,46 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1281 | client_name = "as99127f"; | 1159 | client_name = "as99127f"; |
1282 | } | 1160 | } |
1283 | 1161 | ||
1284 | /* Fill in the remaining client fields and put into the global list */ | 1162 | strlcpy(info->type, client_name, I2C_NAME_SIZE); |
1285 | strlcpy(client->name, client_name, I2C_NAME_SIZE); | 1163 | |
1286 | data->type = kind; | 1164 | return 0; |
1165 | |||
1166 | err_nodev: | ||
1167 | if (isa) | ||
1168 | mutex_unlock(&isa->update_lock); | ||
1169 | return -ENODEV; | ||
1170 | } | ||
1171 | |||
1172 | static int | ||
1173 | w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
1174 | { | ||
1175 | struct device *dev = &client->dev; | ||
1176 | struct w83781d_data *data; | ||
1177 | int err; | ||
1178 | |||
1179 | data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL); | ||
1180 | if (!data) { | ||
1181 | err = -ENOMEM; | ||
1182 | goto ERROR1; | ||
1183 | } | ||
1184 | |||
1185 | i2c_set_clientdata(client, data); | ||
1186 | mutex_init(&data->lock); | ||
1187 | mutex_init(&data->update_lock); | ||
1287 | 1188 | ||
1288 | /* Tell the I2C layer a new client has arrived */ | 1189 | data->type = id->driver_data; |
1289 | if ((err = i2c_attach_client(client))) | 1190 | data->client = client; |
1290 | goto ERROR2; | ||
1291 | 1191 | ||
1292 | /* attach secondary i2c lm75-like clients */ | 1192 | /* attach secondary i2c lm75-like clients */ |
1293 | if ((err = w83781d_detect_subclients(adapter, address, | 1193 | err = w83781d_detect_subclients(client); |
1294 | kind, client))) | 1194 | if (err) |
1295 | goto ERROR3; | 1195 | goto ERROR3; |
1296 | 1196 | ||
1297 | /* Initialize the chip */ | 1197 | /* Initialize the chip */ |
1298 | w83781d_init_device(dev); | 1198 | w83781d_init_device(dev); |
1299 | 1199 | ||
1300 | /* Register sysfs hooks */ | 1200 | /* Register sysfs hooks */ |
1301 | err = w83781d_create_files(dev, kind, 0); | 1201 | err = w83781d_create_files(dev, data->type, 0); |
1302 | if (err) | 1202 | if (err) |
1303 | goto ERROR4; | 1203 | goto ERROR4; |
1304 | 1204 | ||
@@ -1314,264 +1214,113 @@ ERROR4: | |||
1314 | sysfs_remove_group(&dev->kobj, &w83781d_group); | 1214 | sysfs_remove_group(&dev->kobj, &w83781d_group); |
1315 | sysfs_remove_group(&dev->kobj, &w83781d_group_opt); | 1215 | sysfs_remove_group(&dev->kobj, &w83781d_group_opt); |
1316 | 1216 | ||
1317 | if (data->lm75[1]) { | 1217 | if (data->lm75[0]) |
1318 | i2c_detach_client(data->lm75[1]); | 1218 | i2c_unregister_device(data->lm75[0]); |
1319 | kfree(data->lm75[1]); | 1219 | if (data->lm75[1]) |
1320 | } | 1220 | i2c_unregister_device(data->lm75[1]); |
1321 | if (data->lm75[0]) { | ||
1322 | i2c_detach_client(data->lm75[0]); | ||
1323 | kfree(data->lm75[0]); | ||
1324 | } | ||
1325 | ERROR3: | 1221 | ERROR3: |
1326 | i2c_detach_client(client); | 1222 | i2c_set_clientdata(client, NULL); |
1327 | ERROR2: | ||
1328 | kfree(data); | 1223 | kfree(data); |
1329 | ERROR1: | 1224 | ERROR1: |
1330 | return err; | 1225 | return err; |
1331 | } | 1226 | } |
1332 | 1227 | ||
1333 | static int | 1228 | static int |
1334 | w83781d_detach_client(struct i2c_client *client) | 1229 | w83781d_remove(struct i2c_client *client) |
1335 | { | 1230 | { |
1336 | struct w83781d_data *data = i2c_get_clientdata(client); | 1231 | struct w83781d_data *data = i2c_get_clientdata(client); |
1337 | int err; | 1232 | struct device *dev = &client->dev; |
1338 | |||
1339 | /* main client */ | ||
1340 | if (data) { | ||
1341 | hwmon_device_unregister(data->hwmon_dev); | ||
1342 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); | ||
1343 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); | ||
1344 | } | ||
1345 | |||
1346 | if ((err = i2c_detach_client(client))) | ||
1347 | return err; | ||
1348 | 1233 | ||
1349 | /* main client */ | 1234 | hwmon_device_unregister(data->hwmon_dev); |
1350 | if (data) | ||
1351 | kfree(data); | ||
1352 | |||
1353 | /* subclient */ | ||
1354 | else | ||
1355 | kfree(client); | ||
1356 | |||
1357 | return 0; | ||
1358 | } | ||
1359 | |||
1360 | static int __devinit | ||
1361 | w83781d_isa_probe(struct platform_device *pdev) | ||
1362 | { | ||
1363 | int err, reg; | ||
1364 | struct w83781d_data *data; | ||
1365 | struct resource *res; | ||
1366 | const char *name; | ||
1367 | |||
1368 | /* Reserve the ISA region */ | ||
1369 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
1370 | if (!request_region(res->start + W83781D_ADDR_REG_OFFSET, 2, | ||
1371 | "w83781d")) { | ||
1372 | err = -EBUSY; | ||
1373 | goto exit; | ||
1374 | } | ||
1375 | |||
1376 | if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { | ||
1377 | err = -ENOMEM; | ||
1378 | goto exit_release_region; | ||
1379 | } | ||
1380 | mutex_init(&data->lock); | ||
1381 | data->client.addr = res->start; | ||
1382 | i2c_set_clientdata(&data->client, data); | ||
1383 | platform_set_drvdata(pdev, data); | ||
1384 | |||
1385 | reg = w83781d_read_value(data, W83781D_REG_WCHIPID); | ||
1386 | switch (reg) { | ||
1387 | case 0x30: | ||
1388 | data->type = w83782d; | ||
1389 | name = "w83782d"; | ||
1390 | break; | ||
1391 | default: | ||
1392 | data->type = w83781d; | ||
1393 | name = "w83781d"; | ||
1394 | } | ||
1395 | strlcpy(data->client.name, name, I2C_NAME_SIZE); | ||
1396 | |||
1397 | /* Initialize the W83781D chip */ | ||
1398 | w83781d_init_device(&pdev->dev); | ||
1399 | |||
1400 | /* Register sysfs hooks */ | ||
1401 | err = w83781d_create_files(&pdev->dev, data->type, 1); | ||
1402 | if (err) | ||
1403 | goto exit_remove_files; | ||
1404 | |||
1405 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
1406 | if (IS_ERR(data->hwmon_dev)) { | ||
1407 | err = PTR_ERR(data->hwmon_dev); | ||
1408 | goto exit_remove_files; | ||
1409 | } | ||
1410 | |||
1411 | return 0; | ||
1412 | 1235 | ||
1413 | exit_remove_files: | 1236 | sysfs_remove_group(&dev->kobj, &w83781d_group); |
1414 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | 1237 | sysfs_remove_group(&dev->kobj, &w83781d_group_opt); |
1415 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | ||
1416 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
1417 | kfree(data); | ||
1418 | exit_release_region: | ||
1419 | release_region(res->start + W83781D_ADDR_REG_OFFSET, 2); | ||
1420 | exit: | ||
1421 | return err; | ||
1422 | } | ||
1423 | 1238 | ||
1424 | static int __devexit | 1239 | if (data->lm75[0]) |
1425 | w83781d_isa_remove(struct platform_device *pdev) | 1240 | i2c_unregister_device(data->lm75[0]); |
1426 | { | 1241 | if (data->lm75[1]) |
1427 | struct w83781d_data *data = platform_get_drvdata(pdev); | 1242 | i2c_unregister_device(data->lm75[1]); |
1428 | 1243 | ||
1429 | hwmon_device_unregister(data->hwmon_dev); | 1244 | i2c_set_clientdata(client, NULL); |
1430 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | ||
1431 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | ||
1432 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
1433 | release_region(data->client.addr + W83781D_ADDR_REG_OFFSET, 2); | ||
1434 | kfree(data); | 1245 | kfree(data); |
1435 | 1246 | ||
1436 | return 0; | 1247 | return 0; |
1437 | } | 1248 | } |
1438 | 1249 | ||
1439 | /* The SMBus locks itself, usually, but nothing may access the Winbond between | ||
1440 | bank switches. ISA access must always be locked explicitly! | ||
1441 | We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, | ||
1442 | would slow down the W83781D access and should not be necessary. | ||
1443 | There are some ugly typecasts here, but the good news is - they should | ||
1444 | nowhere else be necessary! */ | ||
1445 | static int | 1250 | static int |
1446 | w83781d_read_value(struct w83781d_data *data, u16 reg) | 1251 | w83781d_read_value_i2c(struct w83781d_data *data, u16 reg) |
1447 | { | 1252 | { |
1448 | struct i2c_client *client = &data->client; | 1253 | struct i2c_client *client = data->client; |
1449 | int res, word_sized, bank; | 1254 | int res, bank; |
1450 | struct i2c_client *cl; | 1255 | struct i2c_client *cl; |
1451 | 1256 | ||
1452 | mutex_lock(&data->lock); | 1257 | bank = (reg >> 8) & 0x0f; |
1453 | if (!client->driver) { /* ISA device */ | 1258 | if (bank > 2) |
1454 | word_sized = (((reg & 0xff00) == 0x100) | 1259 | /* switch banks */ |
1455 | || ((reg & 0xff00) == 0x200)) | 1260 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, |
1456 | && (((reg & 0x00ff) == 0x50) | 1261 | bank); |
1457 | || ((reg & 0x00ff) == 0x53) | 1262 | if (bank == 0 || bank > 2) { |
1458 | || ((reg & 0x00ff) == 0x55)); | 1263 | res = i2c_smbus_read_byte_data(client, reg & 0xff); |
1459 | if (reg & 0xff00) { | ||
1460 | outb_p(W83781D_REG_BANK, | ||
1461 | client->addr + W83781D_ADDR_REG_OFFSET); | ||
1462 | outb_p(reg >> 8, | ||
1463 | client->addr + W83781D_DATA_REG_OFFSET); | ||
1464 | } | ||
1465 | outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); | ||
1466 | res = inb_p(client->addr + W83781D_DATA_REG_OFFSET); | ||
1467 | if (word_sized) { | ||
1468 | outb_p((reg & 0xff) + 1, | ||
1469 | client->addr + W83781D_ADDR_REG_OFFSET); | ||
1470 | res = | ||
1471 | (res << 8) + inb_p(client->addr + | ||
1472 | W83781D_DATA_REG_OFFSET); | ||
1473 | } | ||
1474 | if (reg & 0xff00) { | ||
1475 | outb_p(W83781D_REG_BANK, | ||
1476 | client->addr + W83781D_ADDR_REG_OFFSET); | ||
1477 | outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); | ||
1478 | } | ||
1479 | } else { | 1264 | } else { |
1480 | bank = (reg >> 8) & 0x0f; | 1265 | /* switch to subclient */ |
1481 | if (bank > 2) | 1266 | cl = data->lm75[bank - 1]; |
1482 | /* switch banks */ | 1267 | /* convert from ISA to LM75 I2C addresses */ |
1483 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, | 1268 | switch (reg & 0xff) { |
1484 | bank); | 1269 | case 0x50: /* TEMP */ |
1485 | if (bank == 0 || bank > 2) { | 1270 | res = swab16(i2c_smbus_read_word_data(cl, 0)); |
1486 | res = i2c_smbus_read_byte_data(client, reg & 0xff); | 1271 | break; |
1487 | } else { | 1272 | case 0x52: /* CONFIG */ |
1488 | /* switch to subclient */ | 1273 | res = i2c_smbus_read_byte_data(cl, 1); |
1489 | cl = data->lm75[bank - 1]; | 1274 | break; |
1490 | /* convert from ISA to LM75 I2C addresses */ | 1275 | case 0x53: /* HYST */ |
1491 | switch (reg & 0xff) { | 1276 | res = swab16(i2c_smbus_read_word_data(cl, 2)); |
1492 | case 0x50: /* TEMP */ | 1277 | break; |
1493 | res = swab16(i2c_smbus_read_word_data(cl, 0)); | 1278 | case 0x55: /* OVER */ |
1494 | break; | 1279 | default: |
1495 | case 0x52: /* CONFIG */ | 1280 | res = swab16(i2c_smbus_read_word_data(cl, 3)); |
1496 | res = i2c_smbus_read_byte_data(cl, 1); | 1281 | break; |
1497 | break; | ||
1498 | case 0x53: /* HYST */ | ||
1499 | res = swab16(i2c_smbus_read_word_data(cl, 2)); | ||
1500 | break; | ||
1501 | case 0x55: /* OVER */ | ||
1502 | default: | ||
1503 | res = swab16(i2c_smbus_read_word_data(cl, 3)); | ||
1504 | break; | ||
1505 | } | ||
1506 | } | 1282 | } |
1507 | if (bank > 2) | ||
1508 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); | ||
1509 | } | 1283 | } |
1510 | mutex_unlock(&data->lock); | 1284 | if (bank > 2) |
1285 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); | ||
1286 | |||
1511 | return res; | 1287 | return res; |
1512 | } | 1288 | } |
1513 | 1289 | ||
1514 | static int | 1290 | static int |
1515 | w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value) | 1291 | w83781d_write_value_i2c(struct w83781d_data *data, u16 reg, u16 value) |
1516 | { | 1292 | { |
1517 | struct i2c_client *client = &data->client; | 1293 | struct i2c_client *client = data->client; |
1518 | int word_sized, bank; | 1294 | int bank; |
1519 | struct i2c_client *cl; | 1295 | struct i2c_client *cl; |
1520 | 1296 | ||
1521 | mutex_lock(&data->lock); | 1297 | bank = (reg >> 8) & 0x0f; |
1522 | if (!client->driver) { /* ISA device */ | 1298 | if (bank > 2) |
1523 | word_sized = (((reg & 0xff00) == 0x100) | 1299 | /* switch banks */ |
1524 | || ((reg & 0xff00) == 0x200)) | 1300 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, |
1525 | && (((reg & 0x00ff) == 0x53) | 1301 | bank); |
1526 | || ((reg & 0x00ff) == 0x55)); | 1302 | if (bank == 0 || bank > 2) { |
1527 | if (reg & 0xff00) { | 1303 | i2c_smbus_write_byte_data(client, reg & 0xff, |
1528 | outb_p(W83781D_REG_BANK, | 1304 | value & 0xff); |
1529 | client->addr + W83781D_ADDR_REG_OFFSET); | ||
1530 | outb_p(reg >> 8, | ||
1531 | client->addr + W83781D_DATA_REG_OFFSET); | ||
1532 | } | ||
1533 | outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); | ||
1534 | if (word_sized) { | ||
1535 | outb_p(value >> 8, | ||
1536 | client->addr + W83781D_DATA_REG_OFFSET); | ||
1537 | outb_p((reg & 0xff) + 1, | ||
1538 | client->addr + W83781D_ADDR_REG_OFFSET); | ||
1539 | } | ||
1540 | outb_p(value & 0xff, client->addr + W83781D_DATA_REG_OFFSET); | ||
1541 | if (reg & 0xff00) { | ||
1542 | outb_p(W83781D_REG_BANK, | ||
1543 | client->addr + W83781D_ADDR_REG_OFFSET); | ||
1544 | outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); | ||
1545 | } | ||
1546 | } else { | 1305 | } else { |
1547 | bank = (reg >> 8) & 0x0f; | 1306 | /* switch to subclient */ |
1548 | if (bank > 2) | 1307 | cl = data->lm75[bank - 1]; |
1549 | /* switch banks */ | 1308 | /* convert from ISA to LM75 I2C addresses */ |
1550 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, | 1309 | switch (reg & 0xff) { |
1551 | bank); | 1310 | case 0x52: /* CONFIG */ |
1552 | if (bank == 0 || bank > 2) { | 1311 | i2c_smbus_write_byte_data(cl, 1, value & 0xff); |
1553 | i2c_smbus_write_byte_data(client, reg & 0xff, | 1312 | break; |
1554 | value & 0xff); | 1313 | case 0x53: /* HYST */ |
1555 | } else { | 1314 | i2c_smbus_write_word_data(cl, 2, swab16(value)); |
1556 | /* switch to subclient */ | 1315 | break; |
1557 | cl = data->lm75[bank - 1]; | 1316 | case 0x55: /* OVER */ |
1558 | /* convert from ISA to LM75 I2C addresses */ | 1317 | i2c_smbus_write_word_data(cl, 3, swab16(value)); |
1559 | switch (reg & 0xff) { | 1318 | break; |
1560 | case 0x52: /* CONFIG */ | ||
1561 | i2c_smbus_write_byte_data(cl, 1, value & 0xff); | ||
1562 | break; | ||
1563 | case 0x53: /* HYST */ | ||
1564 | i2c_smbus_write_word_data(cl, 2, swab16(value)); | ||
1565 | break; | ||
1566 | case 0x55: /* OVER */ | ||
1567 | i2c_smbus_write_word_data(cl, 3, swab16(value)); | ||
1568 | break; | ||
1569 | } | ||
1570 | } | 1319 | } |
1571 | if (bank > 2) | ||
1572 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); | ||
1573 | } | 1320 | } |
1574 | mutex_unlock(&data->lock); | 1321 | if (bank > 2) |
1322 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); | ||
1323 | |||
1575 | return 0; | 1324 | return 0; |
1576 | } | 1325 | } |
1577 | 1326 | ||
@@ -1678,7 +1427,7 @@ w83781d_init_device(struct device *dev) | |||
1678 | static struct w83781d_data *w83781d_update_device(struct device *dev) | 1427 | static struct w83781d_data *w83781d_update_device(struct device *dev) |
1679 | { | 1428 | { |
1680 | struct w83781d_data *data = dev_get_drvdata(dev); | 1429 | struct w83781d_data *data = dev_get_drvdata(dev); |
1681 | struct i2c_client *client = &data->client; | 1430 | struct i2c_client *client = data->client; |
1682 | int i; | 1431 | int i; |
1683 | 1432 | ||
1684 | mutex_lock(&data->update_lock); | 1433 | mutex_lock(&data->update_lock); |
@@ -1775,8 +1524,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1775 | W83781D_REG_ALARM2) << 8); | 1524 | W83781D_REG_ALARM2) << 8); |
1776 | } | 1525 | } |
1777 | i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2); | 1526 | i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2); |
1778 | data->beep_enable = i >> 7; | 1527 | data->beep_mask = (i << 8) + |
1779 | data->beep_mask = ((i & 0x7f) << 8) + | ||
1780 | w83781d_read_value(data, W83781D_REG_BEEP_INTS1); | 1528 | w83781d_read_value(data, W83781D_REG_BEEP_INTS1); |
1781 | if ((data->type != w83781d) && (data->type != as99127f)) { | 1529 | if ((data->type != w83781d) && (data->type != as99127f)) { |
1782 | data->beep_mask |= | 1530 | data->beep_mask |= |
@@ -1792,6 +1540,275 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1792 | return data; | 1540 | return data; |
1793 | } | 1541 | } |
1794 | 1542 | ||
1543 | static const struct i2c_device_id w83781d_ids[] = { | ||
1544 | { "w83781d", w83781d, }, | ||
1545 | { "w83782d", w83782d, }, | ||
1546 | { "w83783s", w83783s, }, | ||
1547 | { "as99127f", as99127f }, | ||
1548 | { /* LIST END */ } | ||
1549 | }; | ||
1550 | MODULE_DEVICE_TABLE(i2c, w83781d_ids); | ||
1551 | |||
1552 | static struct i2c_driver w83781d_driver = { | ||
1553 | .class = I2C_CLASS_HWMON, | ||
1554 | .driver = { | ||
1555 | .name = "w83781d", | ||
1556 | }, | ||
1557 | .probe = w83781d_probe, | ||
1558 | .remove = w83781d_remove, | ||
1559 | .id_table = w83781d_ids, | ||
1560 | .detect = w83781d_detect, | ||
1561 | .address_data = &addr_data, | ||
1562 | }; | ||
1563 | |||
1564 | /* | ||
1565 | * ISA related code | ||
1566 | */ | ||
1567 | #ifdef CONFIG_ISA | ||
1568 | |||
1569 | /* ISA device, if found */ | ||
1570 | static struct platform_device *pdev; | ||
1571 | |||
1572 | static unsigned short isa_address = 0x290; | ||
1573 | |||
1574 | /* I2C devices get this name attribute automatically, but for ISA devices | ||
1575 | we must create it by ourselves. */ | ||
1576 | static ssize_t | ||
1577 | show_name(struct device *dev, struct device_attribute *devattr, char *buf) | ||
1578 | { | ||
1579 | struct w83781d_data *data = dev_get_drvdata(dev); | ||
1580 | return sprintf(buf, "%s\n", data->name); | ||
1581 | } | ||
1582 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
1583 | |||
1584 | static struct w83781d_data *w83781d_data_if_isa(void) | ||
1585 | { | ||
1586 | return pdev ? platform_get_drvdata(pdev) : NULL; | ||
1587 | } | ||
1588 | |||
1589 | /* Returns 1 if the I2C chip appears to be an alias of the ISA chip */ | ||
1590 | static int w83781d_alias_detect(struct i2c_client *client, u8 chipid) | ||
1591 | { | ||
1592 | struct w83781d_data *isa; | ||
1593 | int i; | ||
1594 | |||
1595 | if (!pdev) /* No ISA chip */ | ||
1596 | return 0; | ||
1597 | |||
1598 | isa = platform_get_drvdata(pdev); | ||
1599 | |||
1600 | if (w83781d_read_value(isa, W83781D_REG_I2C_ADDR) != client->addr) | ||
1601 | return 0; /* Address doesn't match */ | ||
1602 | if (w83781d_read_value(isa, W83781D_REG_WCHIPID) != chipid) | ||
1603 | return 0; /* Chip type doesn't match */ | ||
1604 | |||
1605 | /* We compare all the limit registers, the config register and the | ||
1606 | * interrupt mask registers */ | ||
1607 | for (i = 0x2b; i <= 0x3d; i++) { | ||
1608 | if (w83781d_read_value(isa, i) != | ||
1609 | i2c_smbus_read_byte_data(client, i)) | ||
1610 | return 0; | ||
1611 | } | ||
1612 | if (w83781d_read_value(isa, W83781D_REG_CONFIG) != | ||
1613 | i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG)) | ||
1614 | return 0; | ||
1615 | for (i = 0x43; i <= 0x46; i++) { | ||
1616 | if (w83781d_read_value(isa, i) != | ||
1617 | i2c_smbus_read_byte_data(client, i)) | ||
1618 | return 0; | ||
1619 | } | ||
1620 | |||
1621 | return 1; | ||
1622 | } | ||
1623 | |||
1624 | static int | ||
1625 | w83781d_read_value_isa(struct w83781d_data *data, u16 reg) | ||
1626 | { | ||
1627 | int word_sized, res; | ||
1628 | |||
1629 | word_sized = (((reg & 0xff00) == 0x100) | ||
1630 | || ((reg & 0xff00) == 0x200)) | ||
1631 | && (((reg & 0x00ff) == 0x50) | ||
1632 | || ((reg & 0x00ff) == 0x53) | ||
1633 | || ((reg & 0x00ff) == 0x55)); | ||
1634 | if (reg & 0xff00) { | ||
1635 | outb_p(W83781D_REG_BANK, | ||
1636 | data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1637 | outb_p(reg >> 8, | ||
1638 | data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1639 | } | ||
1640 | outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1641 | res = inb_p(data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1642 | if (word_sized) { | ||
1643 | outb_p((reg & 0xff) + 1, | ||
1644 | data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1645 | res = | ||
1646 | (res << 8) + inb_p(data->isa_addr + | ||
1647 | W83781D_DATA_REG_OFFSET); | ||
1648 | } | ||
1649 | if (reg & 0xff00) { | ||
1650 | outb_p(W83781D_REG_BANK, | ||
1651 | data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1652 | outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1653 | } | ||
1654 | return res; | ||
1655 | } | ||
1656 | |||
1657 | static void | ||
1658 | w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value) | ||
1659 | { | ||
1660 | int word_sized; | ||
1661 | |||
1662 | word_sized = (((reg & 0xff00) == 0x100) | ||
1663 | || ((reg & 0xff00) == 0x200)) | ||
1664 | && (((reg & 0x00ff) == 0x53) | ||
1665 | || ((reg & 0x00ff) == 0x55)); | ||
1666 | if (reg & 0xff00) { | ||
1667 | outb_p(W83781D_REG_BANK, | ||
1668 | data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1669 | outb_p(reg >> 8, | ||
1670 | data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1671 | } | ||
1672 | outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1673 | if (word_sized) { | ||
1674 | outb_p(value >> 8, | ||
1675 | data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1676 | outb_p((reg & 0xff) + 1, | ||
1677 | data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1678 | } | ||
1679 | outb_p(value & 0xff, data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1680 | if (reg & 0xff00) { | ||
1681 | outb_p(W83781D_REG_BANK, | ||
1682 | data->isa_addr + W83781D_ADDR_REG_OFFSET); | ||
1683 | outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | /* The SMBus locks itself, usually, but nothing may access the Winbond between | ||
1688 | bank switches. ISA access must always be locked explicitly! | ||
1689 | We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, | ||
1690 | would slow down the W83781D access and should not be necessary. | ||
1691 | There are some ugly typecasts here, but the good news is - they should | ||
1692 | nowhere else be necessary! */ | ||
1693 | static int | ||
1694 | w83781d_read_value(struct w83781d_data *data, u16 reg) | ||
1695 | { | ||
1696 | struct i2c_client *client = data->client; | ||
1697 | int res; | ||
1698 | |||
1699 | mutex_lock(&data->lock); | ||
1700 | if (client) | ||
1701 | res = w83781d_read_value_i2c(data, reg); | ||
1702 | else | ||
1703 | res = w83781d_read_value_isa(data, reg); | ||
1704 | mutex_unlock(&data->lock); | ||
1705 | return res; | ||
1706 | } | ||
1707 | |||
1708 | static int | ||
1709 | w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value) | ||
1710 | { | ||
1711 | struct i2c_client *client = data->client; | ||
1712 | |||
1713 | mutex_lock(&data->lock); | ||
1714 | if (client) | ||
1715 | w83781d_write_value_i2c(data, reg, value); | ||
1716 | else | ||
1717 | w83781d_write_value_isa(data, reg, value); | ||
1718 | mutex_unlock(&data->lock); | ||
1719 | return 0; | ||
1720 | } | ||
1721 | |||
1722 | static int __devinit | ||
1723 | w83781d_isa_probe(struct platform_device *pdev) | ||
1724 | { | ||
1725 | int err, reg; | ||
1726 | struct w83781d_data *data; | ||
1727 | struct resource *res; | ||
1728 | |||
1729 | /* Reserve the ISA region */ | ||
1730 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
1731 | if (!request_region(res->start + W83781D_ADDR_REG_OFFSET, 2, | ||
1732 | "w83781d")) { | ||
1733 | err = -EBUSY; | ||
1734 | goto exit; | ||
1735 | } | ||
1736 | |||
1737 | data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL); | ||
1738 | if (!data) { | ||
1739 | err = -ENOMEM; | ||
1740 | goto exit_release_region; | ||
1741 | } | ||
1742 | mutex_init(&data->lock); | ||
1743 | data->isa_addr = res->start; | ||
1744 | platform_set_drvdata(pdev, data); | ||
1745 | |||
1746 | reg = w83781d_read_value(data, W83781D_REG_WCHIPID); | ||
1747 | switch (reg) { | ||
1748 | case 0x30: | ||
1749 | data->type = w83782d; | ||
1750 | data->name = "w83782d"; | ||
1751 | break; | ||
1752 | default: | ||
1753 | data->type = w83781d; | ||
1754 | data->name = "w83781d"; | ||
1755 | } | ||
1756 | |||
1757 | /* Initialize the W83781D chip */ | ||
1758 | w83781d_init_device(&pdev->dev); | ||
1759 | |||
1760 | /* Register sysfs hooks */ | ||
1761 | err = w83781d_create_files(&pdev->dev, data->type, 1); | ||
1762 | if (err) | ||
1763 | goto exit_remove_files; | ||
1764 | |||
1765 | err = device_create_file(&pdev->dev, &dev_attr_name); | ||
1766 | if (err) | ||
1767 | goto exit_remove_files; | ||
1768 | |||
1769 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
1770 | if (IS_ERR(data->hwmon_dev)) { | ||
1771 | err = PTR_ERR(data->hwmon_dev); | ||
1772 | goto exit_remove_files; | ||
1773 | } | ||
1774 | |||
1775 | return 0; | ||
1776 | |||
1777 | exit_remove_files: | ||
1778 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | ||
1779 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | ||
1780 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
1781 | kfree(data); | ||
1782 | exit_release_region: | ||
1783 | release_region(res->start + W83781D_ADDR_REG_OFFSET, 2); | ||
1784 | exit: | ||
1785 | return err; | ||
1786 | } | ||
1787 | |||
1788 | static int __devexit | ||
1789 | w83781d_isa_remove(struct platform_device *pdev) | ||
1790 | { | ||
1791 | struct w83781d_data *data = platform_get_drvdata(pdev); | ||
1792 | |||
1793 | hwmon_device_unregister(data->hwmon_dev); | ||
1794 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | ||
1795 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | ||
1796 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
1797 | release_region(data->isa_addr + W83781D_ADDR_REG_OFFSET, 2); | ||
1798 | kfree(data); | ||
1799 | |||
1800 | return 0; | ||
1801 | } | ||
1802 | |||
1803 | static struct platform_driver w83781d_isa_driver = { | ||
1804 | .driver = { | ||
1805 | .owner = THIS_MODULE, | ||
1806 | .name = "w83781d", | ||
1807 | }, | ||
1808 | .probe = w83781d_isa_probe, | ||
1809 | .remove = __devexit_p(w83781d_isa_remove), | ||
1810 | }; | ||
1811 | |||
1795 | /* return 1 if a supported chip is found, 0 otherwise */ | 1812 | /* return 1 if a supported chip is found, 0 otherwise */ |
1796 | static int __init | 1813 | static int __init |
1797 | w83781d_isa_found(unsigned short address) | 1814 | w83781d_isa_found(unsigned short address) |
@@ -1928,18 +1945,14 @@ w83781d_isa_device_add(unsigned short address) | |||
1928 | } | 1945 | } |
1929 | 1946 | ||
1930 | static int __init | 1947 | static int __init |
1931 | sensors_w83781d_init(void) | 1948 | w83781d_isa_register(void) |
1932 | { | 1949 | { |
1933 | int res; | 1950 | int res; |
1934 | 1951 | ||
1935 | res = i2c_add_driver(&w83781d_driver); | ||
1936 | if (res) | ||
1937 | goto exit; | ||
1938 | |||
1939 | if (w83781d_isa_found(isa_address)) { | 1952 | if (w83781d_isa_found(isa_address)) { |
1940 | res = platform_driver_register(&w83781d_isa_driver); | 1953 | res = platform_driver_register(&w83781d_isa_driver); |
1941 | if (res) | 1954 | if (res) |
1942 | goto exit_unreg_i2c_driver; | 1955 | goto exit; |
1943 | 1956 | ||
1944 | /* Sets global pdev as a side effect */ | 1957 | /* Sets global pdev as a side effect */ |
1945 | res = w83781d_isa_device_add(isa_address); | 1958 | res = w83781d_isa_device_add(isa_address); |
@@ -1949,21 +1962,94 @@ sensors_w83781d_init(void) | |||
1949 | 1962 | ||
1950 | return 0; | 1963 | return 0; |
1951 | 1964 | ||
1952 | exit_unreg_isa_driver: | 1965 | exit_unreg_isa_driver: |
1953 | platform_driver_unregister(&w83781d_isa_driver); | 1966 | platform_driver_unregister(&w83781d_isa_driver); |
1954 | exit_unreg_i2c_driver: | 1967 | exit: |
1955 | i2c_del_driver(&w83781d_driver); | ||
1956 | exit: | ||
1957 | return res; | 1968 | return res; |
1958 | } | 1969 | } |
1959 | 1970 | ||
1960 | static void __exit | 1971 | static void |
1961 | sensors_w83781d_exit(void) | 1972 | w83781d_isa_unregister(void) |
1962 | { | 1973 | { |
1963 | if (pdev) { | 1974 | if (pdev) { |
1964 | platform_device_unregister(pdev); | 1975 | platform_device_unregister(pdev); |
1965 | platform_driver_unregister(&w83781d_isa_driver); | 1976 | platform_driver_unregister(&w83781d_isa_driver); |
1966 | } | 1977 | } |
1978 | } | ||
1979 | #else /* !CONFIG_ISA */ | ||
1980 | |||
1981 | static struct w83781d_data *w83781d_data_if_isa(void) | ||
1982 | { | ||
1983 | return NULL; | ||
1984 | } | ||
1985 | |||
1986 | static int | ||
1987 | w83781d_alias_detect(struct i2c_client *client, u8 chipid) | ||
1988 | { | ||
1989 | return 0; | ||
1990 | } | ||
1991 | |||
1992 | static int | ||
1993 | w83781d_read_value(struct w83781d_data *data, u16 reg) | ||
1994 | { | ||
1995 | int res; | ||
1996 | |||
1997 | mutex_lock(&data->lock); | ||
1998 | res = w83781d_read_value_i2c(data, reg); | ||
1999 | mutex_unlock(&data->lock); | ||
2000 | |||
2001 | return res; | ||
2002 | } | ||
2003 | |||
2004 | static int | ||
2005 | w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value) | ||
2006 | { | ||
2007 | mutex_lock(&data->lock); | ||
2008 | w83781d_write_value_i2c(data, reg, value); | ||
2009 | mutex_unlock(&data->lock); | ||
2010 | |||
2011 | return 0; | ||
2012 | } | ||
2013 | |||
2014 | static int __init | ||
2015 | w83781d_isa_register(void) | ||
2016 | { | ||
2017 | return 0; | ||
2018 | } | ||
2019 | |||
2020 | static void | ||
2021 | w83781d_isa_unregister(void) | ||
2022 | { | ||
2023 | } | ||
2024 | #endif /* CONFIG_ISA */ | ||
2025 | |||
2026 | static int __init | ||
2027 | sensors_w83781d_init(void) | ||
2028 | { | ||
2029 | int res; | ||
2030 | |||
2031 | /* We register the ISA device first, so that we can skip the | ||
2032 | * registration of an I2C interface to the same device. */ | ||
2033 | res = w83781d_isa_register(); | ||
2034 | if (res) | ||
2035 | goto exit; | ||
2036 | |||
2037 | res = i2c_add_driver(&w83781d_driver); | ||
2038 | if (res) | ||
2039 | goto exit_unreg_isa; | ||
2040 | |||
2041 | return 0; | ||
2042 | |||
2043 | exit_unreg_isa: | ||
2044 | w83781d_isa_unregister(); | ||
2045 | exit: | ||
2046 | return res; | ||
2047 | } | ||
2048 | |||
2049 | static void __exit | ||
2050 | sensors_w83781d_exit(void) | ||
2051 | { | ||
2052 | w83781d_isa_unregister(); | ||
1967 | i2c_del_driver(&w83781d_driver); | 2053 | i2c_del_driver(&w83781d_driver); |
1968 | } | 2054 | } |
1969 | 2055 | ||
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index e4e91c9d480a..5768def8a4f2 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -23,7 +23,7 @@ | |||
23 | Supports following chips: | 23 | Supports following chips: |
24 | 24 | ||
25 | Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 25 | Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
26 | w83791d 10 5 3 3 0x71 0x5ca3 yes no | 26 | w83791d 10 5 5 3 0x71 0x5ca3 yes no |
27 | 27 | ||
28 | The w83791d chip appears to be part way between the 83781d and the | 28 | The w83791d chip appears to be part way between the 83781d and the |
29 | 83792d. Thus, this file is derived from both the w83792d.c and | 29 | 83792d. Thus, this file is derived from both the w83792d.c and |
@@ -45,6 +45,7 @@ | |||
45 | #define NUMBER_OF_VIN 10 | 45 | #define NUMBER_OF_VIN 10 |
46 | #define NUMBER_OF_FANIN 5 | 46 | #define NUMBER_OF_FANIN 5 |
47 | #define NUMBER_OF_TEMPIN 3 | 47 | #define NUMBER_OF_TEMPIN 3 |
48 | #define NUMBER_OF_PWM 5 | ||
48 | 49 | ||
49 | /* Addresses to scan */ | 50 | /* Addresses to scan */ |
50 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | 51 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, |
@@ -116,6 +117,25 @@ static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = { | |||
116 | 0xBD, /* FAN 5 Count Low Limit in DataSheet */ | 117 | 0xBD, /* FAN 5 Count Low Limit in DataSheet */ |
117 | }; | 118 | }; |
118 | 119 | ||
120 | static const u8 W83791D_REG_PWM[NUMBER_OF_PWM] = { | ||
121 | 0x81, /* PWM 1 duty cycle register in DataSheet */ | ||
122 | 0x83, /* PWM 2 duty cycle register in DataSheet */ | ||
123 | 0x94, /* PWM 3 duty cycle register in DataSheet */ | ||
124 | 0xA0, /* PWM 4 duty cycle register in DataSheet */ | ||
125 | 0xA1, /* PWM 5 duty cycle register in DataSheet */ | ||
126 | }; | ||
127 | |||
128 | static const u8 W83791D_REG_TEMP_TARGET[3] = { | ||
129 | 0x85, /* PWM 1 target temperature for temp 1 */ | ||
130 | 0x86, /* PWM 2 target temperature for temp 2 */ | ||
131 | 0x96, /* PWM 3 target temperature for temp 3 */ | ||
132 | }; | ||
133 | |||
134 | static const u8 W83791D_REG_TEMP_TOL[2] = { | ||
135 | 0x87, /* PWM 1/2 temperature tolerance */ | ||
136 | 0x97, /* PWM 3 temperature tolerance */ | ||
137 | }; | ||
138 | |||
119 | static const u8 W83791D_REG_FAN_CFG[2] = { | 139 | static const u8 W83791D_REG_FAN_CFG[2] = { |
120 | 0x84, /* FAN 1/2 configuration */ | 140 | 0x84, /* FAN 1/2 configuration */ |
121 | 0x95, /* FAN 3 configuration */ | 141 | 0x95, /* FAN 3 configuration */ |
@@ -160,6 +180,7 @@ static const u8 W83791D_REG_BEEP_CTRL[3] = { | |||
160 | 0xA3, /* BEEP Control Register 3 */ | 180 | 0xA3, /* BEEP Control Register 3 */ |
161 | }; | 181 | }; |
162 | 182 | ||
183 | #define W83791D_REG_GPIO 0x15 | ||
163 | #define W83791D_REG_CONFIG 0x40 | 184 | #define W83791D_REG_CONFIG 0x40 |
164 | #define W83791D_REG_VID_FANDIV 0x47 | 185 | #define W83791D_REG_VID_FANDIV 0x47 |
165 | #define W83791D_REG_DID_VID4 0x49 | 186 | #define W83791D_REG_DID_VID4 0x49 |
@@ -224,6 +245,15 @@ static u8 fan_to_reg(long rpm, int div) | |||
224 | (val) < 0 ? ((val) - 250) / 500 * 128 : \ | 245 | (val) < 0 ? ((val) - 250) / 500 * 128 : \ |
225 | ((val) + 250) / 500 * 128) | 246 | ((val) + 250) / 500 * 128) |
226 | 247 | ||
248 | /* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */ | ||
249 | #define TARGET_TEMP_TO_REG(val) ((val) < 0 ? 0 : \ | ||
250 | (val) >= 127000 ? 127 : \ | ||
251 | ((val) + 500) / 1000) | ||
252 | |||
253 | /* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */ | ||
254 | #define TOL_TEMP_TO_REG(val) ((val) < 0 ? 0 : \ | ||
255 | (val) >= 15000 ? 15 : \ | ||
256 | ((val) + 500) / 1000) | ||
227 | 257 | ||
228 | #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) | 258 | #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) |
229 | #define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff) | 259 | #define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff) |
@@ -233,11 +263,9 @@ static u8 fan_to_reg(long rpm, int div) | |||
233 | static u8 div_to_reg(int nr, long val) | 263 | static u8 div_to_reg(int nr, long val) |
234 | { | 264 | { |
235 | int i; | 265 | int i; |
236 | int max; | ||
237 | 266 | ||
238 | /* first three fan's divisor max out at 8, rest max out at 128 */ | 267 | /* fan divisors max out at 128 */ |
239 | max = (nr < 3) ? 8 : 128; | 268 | val = SENSORS_LIMIT(val, 1, 128) >> 1; |
240 | val = SENSORS_LIMIT(val, 1, max) >> 1; | ||
241 | for (i = 0; i < 7; i++) { | 269 | for (i = 0; i < 7; i++) { |
242 | if (val == 0) | 270 | if (val == 0) |
243 | break; | 271 | break; |
@@ -277,6 +305,14 @@ struct w83791d_data { | |||
277 | two sensors with three values | 305 | two sensors with three values |
278 | (cur, over, hyst) */ | 306 | (cur, over, hyst) */ |
279 | 307 | ||
308 | /* PWMs */ | ||
309 | u8 pwm[5]; /* pwm duty cycle */ | ||
310 | u8 pwm_enable[3]; /* pwm enable status for fan 1-3 | ||
311 | (fan 4-5 only support manual mode) */ | ||
312 | |||
313 | u8 temp_target[3]; /* pwm 1-3 target temperature */ | ||
314 | u8 temp_tolerance[3]; /* pwm 1-3 temperature tolerance */ | ||
315 | |||
280 | /* Misc */ | 316 | /* Misc */ |
281 | u32 alarms; /* realtime status register encoding,combined */ | 317 | u32 alarms; /* realtime status register encoding,combined */ |
282 | u8 beep_enable; /* Global beep enable */ | 318 | u8 beep_enable; /* Global beep enable */ |
@@ -530,6 +566,7 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, | |||
530 | unsigned long min; | 566 | unsigned long min; |
531 | u8 tmp_fan_div; | 567 | u8 tmp_fan_div; |
532 | u8 fan_div_reg; | 568 | u8 fan_div_reg; |
569 | u8 vbat_reg; | ||
533 | int indx = 0; | 570 | int indx = 0; |
534 | u8 keep_mask = 0; | 571 | u8 keep_mask = 0; |
535 | u8 new_shift = 0; | 572 | u8 new_shift = 0; |
@@ -581,6 +618,16 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, | |||
581 | w83791d_write(client, W83791D_REG_FAN_DIV[indx], | 618 | w83791d_write(client, W83791D_REG_FAN_DIV[indx], |
582 | fan_div_reg | tmp_fan_div); | 619 | fan_div_reg | tmp_fan_div); |
583 | 620 | ||
621 | /* Bit 2 of fans 0-2 is stored in the vbat register (bits 5-7) */ | ||
622 | if (nr < 3) { | ||
623 | keep_mask = ~(1 << (nr + 5)); | ||
624 | vbat_reg = w83791d_read(client, W83791D_REG_VBAT) | ||
625 | & keep_mask; | ||
626 | tmp_fan_div = (data->fan_div[nr] << (3 + nr)) & ~keep_mask; | ||
627 | w83791d_write(client, W83791D_REG_VBAT, | ||
628 | vbat_reg | tmp_fan_div); | ||
629 | } | ||
630 | |||
584 | /* Restore fan_min */ | 631 | /* Restore fan_min */ |
585 | data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); | 632 | data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); |
586 | w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); | 633 | w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); |
@@ -643,6 +690,217 @@ static struct sensor_device_attribute sda_fan_alarm[] = { | |||
643 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22), | 690 | SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22), |
644 | }; | 691 | }; |
645 | 692 | ||
693 | /* read/write PWMs */ | ||
694 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | ||
695 | char *buf) | ||
696 | { | ||
697 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
698 | int nr = sensor_attr->index; | ||
699 | struct w83791d_data *data = w83791d_update_device(dev); | ||
700 | return sprintf(buf, "%u\n", data->pwm[nr]); | ||
701 | } | ||
702 | |||
703 | static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, | ||
704 | const char *buf, size_t count) | ||
705 | { | ||
706 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
707 | struct i2c_client *client = to_i2c_client(dev); | ||
708 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
709 | int nr = sensor_attr->index; | ||
710 | unsigned long val; | ||
711 | |||
712 | if (strict_strtoul(buf, 10, &val)) | ||
713 | return -EINVAL; | ||
714 | |||
715 | mutex_lock(&data->update_lock); | ||
716 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); | ||
717 | w83791d_write(client, W83791D_REG_PWM[nr], data->pwm[nr]); | ||
718 | mutex_unlock(&data->update_lock); | ||
719 | return count; | ||
720 | } | ||
721 | |||
722 | static struct sensor_device_attribute sda_pwm[] = { | ||
723 | SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, | ||
724 | show_pwm, store_pwm, 0), | ||
725 | SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, | ||
726 | show_pwm, store_pwm, 1), | ||
727 | SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, | ||
728 | show_pwm, store_pwm, 2), | ||
729 | SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, | ||
730 | show_pwm, store_pwm, 3), | ||
731 | SENSOR_ATTR(pwm5, S_IWUSR | S_IRUGO, | ||
732 | show_pwm, store_pwm, 4), | ||
733 | }; | ||
734 | |||
735 | static ssize_t show_pwmenable(struct device *dev, struct device_attribute *attr, | ||
736 | char *buf) | ||
737 | { | ||
738 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
739 | int nr = sensor_attr->index; | ||
740 | struct w83791d_data *data = w83791d_update_device(dev); | ||
741 | return sprintf(buf, "%u\n", data->pwm_enable[nr] + 1); | ||
742 | } | ||
743 | |||
744 | static ssize_t store_pwmenable(struct device *dev, | ||
745 | struct device_attribute *attr, const char *buf, size_t count) | ||
746 | { | ||
747 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
748 | struct i2c_client *client = to_i2c_client(dev); | ||
749 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
750 | int nr = sensor_attr->index; | ||
751 | unsigned long val; | ||
752 | u8 reg_cfg_tmp; | ||
753 | u8 reg_idx = 0; | ||
754 | u8 val_shift = 0; | ||
755 | u8 keep_mask = 0; | ||
756 | |||
757 | int ret = strict_strtoul(buf, 10, &val); | ||
758 | |||
759 | if (ret || val < 1 || val > 3) | ||
760 | return -EINVAL; | ||
761 | |||
762 | mutex_lock(&data->update_lock); | ||
763 | data->pwm_enable[nr] = val - 1; | ||
764 | switch (nr) { | ||
765 | case 0: | ||
766 | reg_idx = 0; | ||
767 | val_shift = 2; | ||
768 | keep_mask = 0xf3; | ||
769 | break; | ||
770 | case 1: | ||
771 | reg_idx = 0; | ||
772 | val_shift = 4; | ||
773 | keep_mask = 0xcf; | ||
774 | break; | ||
775 | case 2: | ||
776 | reg_idx = 1; | ||
777 | val_shift = 2; | ||
778 | keep_mask = 0xf3; | ||
779 | break; | ||
780 | } | ||
781 | |||
782 | reg_cfg_tmp = w83791d_read(client, W83791D_REG_FAN_CFG[reg_idx]); | ||
783 | reg_cfg_tmp = (reg_cfg_tmp & keep_mask) | | ||
784 | data->pwm_enable[nr] << val_shift; | ||
785 | |||
786 | w83791d_write(client, W83791D_REG_FAN_CFG[reg_idx], reg_cfg_tmp); | ||
787 | mutex_unlock(&data->update_lock); | ||
788 | |||
789 | return count; | ||
790 | } | ||
791 | static struct sensor_device_attribute sda_pwmenable[] = { | ||
792 | SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
793 | show_pwmenable, store_pwmenable, 0), | ||
794 | SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, | ||
795 | show_pwmenable, store_pwmenable, 1), | ||
796 | SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, | ||
797 | show_pwmenable, store_pwmenable, 2), | ||
798 | }; | ||
799 | |||
800 | /* For Smart Fan I / Thermal Cruise */ | ||
801 | static ssize_t show_temp_target(struct device *dev, | ||
802 | struct device_attribute *attr, char *buf) | ||
803 | { | ||
804 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
805 | struct w83791d_data *data = w83791d_update_device(dev); | ||
806 | int nr = sensor_attr->index; | ||
807 | return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp_target[nr])); | ||
808 | } | ||
809 | |||
810 | static ssize_t store_temp_target(struct device *dev, | ||
811 | struct device_attribute *attr, const char *buf, size_t count) | ||
812 | { | ||
813 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
814 | struct i2c_client *client = to_i2c_client(dev); | ||
815 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
816 | int nr = sensor_attr->index; | ||
817 | unsigned long val; | ||
818 | u8 target_mask; | ||
819 | |||
820 | if (strict_strtoul(buf, 10, &val)) | ||
821 | return -EINVAL; | ||
822 | |||
823 | mutex_lock(&data->update_lock); | ||
824 | data->temp_target[nr] = TARGET_TEMP_TO_REG(val); | ||
825 | target_mask = w83791d_read(client, | ||
826 | W83791D_REG_TEMP_TARGET[nr]) & 0x80; | ||
827 | w83791d_write(client, W83791D_REG_TEMP_TARGET[nr], | ||
828 | data->temp_target[nr] | target_mask); | ||
829 | mutex_unlock(&data->update_lock); | ||
830 | return count; | ||
831 | } | ||
832 | |||
833 | static struct sensor_device_attribute sda_temp_target[] = { | ||
834 | SENSOR_ATTR(temp1_target, S_IWUSR | S_IRUGO, | ||
835 | show_temp_target, store_temp_target, 0), | ||
836 | SENSOR_ATTR(temp2_target, S_IWUSR | S_IRUGO, | ||
837 | show_temp_target, store_temp_target, 1), | ||
838 | SENSOR_ATTR(temp3_target, S_IWUSR | S_IRUGO, | ||
839 | show_temp_target, store_temp_target, 2), | ||
840 | }; | ||
841 | |||
842 | static ssize_t show_temp_tolerance(struct device *dev, | ||
843 | struct device_attribute *attr, char *buf) | ||
844 | { | ||
845 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
846 | struct w83791d_data *data = w83791d_update_device(dev); | ||
847 | int nr = sensor_attr->index; | ||
848 | return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp_tolerance[nr])); | ||
849 | } | ||
850 | |||
851 | static ssize_t store_temp_tolerance(struct device *dev, | ||
852 | struct device_attribute *attr, const char *buf, size_t count) | ||
853 | { | ||
854 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
855 | struct i2c_client *client = to_i2c_client(dev); | ||
856 | struct w83791d_data *data = i2c_get_clientdata(client); | ||
857 | int nr = sensor_attr->index; | ||
858 | unsigned long val; | ||
859 | u8 target_mask; | ||
860 | u8 reg_idx = 0; | ||
861 | u8 val_shift = 0; | ||
862 | u8 keep_mask = 0; | ||
863 | |||
864 | if (strict_strtoul(buf, 10, &val)) | ||
865 | return -EINVAL; | ||
866 | |||
867 | switch (nr) { | ||
868 | case 0: | ||
869 | reg_idx = 0; | ||
870 | val_shift = 0; | ||
871 | keep_mask = 0xf0; | ||
872 | break; | ||
873 | case 1: | ||
874 | reg_idx = 0; | ||
875 | val_shift = 4; | ||
876 | keep_mask = 0x0f; | ||
877 | break; | ||
878 | case 2: | ||
879 | reg_idx = 1; | ||
880 | val_shift = 0; | ||
881 | keep_mask = 0xf0; | ||
882 | break; | ||
883 | } | ||
884 | |||
885 | mutex_lock(&data->update_lock); | ||
886 | data->temp_tolerance[nr] = TOL_TEMP_TO_REG(val); | ||
887 | target_mask = w83791d_read(client, | ||
888 | W83791D_REG_TEMP_TOL[reg_idx]) & keep_mask; | ||
889 | w83791d_write(client, W83791D_REG_TEMP_TOL[reg_idx], | ||
890 | (data->temp_tolerance[nr] << val_shift) | target_mask); | ||
891 | mutex_unlock(&data->update_lock); | ||
892 | return count; | ||
893 | } | ||
894 | |||
895 | static struct sensor_device_attribute sda_temp_tolerance[] = { | ||
896 | SENSOR_ATTR(temp1_tolerance, S_IWUSR | S_IRUGO, | ||
897 | show_temp_tolerance, store_temp_tolerance, 0), | ||
898 | SENSOR_ATTR(temp2_tolerance, S_IWUSR | S_IRUGO, | ||
899 | show_temp_tolerance, store_temp_tolerance, 1), | ||
900 | SENSOR_ATTR(temp3_tolerance, S_IWUSR | S_IRUGO, | ||
901 | show_temp_tolerance, store_temp_tolerance, 2), | ||
902 | }; | ||
903 | |||
646 | /* read/write the temperature1, includes measured value and limits */ | 904 | /* read/write the temperature1, includes measured value and limits */ |
647 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, | 905 | static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, |
648 | char *buf) | 906 | char *buf) |
@@ -899,8 +1157,6 @@ static struct attribute *w83791d_attributes[] = { | |||
899 | FAN_UNIT_ATTRS(0), | 1157 | FAN_UNIT_ATTRS(0), |
900 | FAN_UNIT_ATTRS(1), | 1158 | FAN_UNIT_ATTRS(1), |
901 | FAN_UNIT_ATTRS(2), | 1159 | FAN_UNIT_ATTRS(2), |
902 | FAN_UNIT_ATTRS(3), | ||
903 | FAN_UNIT_ATTRS(4), | ||
904 | TEMP_UNIT_ATTRS(0), | 1160 | TEMP_UNIT_ATTRS(0), |
905 | TEMP_UNIT_ATTRS(1), | 1161 | TEMP_UNIT_ATTRS(1), |
906 | TEMP_UNIT_ATTRS(2), | 1162 | TEMP_UNIT_ATTRS(2), |
@@ -909,6 +1165,18 @@ static struct attribute *w83791d_attributes[] = { | |||
909 | &sda_beep_ctrl[1].dev_attr.attr, | 1165 | &sda_beep_ctrl[1].dev_attr.attr, |
910 | &dev_attr_cpu0_vid.attr, | 1166 | &dev_attr_cpu0_vid.attr, |
911 | &dev_attr_vrm.attr, | 1167 | &dev_attr_vrm.attr, |
1168 | &sda_pwm[0].dev_attr.attr, | ||
1169 | &sda_pwm[1].dev_attr.attr, | ||
1170 | &sda_pwm[2].dev_attr.attr, | ||
1171 | &sda_pwmenable[0].dev_attr.attr, | ||
1172 | &sda_pwmenable[1].dev_attr.attr, | ||
1173 | &sda_pwmenable[2].dev_attr.attr, | ||
1174 | &sda_temp_target[0].dev_attr.attr, | ||
1175 | &sda_temp_target[1].dev_attr.attr, | ||
1176 | &sda_temp_target[2].dev_attr.attr, | ||
1177 | &sda_temp_tolerance[0].dev_attr.attr, | ||
1178 | &sda_temp_tolerance[1].dev_attr.attr, | ||
1179 | &sda_temp_tolerance[2].dev_attr.attr, | ||
912 | NULL | 1180 | NULL |
913 | }; | 1181 | }; |
914 | 1182 | ||
@@ -916,6 +1184,20 @@ static const struct attribute_group w83791d_group = { | |||
916 | .attrs = w83791d_attributes, | 1184 | .attrs = w83791d_attributes, |
917 | }; | 1185 | }; |
918 | 1186 | ||
1187 | /* Separate group of attributes for fan/pwm 4-5. Their pins can also be | ||
1188 | in use for GPIO in which case their sysfs-interface should not be made | ||
1189 | available */ | ||
1190 | static struct attribute *w83791d_attributes_fanpwm45[] = { | ||
1191 | FAN_UNIT_ATTRS(3), | ||
1192 | FAN_UNIT_ATTRS(4), | ||
1193 | &sda_pwm[3].dev_attr.attr, | ||
1194 | &sda_pwm[4].dev_attr.attr, | ||
1195 | NULL | ||
1196 | }; | ||
1197 | |||
1198 | static const struct attribute_group w83791d_group_fanpwm45 = { | ||
1199 | .attrs = w83791d_attributes_fanpwm45, | ||
1200 | }; | ||
919 | 1201 | ||
920 | static int w83791d_detect_subclients(struct i2c_client *client) | 1202 | static int w83791d_detect_subclients(struct i2c_client *client) |
921 | { | 1203 | { |
@@ -1046,9 +1328,11 @@ static int w83791d_probe(struct i2c_client *client, | |||
1046 | { | 1328 | { |
1047 | struct w83791d_data *data; | 1329 | struct w83791d_data *data; |
1048 | struct device *dev = &client->dev; | 1330 | struct device *dev = &client->dev; |
1049 | int i, val1, err; | 1331 | int i, err; |
1332 | u8 has_fanpwm45; | ||
1050 | 1333 | ||
1051 | #ifdef DEBUG | 1334 | #ifdef DEBUG |
1335 | int val1; | ||
1052 | val1 = w83791d_read(client, W83791D_REG_DID_VID4); | 1336 | val1 = w83791d_read(client, W83791D_REG_DID_VID4); |
1053 | dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", | 1337 | dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", |
1054 | (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); | 1338 | (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); |
@@ -1080,15 +1364,27 @@ static int w83791d_probe(struct i2c_client *client, | |||
1080 | if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group))) | 1364 | if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group))) |
1081 | goto error3; | 1365 | goto error3; |
1082 | 1366 | ||
1367 | /* Check if pins of fan/pwm 4-5 are in use as GPIO */ | ||
1368 | has_fanpwm45 = w83791d_read(client, W83791D_REG_GPIO) & 0x10; | ||
1369 | if (has_fanpwm45) { | ||
1370 | err = sysfs_create_group(&client->dev.kobj, | ||
1371 | &w83791d_group_fanpwm45); | ||
1372 | if (err) | ||
1373 | goto error4; | ||
1374 | } | ||
1375 | |||
1083 | /* Everything is ready, now register the working device */ | 1376 | /* Everything is ready, now register the working device */ |
1084 | data->hwmon_dev = hwmon_device_register(dev); | 1377 | data->hwmon_dev = hwmon_device_register(dev); |
1085 | if (IS_ERR(data->hwmon_dev)) { | 1378 | if (IS_ERR(data->hwmon_dev)) { |
1086 | err = PTR_ERR(data->hwmon_dev); | 1379 | err = PTR_ERR(data->hwmon_dev); |
1087 | goto error4; | 1380 | goto error5; |
1088 | } | 1381 | } |
1089 | 1382 | ||
1090 | return 0; | 1383 | return 0; |
1091 | 1384 | ||
1385 | error5: | ||
1386 | if (has_fanpwm45) | ||
1387 | sysfs_remove_group(&client->dev.kobj, &w83791d_group_fanpwm45); | ||
1092 | error4: | 1388 | error4: |
1093 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); | 1389 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); |
1094 | error3: | 1390 | error3: |
@@ -1182,6 +1478,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
1182 | struct w83791d_data *data = i2c_get_clientdata(client); | 1478 | struct w83791d_data *data = i2c_get_clientdata(client); |
1183 | int i, j; | 1479 | int i, j; |
1184 | u8 reg_array_tmp[3]; | 1480 | u8 reg_array_tmp[3]; |
1481 | u8 vbat_reg; | ||
1185 | 1482 | ||
1186 | mutex_lock(&data->update_lock); | 1483 | mutex_lock(&data->update_lock); |
1187 | 1484 | ||
@@ -1219,6 +1516,42 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
1219 | data->fan_div[3] = reg_array_tmp[2] & 0x07; | 1516 | data->fan_div[3] = reg_array_tmp[2] & 0x07; |
1220 | data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; | 1517 | data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; |
1221 | 1518 | ||
1519 | /* The fan divisor for fans 0-2 get bit 2 from | ||
1520 | bits 5-7 respectively of vbat register */ | ||
1521 | vbat_reg = w83791d_read(client, W83791D_REG_VBAT); | ||
1522 | for (i = 0; i < 3; i++) | ||
1523 | data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04; | ||
1524 | |||
1525 | /* Update PWM duty cycle */ | ||
1526 | for (i = 0; i < NUMBER_OF_PWM; i++) { | ||
1527 | data->pwm[i] = w83791d_read(client, | ||
1528 | W83791D_REG_PWM[i]); | ||
1529 | } | ||
1530 | |||
1531 | /* Update PWM enable status */ | ||
1532 | for (i = 0; i < 2; i++) { | ||
1533 | reg_array_tmp[i] = w83791d_read(client, | ||
1534 | W83791D_REG_FAN_CFG[i]); | ||
1535 | } | ||
1536 | data->pwm_enable[0] = (reg_array_tmp[0] >> 2) & 0x03; | ||
1537 | data->pwm_enable[1] = (reg_array_tmp[0] >> 4) & 0x03; | ||
1538 | data->pwm_enable[2] = (reg_array_tmp[1] >> 2) & 0x03; | ||
1539 | |||
1540 | /* Update PWM target temperature */ | ||
1541 | for (i = 0; i < 3; i++) { | ||
1542 | data->temp_target[i] = w83791d_read(client, | ||
1543 | W83791D_REG_TEMP_TARGET[i]) & 0x7f; | ||
1544 | } | ||
1545 | |||
1546 | /* Update PWM temperature tolerance */ | ||
1547 | for (i = 0; i < 2; i++) { | ||
1548 | reg_array_tmp[i] = w83791d_read(client, | ||
1549 | W83791D_REG_TEMP_TOL[i]); | ||
1550 | } | ||
1551 | data->temp_tolerance[0] = reg_array_tmp[0] & 0x0f; | ||
1552 | data->temp_tolerance[1] = (reg_array_tmp[0] >> 4) & 0x0f; | ||
1553 | data->temp_tolerance[2] = reg_array_tmp[1] & 0x0f; | ||
1554 | |||
1222 | /* Update the first temperature sensor */ | 1555 | /* Update the first temperature sensor */ |
1223 | for (i = 0; i < 3; i++) { | 1556 | for (i = 0; i < 3; i++) { |
1224 | data->temp1[i] = w83791d_read(client, | 1557 | data->temp1[i] = w83791d_read(client, |