aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 18:20:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 18:20:16 -0400
commit3e56d49390cd161f34cc049a3661045183d276d5 (patch)
tree0006f1cd2f1b1be6c7149a3234a9ab3ff76c7e80 /drivers
parentc82ffab9a857f8286ed2b559624b7005a367b638 (diff)
parent58f055e5314856a3badfa61fe144347903488989 (diff)
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging: hwmon: (ltc4245) Clear faults at startup hwmon: (ltc4215) Clear faults at startup hwmon: (coretemp) Add Lynnfield CPU hwmon: (coretemp) Add support for Penryn mobile CPUs hwmon: (coretemp) Fix Atom CPUs support hwmon: Delete deprecated FSC drivers hwmon: (adm1031) Add sysfs files for temperature offsets
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/Kconfig34
-rw-r--r--drivers/hwmon/Makefile2
-rw-r--r--drivers/hwmon/adm1031.c40
-rw-r--r--drivers/hwmon/coretemp.c57
-rw-r--r--drivers/hwmon/fscher.c680
-rw-r--r--drivers/hwmon/fscpos.c654
-rw-r--r--drivers/hwmon/ltc4215.c2
-rw-r--r--drivers/hwmon/ltc4245.c3
8 files changed, 90 insertions, 1382 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ed7711d11ae8..6857560144bd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -325,34 +325,6 @@ config SENSORS_F75375S
325 This driver can also be built as a module. If so, the module 325 This driver can also be built as a module. If so, the module
326 will be called f75375s. 326 will be called f75375s.
327 327
328config SENSORS_FSCHER
329 tristate "FSC Hermes (DEPRECATED)"
330 depends on X86 && I2C
331 help
332 This driver is DEPRECATED please use the new merged fschmd
333 ("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver
334 instead.
335
336 If you say yes here you get support for Fujitsu Siemens
337 Computers Hermes sensor chips.
338
339 This driver can also be built as a module. If so, the module
340 will be called fscher.
341
342config SENSORS_FSCPOS
343 tristate "FSC Poseidon (DEPRECATED)"
344 depends on X86 && I2C
345 help
346 This driver is DEPRECATED please use the new merged fschmd
347 ("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver
348 instead.
349
350 If you say yes here you get support for Fujitsu Siemens
351 Computers Poseidon sensor chips.
352
353 This driver can also be built as a module. If so, the module
354 will be called fscpos.
355
356config SENSORS_FSCHMD 328config SENSORS_FSCHMD
357 tristate "Fujitsu Siemens Computers sensor chips" 329 tristate "Fujitsu Siemens Computers sensor chips"
358 depends on X86 && I2C 330 depends on X86 && I2C
@@ -401,12 +373,12 @@ config SENSORS_GL520SM
401 will be called gl520sm. 373 will be called gl520sm.
402 374
403config SENSORS_CORETEMP 375config SENSORS_CORETEMP
404 tristate "Intel Core (2) Duo/Solo temperature sensor" 376 tristate "Intel Core/Core2/Atom temperature sensor"
405 depends on X86 && EXPERIMENTAL 377 depends on X86 && EXPERIMENTAL
406 help 378 help
407 If you say yes here you get support for the temperature 379 If you say yes here you get support for the temperature
408 sensor inside your CPU. Supported all are all known variants 380 sensor inside your CPU. Most of the family 6 CPUs
409 of Intel Core family. 381 are supported. Check documentation/driver for details.
410 382
411config SENSORS_IBMAEM 383config SENSORS_IBMAEM
412 tristate "IBM Active Energy Manager temperature/power sensors and control" 384 tristate "IBM Active Energy Manager temperature/power sensors and control"
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index bcf73a9bb619..9f46cb019cc6 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -42,9 +42,7 @@ obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
42obj-$(CONFIG_SENSORS_F71805F) += f71805f.o 42obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
43obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o 43obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o
44obj-$(CONFIG_SENSORS_F75375S) += f75375s.o 44obj-$(CONFIG_SENSORS_F75375S) += f75375s.o
45obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
46obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o 45obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o
47obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
48obj-$(CONFIG_SENSORS_G760A) += g760a.o 46obj-$(CONFIG_SENSORS_G760A) += g760a.o
49obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o 47obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
50obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o 48obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 789441830cd8..56905955352c 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -37,6 +37,7 @@
37#define ADM1031_REG_PWM (0x22) 37#define ADM1031_REG_PWM (0x22)
38#define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) 38#define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr))
39 39
40#define ADM1031_REG_TEMP_OFFSET(nr) (0x0d + (nr))
40#define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr)) 41#define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr))
41#define ADM1031_REG_TEMP_MIN(nr) (0x15 + 4 * (nr)) 42#define ADM1031_REG_TEMP_MIN(nr) (0x15 + 4 * (nr))
42#define ADM1031_REG_TEMP_CRIT(nr) (0x16 + 4 * (nr)) 43#define ADM1031_REG_TEMP_CRIT(nr) (0x16 + 4 * (nr))
@@ -93,6 +94,7 @@ struct adm1031_data {
93 u8 auto_temp_min[3]; 94 u8 auto_temp_min[3];
94 u8 auto_temp_off[3]; 95 u8 auto_temp_off[3];
95 u8 auto_temp_max[3]; 96 u8 auto_temp_max[3];
97 s8 temp_offset[3];
96 s8 temp_min[3]; 98 s8 temp_min[3];
97 s8 temp_max[3]; 99 s8 temp_max[3];
98 s8 temp_crit[3]; 100 s8 temp_crit[3];
@@ -145,6 +147,10 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
145 147
146#define TEMP_FROM_REG_EXT(val, ext) (TEMP_FROM_REG(val) + (ext) * 125) 148#define TEMP_FROM_REG_EXT(val, ext) (TEMP_FROM_REG(val) + (ext) * 125)
147 149
150#define TEMP_OFFSET_TO_REG(val) (TEMP_TO_REG(val) & 0x8f)
151#define TEMP_OFFSET_FROM_REG(val) TEMP_FROM_REG((val) < 0 ? \
152 (val) | 0x70 : (val))
153
148#define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0) 154#define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0)
149 155
150static int FAN_TO_REG(int reg, int div) 156static int FAN_TO_REG(int reg, int div)
@@ -585,6 +591,14 @@ static ssize_t show_temp(struct device *dev,
585 (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7)); 591 (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
586 return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext)); 592 return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
587} 593}
594static ssize_t show_temp_offset(struct device *dev,
595 struct device_attribute *attr, char *buf)
596{
597 int nr = to_sensor_dev_attr(attr)->index;
598 struct adm1031_data *data = adm1031_update_device(dev);
599 return sprintf(buf, "%d\n",
600 TEMP_OFFSET_FROM_REG(data->temp_offset[nr]));
601}
588static ssize_t show_temp_min(struct device *dev, 602static ssize_t show_temp_min(struct device *dev,
589 struct device_attribute *attr, char *buf) 603 struct device_attribute *attr, char *buf)
590{ 604{
@@ -606,6 +620,24 @@ static ssize_t show_temp_crit(struct device *dev,
606 struct adm1031_data *data = adm1031_update_device(dev); 620 struct adm1031_data *data = adm1031_update_device(dev);
607 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr])); 621 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
608} 622}
623static ssize_t set_temp_offset(struct device *dev,
624 struct device_attribute *attr, const char *buf,
625 size_t count)
626{
627 struct i2c_client *client = to_i2c_client(dev);
628 struct adm1031_data *data = i2c_get_clientdata(client);
629 int nr = to_sensor_dev_attr(attr)->index;
630 int val;
631
632 val = simple_strtol(buf, NULL, 10);
633 val = SENSORS_LIMIT(val, -15000, 15000);
634 mutex_lock(&data->update_lock);
635 data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val);
636 adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr),
637 data->temp_offset[nr]);
638 mutex_unlock(&data->update_lock);
639 return count;
640}
609static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, 641static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
610 const char *buf, size_t count) 642 const char *buf, size_t count)
611{ 643{
@@ -661,6 +693,8 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
661#define temp_reg(offset) \ 693#define temp_reg(offset) \
662static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ 694static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
663 show_temp, NULL, offset - 1); \ 695 show_temp, NULL, offset - 1); \
696static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \
697 show_temp_offset, set_temp_offset, offset - 1); \
664static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ 698static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
665 show_temp_min, set_temp_min, offset - 1); \ 699 show_temp_min, set_temp_min, offset - 1); \
666static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ 700static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
@@ -714,6 +748,7 @@ static struct attribute *adm1031_attributes[] = {
714 &sensor_dev_attr_pwm1.dev_attr.attr, 748 &sensor_dev_attr_pwm1.dev_attr.attr,
715 &sensor_dev_attr_auto_fan1_channel.dev_attr.attr, 749 &sensor_dev_attr_auto_fan1_channel.dev_attr.attr,
716 &sensor_dev_attr_temp1_input.dev_attr.attr, 750 &sensor_dev_attr_temp1_input.dev_attr.attr,
751 &sensor_dev_attr_temp1_offset.dev_attr.attr,
717 &sensor_dev_attr_temp1_min.dev_attr.attr, 752 &sensor_dev_attr_temp1_min.dev_attr.attr,
718 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 753 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
719 &sensor_dev_attr_temp1_max.dev_attr.attr, 754 &sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -721,6 +756,7 @@ static struct attribute *adm1031_attributes[] = {
721 &sensor_dev_attr_temp1_crit.dev_attr.attr, 756 &sensor_dev_attr_temp1_crit.dev_attr.attr,
722 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 757 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
723 &sensor_dev_attr_temp2_input.dev_attr.attr, 758 &sensor_dev_attr_temp2_input.dev_attr.attr,
759 &sensor_dev_attr_temp2_offset.dev_attr.attr,
724 &sensor_dev_attr_temp2_min.dev_attr.attr, 760 &sensor_dev_attr_temp2_min.dev_attr.attr,
725 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, 761 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
726 &sensor_dev_attr_temp2_max.dev_attr.attr, 762 &sensor_dev_attr_temp2_max.dev_attr.attr,
@@ -757,6 +793,7 @@ static struct attribute *adm1031_attributes_opt[] = {
757 &sensor_dev_attr_pwm2.dev_attr.attr, 793 &sensor_dev_attr_pwm2.dev_attr.attr,
758 &sensor_dev_attr_auto_fan2_channel.dev_attr.attr, 794 &sensor_dev_attr_auto_fan2_channel.dev_attr.attr,
759 &sensor_dev_attr_temp3_input.dev_attr.attr, 795 &sensor_dev_attr_temp3_input.dev_attr.attr,
796 &sensor_dev_attr_temp3_offset.dev_attr.attr,
760 &sensor_dev_attr_temp3_min.dev_attr.attr, 797 &sensor_dev_attr_temp3_min.dev_attr.attr,
761 &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, 798 &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
762 &sensor_dev_attr_temp3_max.dev_attr.attr, 799 &sensor_dev_attr_temp3_max.dev_attr.attr,
@@ -937,6 +974,9 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
937 } 974 }
938 data->temp[chan] = newh; 975 data->temp[chan] = newh;
939 976
977 data->temp_offset[chan] =
978 adm1031_read_value(client,
979 ADM1031_REG_TEMP_OFFSET(chan));
940 data->temp_min[chan] = 980 data->temp_min[chan] =
941 adm1031_read_value(client, 981 adm1031_read_value(client,
942 ADM1031_REG_TEMP_MIN(chan)); 982 ADM1031_REG_TEMP_MIN(chan));
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 972cf4ba963c..caef39cda8c8 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -157,17 +157,26 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
157 /* The 100C is default for both mobile and non mobile CPUs */ 157 /* The 100C is default for both mobile and non mobile CPUs */
158 158
159 int tjmax = 100000; 159 int tjmax = 100000;
160 int ismobile = 1; 160 int tjmax_ee = 85000;
161 int usemsr_ee = 1;
161 int err; 162 int err;
162 u32 eax, edx; 163 u32 eax, edx;
163 164
164 /* Early chips have no MSR for TjMax */ 165 /* Early chips have no MSR for TjMax */
165 166
166 if ((c->x86_model == 0xf) && (c->x86_mask < 4)) { 167 if ((c->x86_model == 0xf) && (c->x86_mask < 4)) {
167 ismobile = 0; 168 usemsr_ee = 0;
168 } 169 }
169 170
170 if ((c->x86_model > 0xe) && (ismobile)) { 171 /* Atoms seems to have TjMax at 90C */
172
173 if (c->x86_model == 0x1c) {
174 usemsr_ee = 0;
175 tjmax = 90000;
176 }
177
178 if ((c->x86_model > 0xe) && (usemsr_ee)) {
179 u8 platform_id;
171 180
172 /* Now we can detect the mobile CPU using Intel provided table 181 /* Now we can detect the mobile CPU using Intel provided table
173 http://softwarecommunity.intel.com/Wiki/Mobility/720.htm 182 http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
@@ -179,13 +188,29 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
179 dev_warn(dev, 188 dev_warn(dev,
180 "Unable to access MSR 0x17, assuming desktop" 189 "Unable to access MSR 0x17, assuming desktop"
181 " CPU\n"); 190 " CPU\n");
182 ismobile = 0; 191 usemsr_ee = 0;
183 } else if (!(eax & 0x10000000)) { 192 } else if (c->x86_model < 0x17 && !(eax & 0x10000000)) {
184 ismobile = 0; 193 /* Trust bit 28 up to Penryn, I could not find any
194 documentation on that; if you happen to know
195 someone at Intel please ask */
196 usemsr_ee = 0;
197 } else {
198 /* Platform ID bits 52:50 (EDX starts at bit 32) */
199 platform_id = (edx >> 18) & 0x7;
200
201 /* Mobile Penryn CPU seems to be platform ID 7 or 5
202 (guesswork) */
203 if ((c->x86_model == 0x17) &&
204 ((platform_id == 5) || (platform_id == 7))) {
205 /* If MSR EE bit is set, set it to 90 degrees C,
206 otherwise 105 degrees C */
207 tjmax_ee = 90000;
208 tjmax = 105000;
209 }
185 } 210 }
186 } 211 }
187 212
188 if (ismobile || c->x86_model == 0x1c) { 213 if (usemsr_ee) {
189 214
190 err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); 215 err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx);
191 if (err) { 216 if (err) {
@@ -193,9 +218,11 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
193 "Unable to access MSR 0xEE, for Tjmax, left" 218 "Unable to access MSR 0xEE, for Tjmax, left"
194 " at default"); 219 " at default");
195 } else if (eax & 0x40000000) { 220 } else if (eax & 0x40000000) {
196 tjmax = 85000; 221 tjmax = tjmax_ee;
197 } 222 }
198 } else { 223 /* if we dont use msr EE it means we are desktop CPU (with exeception
224 of Atom) */
225 } else if (tjmax == 100000) {
199 dev_warn(dev, "Using relative temperature scale!\n"); 226 dev_warn(dev, "Using relative temperature scale!\n");
200 } 227 }
201 228
@@ -248,9 +275,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
248 platform_set_drvdata(pdev, data); 275 platform_set_drvdata(pdev, data);
249 276
250 /* read the still undocumented IA32_TEMPERATURE_TARGET it exists 277 /* read the still undocumented IA32_TEMPERATURE_TARGET it exists
251 on older CPUs but not in this register */ 278 on older CPUs but not in this register, Atoms don't have it either */
252 279
253 if (c->x86_model > 0xe) { 280 if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) {
254 err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); 281 err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
255 if (err) { 282 if (err) {
256 dev_warn(&pdev->dev, "Unable to read" 283 dev_warn(&pdev->dev, "Unable to read"
@@ -413,11 +440,15 @@ static int __init coretemp_init(void)
413 for_each_online_cpu(i) { 440 for_each_online_cpu(i) {
414 struct cpuinfo_x86 *c = &cpu_data(i); 441 struct cpuinfo_x86 *c = &cpu_data(i);
415 442
416 /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A */ 443 /* check if family 6, models 0xe (Pentium M DC),
444 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm),
445 0x17 (Penryn 45nm), 0x1a (Nehalem), 0x1c (Atom),
446 0x1e (Lynnfield) */
417 if ((c->cpuid_level < 0) || (c->x86 != 0x6) || 447 if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
418 !((c->x86_model == 0xe) || (c->x86_model == 0xf) || 448 !((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
419 (c->x86_model == 0x16) || (c->x86_model == 0x17) || 449 (c->x86_model == 0x16) || (c->x86_model == 0x17) ||
420 (c->x86_model == 0x1A) || (c->x86_model == 0x1c))) { 450 (c->x86_model == 0x1a) || (c->x86_model == 0x1c) ||
451 (c->x86_model == 0x1e))) {
421 452
422 /* supported CPU not found, but report the unknown 453 /* supported CPU not found, but report the unknown
423 family 6 CPU */ 454 family 6 CPU */
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
deleted file mode 100644
index 12c70e402cb2..000000000000
--- a/drivers/hwmon/fscher.c
+++ /dev/null
@@ -1,680 +0,0 @@
1/*
2 * fscher.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring
4 * Copyright (C) 2003, 2004 Reinhard Nissl <rnissl@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21/*
22 * fujitsu siemens hermes chip,
23 * module based on fscpos.c
24 * Copyright (C) 2000 Hermann Jung <hej@odn.de>
25 * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
26 * and Philip Edelbrock <phil@netroedge.com>
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/jiffies.h>
33#include <linux/i2c.h>
34#include <linux/hwmon.h>
35#include <linux/err.h>
36#include <linux/mutex.h>
37#include <linux/sysfs.h>
38
39/*
40 * Addresses to scan
41 */
42
43static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
44
45/*
46 * Insmod parameters
47 */
48
49I2C_CLIENT_INSMOD_1(fscher);
50
51/*
52 * The FSCHER registers
53 */
54
55/* chip identification */
56#define FSCHER_REG_IDENT_0 0x00
57#define FSCHER_REG_IDENT_1 0x01
58#define FSCHER_REG_IDENT_2 0x02
59#define FSCHER_REG_REVISION 0x03
60
61/* global control and status */
62#define FSCHER_REG_EVENT_STATE 0x04
63#define FSCHER_REG_CONTROL 0x05
64
65/* watchdog */
66#define FSCHER_REG_WDOG_PRESET 0x28
67#define FSCHER_REG_WDOG_STATE 0x23
68#define FSCHER_REG_WDOG_CONTROL 0x21
69
70/* fan 0 */
71#define FSCHER_REG_FAN0_MIN 0x55
72#define FSCHER_REG_FAN0_ACT 0x0e
73#define FSCHER_REG_FAN0_STATE 0x0d
74#define FSCHER_REG_FAN0_RIPPLE 0x0f
75
76/* fan 1 */
77#define FSCHER_REG_FAN1_MIN 0x65
78#define FSCHER_REG_FAN1_ACT 0x6b
79#define FSCHER_REG_FAN1_STATE 0x62
80#define FSCHER_REG_FAN1_RIPPLE 0x6f
81
82/* fan 2 */
83#define FSCHER_REG_FAN2_MIN 0xb5
84#define FSCHER_REG_FAN2_ACT 0xbb
85#define FSCHER_REG_FAN2_STATE 0xb2
86#define FSCHER_REG_FAN2_RIPPLE 0xbf
87
88/* voltage supervision */
89#define FSCHER_REG_VOLT_12 0x45
90#define FSCHER_REG_VOLT_5 0x42
91#define FSCHER_REG_VOLT_BATT 0x48
92
93/* temperature 0 */
94#define FSCHER_REG_TEMP0_ACT 0x64
95#define FSCHER_REG_TEMP0_STATE 0x71
96
97/* temperature 1 */
98#define FSCHER_REG_TEMP1_ACT 0x32
99#define FSCHER_REG_TEMP1_STATE 0x81
100
101/* temperature 2 */
102#define FSCHER_REG_TEMP2_ACT 0x35
103#define FSCHER_REG_TEMP2_STATE 0x91
104
105/*
106 * Functions declaration
107 */
108
109static int fscher_probe(struct i2c_client *client,
110 const struct i2c_device_id *id);
111static int fscher_detect(struct i2c_client *client, int kind,
112 struct i2c_board_info *info);
113static int fscher_remove(struct i2c_client *client);
114static struct fscher_data *fscher_update_device(struct device *dev);
115static void fscher_init_client(struct i2c_client *client);
116
117static int fscher_read_value(struct i2c_client *client, u8 reg);
118static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value);
119
120/*
121 * Driver data (common to all clients)
122 */
123
124static const struct i2c_device_id fscher_id[] = {
125 { "fscher", fscher },
126 { }
127};
128
129static struct i2c_driver fscher_driver = {
130 .class = I2C_CLASS_HWMON,
131 .driver = {
132 .name = "fscher",
133 },
134 .probe = fscher_probe,
135 .remove = fscher_remove,
136 .id_table = fscher_id,
137 .detect = fscher_detect,
138 .address_data = &addr_data,
139};
140
141/*
142 * Client data (each client gets its own)
143 */
144
145struct fscher_data {
146 struct device *hwmon_dev;
147 struct mutex update_lock;
148 char valid; /* zero until following fields are valid */
149 unsigned long last_updated; /* in jiffies */
150
151 /* register values */
152 u8 revision; /* revision of chip */
153 u8 global_event; /* global event status */
154 u8 global_control; /* global control register */
155 u8 watchdog[3]; /* watchdog */
156 u8 volt[3]; /* 12, 5, battery voltage */
157 u8 temp_act[3]; /* temperature */
158 u8 temp_status[3]; /* status of sensor */
159 u8 fan_act[3]; /* fans revolutions per second */
160 u8 fan_status[3]; /* fan status */
161 u8 fan_min[3]; /* fan min value for rps */
162 u8 fan_ripple[3]; /* divider for rps */
163};
164
165/*
166 * Sysfs stuff
167 */
168
169#define sysfs_r(kind, sub, offset, reg) \
170static ssize_t show_##kind##sub (struct fscher_data *, char *, int); \
171static ssize_t show_##kind##offset##sub (struct device *, struct device_attribute *attr, char *); \
172static ssize_t show_##kind##offset##sub (struct device *dev, struct device_attribute *attr, char *buf) \
173{ \
174 struct fscher_data *data = fscher_update_device(dev); \
175 return show_##kind##sub(data, buf, (offset)); \
176}
177
178#define sysfs_w(kind, sub, offset, reg) \
179static ssize_t set_##kind##sub (struct i2c_client *, struct fscher_data *, const char *, size_t, int, int); \
180static ssize_t set_##kind##offset##sub (struct device *, struct device_attribute *attr, const char *, size_t); \
181static ssize_t set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
182{ \
183 struct i2c_client *client = to_i2c_client(dev); \
184 struct fscher_data *data = i2c_get_clientdata(client); \
185 return set_##kind##sub(client, data, buf, count, (offset), reg); \
186}
187
188#define sysfs_rw_n(kind, sub, offset, reg) \
189sysfs_r(kind, sub, offset, reg) \
190sysfs_w(kind, sub, offset, reg) \
191static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, show_##kind##offset##sub, set_##kind##offset##sub);
192
193#define sysfs_rw(kind, sub, reg) \
194sysfs_r(kind, sub, 0, reg) \
195sysfs_w(kind, sub, 0, reg) \
196static DEVICE_ATTR(kind##sub, S_IRUGO | S_IWUSR, show_##kind##0##sub, set_##kind##0##sub);
197
198#define sysfs_ro_n(kind, sub, offset, reg) \
199sysfs_r(kind, sub, offset, reg) \
200static DEVICE_ATTR(kind##offset##sub, S_IRUGO, show_##kind##offset##sub, NULL);
201
202#define sysfs_ro(kind, sub, reg) \
203sysfs_r(kind, sub, 0, reg) \
204static DEVICE_ATTR(kind, S_IRUGO, show_##kind##0##sub, NULL);
205
206#define sysfs_fan(offset, reg_status, reg_min, reg_ripple, reg_act) \
207sysfs_rw_n(pwm, , offset, reg_min) \
208sysfs_rw_n(fan, _status, offset, reg_status) \
209sysfs_rw_n(fan, _div , offset, reg_ripple) \
210sysfs_ro_n(fan, _input , offset, reg_act)
211
212#define sysfs_temp(offset, reg_status, reg_act) \
213sysfs_rw_n(temp, _status, offset, reg_status) \
214sysfs_ro_n(temp, _input , offset, reg_act)
215
216#define sysfs_in(offset, reg_act) \
217sysfs_ro_n(in, _input, offset, reg_act)
218
219#define sysfs_revision(reg_revision) \
220sysfs_ro(revision, , reg_revision)
221
222#define sysfs_alarms(reg_events) \
223sysfs_ro(alarms, , reg_events)
224
225#define sysfs_control(reg_control) \
226sysfs_rw(control, , reg_control)
227
228#define sysfs_watchdog(reg_control, reg_status, reg_preset) \
229sysfs_rw(watchdog, _control, reg_control) \
230sysfs_rw(watchdog, _status , reg_status) \
231sysfs_rw(watchdog, _preset , reg_preset)
232
233sysfs_fan(1, FSCHER_REG_FAN0_STATE, FSCHER_REG_FAN0_MIN,
234 FSCHER_REG_FAN0_RIPPLE, FSCHER_REG_FAN0_ACT)
235sysfs_fan(2, FSCHER_REG_FAN1_STATE, FSCHER_REG_FAN1_MIN,
236 FSCHER_REG_FAN1_RIPPLE, FSCHER_REG_FAN1_ACT)
237sysfs_fan(3, FSCHER_REG_FAN2_STATE, FSCHER_REG_FAN2_MIN,
238 FSCHER_REG_FAN2_RIPPLE, FSCHER_REG_FAN2_ACT)
239
240sysfs_temp(1, FSCHER_REG_TEMP0_STATE, FSCHER_REG_TEMP0_ACT)
241sysfs_temp(2, FSCHER_REG_TEMP1_STATE, FSCHER_REG_TEMP1_ACT)
242sysfs_temp(3, FSCHER_REG_TEMP2_STATE, FSCHER_REG_TEMP2_ACT)
243
244sysfs_in(0, FSCHER_REG_VOLT_12)
245sysfs_in(1, FSCHER_REG_VOLT_5)
246sysfs_in(2, FSCHER_REG_VOLT_BATT)
247
248sysfs_revision(FSCHER_REG_REVISION)
249sysfs_alarms(FSCHER_REG_EVENTS)
250sysfs_control(FSCHER_REG_CONTROL)
251sysfs_watchdog(FSCHER_REG_WDOG_CONTROL, FSCHER_REG_WDOG_STATE, FSCHER_REG_WDOG_PRESET)
252
253static struct attribute *fscher_attributes[] = {
254 &dev_attr_revision.attr,
255 &dev_attr_alarms.attr,
256 &dev_attr_control.attr,
257
258 &dev_attr_watchdog_status.attr,
259 &dev_attr_watchdog_control.attr,
260 &dev_attr_watchdog_preset.attr,
261
262 &dev_attr_in0_input.attr,
263 &dev_attr_in1_input.attr,
264 &dev_attr_in2_input.attr,
265
266 &dev_attr_fan1_status.attr,
267 &dev_attr_fan1_div.attr,
268 &dev_attr_fan1_input.attr,
269 &dev_attr_pwm1.attr,
270 &dev_attr_fan2_status.attr,
271 &dev_attr_fan2_div.attr,
272 &dev_attr_fan2_input.attr,
273 &dev_attr_pwm2.attr,
274 &dev_attr_fan3_status.attr,
275 &dev_attr_fan3_div.attr,
276 &dev_attr_fan3_input.attr,
277 &dev_attr_pwm3.attr,
278
279 &dev_attr_temp1_status.attr,
280 &dev_attr_temp1_input.attr,
281 &dev_attr_temp2_status.attr,
282 &dev_attr_temp2_input.attr,
283 &dev_attr_temp3_status.attr,
284 &dev_attr_temp3_input.attr,
285 NULL
286};
287
288static const struct attribute_group fscher_group = {
289 .attrs = fscher_attributes,
290};
291
292/*
293 * Real code
294 */
295
296/* Return 0 if detection is successful, -ENODEV otherwise */
297static int fscher_detect(struct i2c_client *new_client, int kind,
298 struct i2c_board_info *info)
299{
300 struct i2c_adapter *adapter = new_client->adapter;
301
302 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
303 return -ENODEV;
304
305 /* Do the remaining detection unless force or force_fscher parameter */
306 if (kind < 0) {
307 if ((i2c_smbus_read_byte_data(new_client,
308 FSCHER_REG_IDENT_0) != 0x48) /* 'H' */
309 || (i2c_smbus_read_byte_data(new_client,
310 FSCHER_REG_IDENT_1) != 0x45) /* 'E' */
311 || (i2c_smbus_read_byte_data(new_client,
312 FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */
313 return -ENODEV;
314 }
315
316 strlcpy(info->type, "fscher", I2C_NAME_SIZE);
317
318 return 0;
319}
320
321static int fscher_probe(struct i2c_client *new_client,
322 const struct i2c_device_id *id)
323{
324 struct fscher_data *data;
325 int err;
326
327 data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL);
328 if (!data) {
329 err = -ENOMEM;
330 goto exit;
331 }
332
333 i2c_set_clientdata(new_client, data);
334 data->valid = 0;
335 mutex_init(&data->update_lock);
336
337 fscher_init_client(new_client);
338
339 /* Register sysfs hooks */
340 if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group)))
341 goto exit_free;
342
343 data->hwmon_dev = hwmon_device_register(&new_client->dev);
344 if (IS_ERR(data->hwmon_dev)) {
345 err = PTR_ERR(data->hwmon_dev);
346 goto exit_remove_files;
347 }
348
349 return 0;
350
351exit_remove_files:
352 sysfs_remove_group(&new_client->dev.kobj, &fscher_group);
353exit_free:
354 kfree(data);
355exit:
356 return err;
357}
358
359static int fscher_remove(struct i2c_client *client)
360{
361 struct fscher_data *data = i2c_get_clientdata(client);
362
363 hwmon_device_unregister(data->hwmon_dev);
364 sysfs_remove_group(&client->dev.kobj, &fscher_group);
365
366 kfree(data);
367 return 0;
368}
369
370static int fscher_read_value(struct i2c_client *client, u8 reg)
371{
372 dev_dbg(&client->dev, "read reg 0x%02x\n", reg);
373
374 return i2c_smbus_read_byte_data(client, reg);
375}
376
377static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value)
378{
379 dev_dbg(&client->dev, "write reg 0x%02x, val 0x%02x\n",
380 reg, value);
381
382 return i2c_smbus_write_byte_data(client, reg, value);
383}
384
385/* Called when we have found a new FSC Hermes. */
386static void fscher_init_client(struct i2c_client *client)
387{
388 struct fscher_data *data = i2c_get_clientdata(client);
389
390 /* Read revision from chip */
391 data->revision = fscher_read_value(client, FSCHER_REG_REVISION);
392}
393
394static struct fscher_data *fscher_update_device(struct device *dev)
395{
396 struct i2c_client *client = to_i2c_client(dev);
397 struct fscher_data *data = i2c_get_clientdata(client);
398
399 mutex_lock(&data->update_lock);
400
401 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
402
403 dev_dbg(&client->dev, "Starting fscher update\n");
404
405 data->temp_act[0] = fscher_read_value(client, FSCHER_REG_TEMP0_ACT);
406 data->temp_act[1] = fscher_read_value(client, FSCHER_REG_TEMP1_ACT);
407 data->temp_act[2] = fscher_read_value(client, FSCHER_REG_TEMP2_ACT);
408 data->temp_status[0] = fscher_read_value(client, FSCHER_REG_TEMP0_STATE);
409 data->temp_status[1] = fscher_read_value(client, FSCHER_REG_TEMP1_STATE);
410 data->temp_status[2] = fscher_read_value(client, FSCHER_REG_TEMP2_STATE);
411
412 data->volt[0] = fscher_read_value(client, FSCHER_REG_VOLT_12);
413 data->volt[1] = fscher_read_value(client, FSCHER_REG_VOLT_5);
414 data->volt[2] = fscher_read_value(client, FSCHER_REG_VOLT_BATT);
415
416 data->fan_act[0] = fscher_read_value(client, FSCHER_REG_FAN0_ACT);
417 data->fan_act[1] = fscher_read_value(client, FSCHER_REG_FAN1_ACT);
418 data->fan_act[2] = fscher_read_value(client, FSCHER_REG_FAN2_ACT);
419 data->fan_status[0] = fscher_read_value(client, FSCHER_REG_FAN0_STATE);
420 data->fan_status[1] = fscher_read_value(client, FSCHER_REG_FAN1_STATE);
421 data->fan_status[2] = fscher_read_value(client, FSCHER_REG_FAN2_STATE);
422 data->fan_min[0] = fscher_read_value(client, FSCHER_REG_FAN0_MIN);
423 data->fan_min[1] = fscher_read_value(client, FSCHER_REG_FAN1_MIN);
424 data->fan_min[2] = fscher_read_value(client, FSCHER_REG_FAN2_MIN);
425 data->fan_ripple[0] = fscher_read_value(client, FSCHER_REG_FAN0_RIPPLE);
426 data->fan_ripple[1] = fscher_read_value(client, FSCHER_REG_FAN1_RIPPLE);
427 data->fan_ripple[2] = fscher_read_value(client, FSCHER_REG_FAN2_RIPPLE);
428
429 data->watchdog[0] = fscher_read_value(client, FSCHER_REG_WDOG_PRESET);
430 data->watchdog[1] = fscher_read_value(client, FSCHER_REG_WDOG_STATE);
431 data->watchdog[2] = fscher_read_value(client, FSCHER_REG_WDOG_CONTROL);
432
433 data->global_event = fscher_read_value(client, FSCHER_REG_EVENT_STATE);
434 data->global_control = fscher_read_value(client,
435 FSCHER_REG_CONTROL);
436
437 data->last_updated = jiffies;
438 data->valid = 1;
439 }
440
441 mutex_unlock(&data->update_lock);
442
443 return data;
444}
445
446
447
448#define FAN_INDEX_FROM_NUM(nr) ((nr) - 1)
449
450static ssize_t set_fan_status(struct i2c_client *client, struct fscher_data *data,
451 const char *buf, size_t count, int nr, int reg)
452{
453 /* bits 0..1, 3..7 reserved => mask with 0x04 */
454 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04;
455
456 mutex_lock(&data->update_lock);
457 data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v;
458 fscher_write_value(client, reg, v);
459 mutex_unlock(&data->update_lock);
460 return count;
461}
462
463static ssize_t show_fan_status(struct fscher_data *data, char *buf, int nr)
464{
465 /* bits 0..1, 3..7 reserved => mask with 0x04 */
466 return sprintf(buf, "%u\n", data->fan_status[FAN_INDEX_FROM_NUM(nr)] & 0x04);
467}
468
469static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data,
470 const char *buf, size_t count, int nr, int reg)
471{
472 unsigned long v = simple_strtoul(buf, NULL, 10);
473
474 mutex_lock(&data->update_lock);
475 data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v;
476 fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
477 mutex_unlock(&data->update_lock);
478 return count;
479}
480
481static ssize_t show_pwm(struct fscher_data *data, char *buf, int nr)
482{
483 return sprintf(buf, "%u\n", data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
484}
485
486static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data,
487 const char *buf, size_t count, int nr, int reg)
488{
489 /* supported values: 2, 4, 8 */
490 unsigned long v = simple_strtoul(buf, NULL, 10);
491
492 switch (v) {
493 case 2: v = 1; break;
494 case 4: v = 2; break;
495 case 8: v = 3; break;
496 default:
497 dev_err(&client->dev, "fan_div value %ld not "
498 "supported. Choose one of 2, 4 or 8!\n", v);
499 return -EINVAL;
500 }
501
502 mutex_lock(&data->update_lock);
503
504 /* bits 2..7 reserved => mask with 0x03 */
505 data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03;
506 data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v;
507
508 fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]);
509 mutex_unlock(&data->update_lock);
510 return count;
511}
512
513static ssize_t show_fan_div(struct fscher_data *data, char *buf, int nr)
514{
515 /* bits 2..7 reserved => mask with 0x03 */
516 return sprintf(buf, "%u\n", 1 << (data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] & 0x03));
517}
518
519#define RPM_FROM_REG(val) (val*60)
520
521static ssize_t show_fan_input (struct fscher_data *data, char *buf, int nr)
522{
523 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[FAN_INDEX_FROM_NUM(nr)]));
524}
525
526
527
528#define TEMP_INDEX_FROM_NUM(nr) ((nr) - 1)
529
530static ssize_t set_temp_status(struct i2c_client *client, struct fscher_data *data,
531 const char *buf, size_t count, int nr, int reg)
532{
533 /* bits 2..7 reserved, 0 read only => mask with 0x02 */
534 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
535
536 mutex_lock(&data->update_lock);
537 data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v;
538 fscher_write_value(client, reg, v);
539 mutex_unlock(&data->update_lock);
540 return count;
541}
542
543static ssize_t show_temp_status(struct fscher_data *data, char *buf, int nr)
544{
545 /* bits 2..7 reserved => mask with 0x03 */
546 return sprintf(buf, "%u\n", data->temp_status[TEMP_INDEX_FROM_NUM(nr)] & 0x03);
547}
548
549#define TEMP_FROM_REG(val) (((val) - 128) * 1000)
550
551static ssize_t show_temp_input(struct fscher_data *data, char *buf, int nr)
552{
553 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[TEMP_INDEX_FROM_NUM(nr)]));
554}
555
556/*
557 * The final conversion is specified in sensors.conf, as it depends on
558 * mainboard specific values. We export the registers contents as
559 * pseudo-hundredths-of-Volts (range 0V - 2.55V). Not that it makes much
560 * sense per se, but it minimizes the conversions count and keeps the
561 * values within a usual range.
562 */
563#define VOLT_FROM_REG(val) ((val) * 10)
564
565static ssize_t show_in_input(struct fscher_data *data, char *buf, int nr)
566{
567 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[nr]));
568}
569
570
571
572static ssize_t show_revision(struct fscher_data *data, char *buf, int nr)
573{
574 return sprintf(buf, "%u\n", data->revision);
575}
576
577
578
579static ssize_t show_alarms(struct fscher_data *data, char *buf, int nr)
580{
581 /* bits 2, 5..6 reserved => mask with 0x9b */
582 return sprintf(buf, "%u\n", data->global_event & 0x9b);
583}
584
585
586
587static ssize_t set_control(struct i2c_client *client, struct fscher_data *data,
588 const char *buf, size_t count, int nr, int reg)
589{
590 /* bits 1..7 reserved => mask with 0x01 */
591 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01;
592
593 mutex_lock(&data->update_lock);
594 data->global_control = v;
595 fscher_write_value(client, reg, v);
596 mutex_unlock(&data->update_lock);
597 return count;
598}
599
600static ssize_t show_control(struct fscher_data *data, char *buf, int nr)
601{
602 /* bits 1..7 reserved => mask with 0x01 */
603 return sprintf(buf, "%u\n", data->global_control & 0x01);
604}
605
606
607
608static ssize_t set_watchdog_control(struct i2c_client *client, struct
609 fscher_data *data, const char *buf, size_t count,
610 int nr, int reg)
611{
612 /* bits 0..3 reserved => mask with 0xf0 */
613 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
614
615 mutex_lock(&data->update_lock);
616 data->watchdog[2] &= ~0xf0;
617 data->watchdog[2] |= v;
618 fscher_write_value(client, reg, data->watchdog[2]);
619 mutex_unlock(&data->update_lock);
620 return count;
621}
622
623static ssize_t show_watchdog_control(struct fscher_data *data, char *buf, int nr)
624{
625 /* bits 0..3 reserved, bit 5 write only => mask with 0xd0 */
626 return sprintf(buf, "%u\n", data->watchdog[2] & 0xd0);
627}
628
629static ssize_t set_watchdog_status(struct i2c_client *client, struct fscher_data *data,
630 const char *buf, size_t count, int nr, int reg)
631{
632 /* bits 0, 2..7 reserved => mask with 0x02 */
633 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
634
635 mutex_lock(&data->update_lock);
636 data->watchdog[1] &= ~v;
637 fscher_write_value(client, reg, v);
638 mutex_unlock(&data->update_lock);
639 return count;
640}
641
642static ssize_t show_watchdog_status(struct fscher_data *data, char *buf, int nr)
643{
644 /* bits 0, 2..7 reserved => mask with 0x02 */
645 return sprintf(buf, "%u\n", data->watchdog[1] & 0x02);
646}
647
648static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data *data,
649 const char *buf, size_t count, int nr, int reg)
650{
651 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
652
653 mutex_lock(&data->update_lock);
654 data->watchdog[0] = v;
655 fscher_write_value(client, reg, data->watchdog[0]);
656 mutex_unlock(&data->update_lock);
657 return count;
658}
659
660static ssize_t show_watchdog_preset(struct fscher_data *data, char *buf, int nr)
661{
662 return sprintf(buf, "%u\n", data->watchdog[0]);
663}
664
665static int __init sensors_fscher_init(void)
666{
667 return i2c_add_driver(&fscher_driver);
668}
669
670static void __exit sensors_fscher_exit(void)
671{
672 i2c_del_driver(&fscher_driver);
673}
674
675MODULE_AUTHOR("Reinhard Nissl <rnissl@gmx.de>");
676MODULE_DESCRIPTION("FSC Hermes driver");
677MODULE_LICENSE("GPL");
678
679module_init(sensors_fscher_init);
680module_exit(sensors_fscher_exit);
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
deleted file mode 100644
index 8a7bcf500b4e..000000000000
--- a/drivers/hwmon/fscpos.c
+++ /dev/null
@@ -1,654 +0,0 @@
1/*
2 fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips
3 Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20/*
21 fujitsu siemens poseidon chip,
22 module based on the old fscpos module by Hermann Jung <hej@odn.de> and
23 the fscher module by Reinhard Nissl <rnissl@gmx.de>
24
25 original module based on lm80.c
26 Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
27 and Philip Edelbrock <phil@netroedge.com>
28
29 Thanks to Jean Delvare for reviewing my code and suggesting a lot of
30 improvements.
31*/
32
33#include <linux/module.h>
34#include <linux/slab.h>
35#include <linux/jiffies.h>
36#include <linux/i2c.h>
37#include <linux/init.h>
38#include <linux/hwmon.h>
39#include <linux/err.h>
40#include <linux/mutex.h>
41#include <linux/sysfs.h>
42
43/*
44 * Addresses to scan
45 */
46static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
47
48/*
49 * Insmod parameters
50 */
51I2C_CLIENT_INSMOD_1(fscpos);
52
53/*
54 * The FSCPOS registers
55 */
56
57/* chip identification */
58#define FSCPOS_REG_IDENT_0 0x00
59#define FSCPOS_REG_IDENT_1 0x01
60#define FSCPOS_REG_IDENT_2 0x02
61#define FSCPOS_REG_REVISION 0x03
62
63/* global control and status */
64#define FSCPOS_REG_EVENT_STATE 0x04
65#define FSCPOS_REG_CONTROL 0x05
66
67/* watchdog */
68#define FSCPOS_REG_WDOG_PRESET 0x28
69#define FSCPOS_REG_WDOG_STATE 0x23
70#define FSCPOS_REG_WDOG_CONTROL 0x21
71
72/* voltages */
73#define FSCPOS_REG_VOLT_12 0x45
74#define FSCPOS_REG_VOLT_5 0x42
75#define FSCPOS_REG_VOLT_BATT 0x48
76
77/* fans - the chip does not support minimum speed for fan2 */
78static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 };
79static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab };
80static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 };
81static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf };
82
83/* temperatures */
84static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 };
85static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
86
87/*
88 * Functions declaration
89 */
90static int fscpos_probe(struct i2c_client *client,
91 const struct i2c_device_id *id);
92static int fscpos_detect(struct i2c_client *client, int kind,
93 struct i2c_board_info *info);
94static int fscpos_remove(struct i2c_client *client);
95
96static int fscpos_read_value(struct i2c_client *client, u8 reg);
97static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value);
98static struct fscpos_data *fscpos_update_device(struct device *dev);
99static void fscpos_init_client(struct i2c_client *client);
100
101static void reset_fan_alarm(struct i2c_client *client, int nr);
102
103/*
104 * Driver data (common to all clients)
105 */
106static const struct i2c_device_id fscpos_id[] = {
107 { "fscpos", fscpos },
108 { }
109};
110
111static struct i2c_driver fscpos_driver = {
112 .class = I2C_CLASS_HWMON,
113 .driver = {
114 .name = "fscpos",
115 },
116 .probe = fscpos_probe,
117 .remove = fscpos_remove,
118 .id_table = fscpos_id,
119 .detect = fscpos_detect,
120 .address_data = &addr_data,
121};
122
123/*
124 * Client data (each client gets its own)
125 */
126struct fscpos_data {
127 struct device *hwmon_dev;
128 struct mutex update_lock;
129 char valid; /* 0 until following fields are valid */
130 unsigned long last_updated; /* In jiffies */
131
132 /* register values */
133 u8 revision; /* revision of chip */
134 u8 global_event; /* global event status */
135 u8 global_control; /* global control register */
136 u8 wdog_control; /* watchdog control */
137 u8 wdog_state; /* watchdog status */
138 u8 wdog_preset; /* watchdog preset */
139 u8 volt[3]; /* 12, 5, battery current */
140 u8 temp_act[3]; /* temperature */
141 u8 temp_status[3]; /* status of sensor */
142 u8 fan_act[3]; /* fans revolutions per second */
143 u8 fan_status[3]; /* fan status */
144 u8 pwm[2]; /* fan min value for rps */
145 u8 fan_ripple[3]; /* divider for rps */
146};
147
148/* Temperature */
149#define TEMP_FROM_REG(val) (((val) - 128) * 1000)
150
151static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr)
152{
153 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1]));
154}
155
156static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr)
157{
158 /* bits 2..7 reserved => mask with 0x03 */
159 return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03);
160}
161
162static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr)
163{
164 return sprintf(buf, "1\n");
165}
166
167static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data
168 *data, const char *buf, size_t count, int nr, int reg)
169{
170 unsigned long v = simple_strtoul(buf, NULL, 10);
171 if (v != 1) {
172 dev_err(&client->dev, "temp_reset value %ld not supported. "
173 "Use 1 to reset the alarm!\n", v);
174 return -EINVAL;
175 }
176
177 dev_info(&client->dev, "You used the temp_reset feature which has not "
178 "been proplerly tested. Please report your "
179 "experience to the module author.\n");
180
181 /* Supported value: 2 (clears the status) */
182 fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2);
183 return count;
184}
185
186/* Fans */
187#define RPM_FROM_REG(val) ((val) * 60)
188
189static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr)
190{
191 /* bits 0..1, 3..7 reserved => mask with 0x04 */
192 return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04);
193}
194
195static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr)
196{
197 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1]));
198}
199
200static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr)
201{
202 /* bits 2..7 reserved => mask with 0x03 */
203 return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03);
204}
205
206static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
207 *data, const char *buf, size_t count, int nr, int reg)
208{
209 /* supported values: 2, 4, 8 */
210 unsigned long v = simple_strtoul(buf, NULL, 10);
211
212 switch (v) {
213 case 2: v = 1; break;
214 case 4: v = 2; break;
215 case 8: v = 3; break;
216 default:
217 dev_err(&client->dev, "fan_ripple value %ld not supported. "
218 "Must be one of 2, 4 or 8!\n", v);
219 return -EINVAL;
220 }
221
222 mutex_lock(&data->update_lock);
223 /* bits 2..7 reserved => mask with 0x03 */
224 data->fan_ripple[nr - 1] &= ~0x03;
225 data->fan_ripple[nr - 1] |= v;
226
227 fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
228 mutex_unlock(&data->update_lock);
229 return count;
230}
231
232static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr)
233{
234 return sprintf(buf, "%u\n", data->pwm[nr - 1]);
235}
236
237static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
238 const char *buf, size_t count, int nr, int reg)
239{
240 unsigned long v = simple_strtoul(buf, NULL, 10);
241
242 /* Range: 0..255 */
243 if (v < 0) v = 0;
244 if (v > 255) v = 255;
245
246 mutex_lock(&data->update_lock);
247 data->pwm[nr - 1] = v;
248 fscpos_write_value(client, reg, data->pwm[nr - 1]);
249 mutex_unlock(&data->update_lock);
250 return count;
251}
252
253static void reset_fan_alarm(struct i2c_client *client, int nr)
254{
255 fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4);
256}
257
258/* Volts */
259#define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255)
260
261static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf)
262{
263 struct fscpos_data *data = fscpos_update_device(dev);
264 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200));
265}
266
267static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf)
268{
269 struct fscpos_data *data = fscpos_update_device(dev);
270 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600));
271}
272
273static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf)
274{
275 struct fscpos_data *data = fscpos_update_device(dev);
276 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300));
277}
278
279/* Watchdog */
280static ssize_t show_wdog_control(struct fscpos_data *data, char *buf)
281{
282 /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
283 return sprintf(buf, "%u\n", data->wdog_control & 0xb0);
284}
285
286static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
287 *data, const char *buf, size_t count, int reg)
288{
289 /* bits 0..3 reserved => mask with 0xf0 */
290 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
291
292 mutex_lock(&data->update_lock);
293 data->wdog_control &= ~0xf0;
294 data->wdog_control |= v;
295 fscpos_write_value(client, reg, data->wdog_control);
296 mutex_unlock(&data->update_lock);
297 return count;
298}
299
300static ssize_t show_wdog_state(struct fscpos_data *data, char *buf)
301{
302 /* bits 0, 2..7 reserved => mask with 0x02 */
303 return sprintf(buf, "%u\n", data->wdog_state & 0x02);
304}
305
306static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
307 *data, const char *buf, size_t count, int reg)
308{
309 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
310
311 /* Valid values: 2 (clear) */
312 if (v != 2) {
313 dev_err(&client->dev, "wdog_state value %ld not supported. "
314 "Must be 2 to clear the state!\n", v);
315 return -EINVAL;
316 }
317
318 mutex_lock(&data->update_lock);
319 data->wdog_state &= ~v;
320 fscpos_write_value(client, reg, v);
321 mutex_unlock(&data->update_lock);
322 return count;
323}
324
325static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf)
326{
327 return sprintf(buf, "%u\n", data->wdog_preset);
328}
329
330static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
331 *data, const char *buf, size_t count, int reg)
332{
333 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
334
335 mutex_lock(&data->update_lock);
336 data->wdog_preset = v;
337 fscpos_write_value(client, reg, data->wdog_preset);
338 mutex_unlock(&data->update_lock);
339 return count;
340}
341
342/* Event */
343static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf)
344{
345 /* bits 5..7 reserved => mask with 0x1f */
346 struct fscpos_data *data = fscpos_update_device(dev);
347 return sprintf(buf, "%u\n", data->global_event & 0x9b);
348}
349
350/*
351 * Sysfs stuff
352 */
353#define create_getter(kind, sub) \
354 static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
355 { \
356 struct fscpos_data *data = fscpos_update_device(dev); \
357 return show_##kind##sub(data, buf); \
358 }
359
360#define create_getter_n(kind, offset, sub) \
361 static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
362 *buf) \
363 { \
364 struct fscpos_data *data = fscpos_update_device(dev); \
365 return show_##kind##sub(data, buf, offset); \
366 }
367
368#define create_setter(kind, sub, reg) \
369 static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
370 *buf, size_t count) \
371 { \
372 struct i2c_client *client = to_i2c_client(dev); \
373 struct fscpos_data *data = i2c_get_clientdata(client); \
374 return set_##kind##sub(client, data, buf, count, reg); \
375 }
376
377#define create_setter_n(kind, offset, sub, reg) \
378 static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
379 const char *buf, size_t count) \
380 { \
381 struct i2c_client *client = to_i2c_client(dev); \
382 struct fscpos_data *data = i2c_get_clientdata(client); \
383 return set_##kind##sub(client, data, buf, count, offset, reg);\
384 }
385
386#define create_sysfs_device_ro(kind, sub, offset) \
387 static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
388 sysfs_show_##kind##offset##sub, NULL);
389
390#define create_sysfs_device_rw(kind, sub, offset) \
391 static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
392 sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
393
394#define sysfs_ro_n(kind, sub, offset) \
395 create_getter_n(kind, offset, sub); \
396 create_sysfs_device_ro(kind, sub, offset);
397
398#define sysfs_rw_n(kind, sub, offset, reg) \
399 create_getter_n(kind, offset, sub); \
400 create_setter_n(kind, offset, sub, reg); \
401 create_sysfs_device_rw(kind, sub, offset);
402
403#define sysfs_rw(kind, sub, reg) \
404 create_getter(kind, sub); \
405 create_setter(kind, sub, reg); \
406 create_sysfs_device_rw(kind, sub,);
407
408#define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
409 sysfs_fan(offset, reg_status, reg_ripple); \
410 sysfs_rw_n(pwm,, offset, reg_min);
411
412#define sysfs_fan(offset, reg_status, reg_ripple) \
413 sysfs_ro_n(fan, _input, offset); \
414 sysfs_ro_n(fan, _status, offset); \
415 sysfs_rw_n(fan, _ripple, offset, reg_ripple);
416
417#define sysfs_temp(offset, reg_status) \
418 sysfs_ro_n(temp, _input, offset); \
419 sysfs_ro_n(temp, _status, offset); \
420 sysfs_rw_n(temp, _reset, offset, reg_status);
421
422#define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
423 sysfs_rw(wdog, _control, reg_wdog_control); \
424 sysfs_rw(wdog, _preset, reg_wdog_preset); \
425 sysfs_rw(wdog, _state, reg_wdog_state);
426
427sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0],
428 FSCPOS_REG_PWM[0]);
429sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1],
430 FSCPOS_REG_PWM[1]);
431sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]);
432
433sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]);
434sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]);
435sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]);
436
437sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE,
438 FSCPOS_REG_WDOG_CONTROL);
439
440static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
441static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL);
442static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL);
443static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL);
444
445static struct attribute *fscpos_attributes[] = {
446 &dev_attr_event.attr,
447 &dev_attr_in0_input.attr,
448 &dev_attr_in1_input.attr,
449 &dev_attr_in2_input.attr,
450
451 &dev_attr_wdog_control.attr,
452 &dev_attr_wdog_preset.attr,
453 &dev_attr_wdog_state.attr,
454
455 &dev_attr_temp1_input.attr,
456 &dev_attr_temp1_status.attr,
457 &dev_attr_temp1_reset.attr,
458 &dev_attr_temp2_input.attr,
459 &dev_attr_temp2_status.attr,
460 &dev_attr_temp2_reset.attr,
461 &dev_attr_temp3_input.attr,
462 &dev_attr_temp3_status.attr,
463 &dev_attr_temp3_reset.attr,
464
465 &dev_attr_fan1_input.attr,
466 &dev_attr_fan1_status.attr,
467 &dev_attr_fan1_ripple.attr,
468 &dev_attr_pwm1.attr,
469 &dev_attr_fan2_input.attr,
470 &dev_attr_fan2_status.attr,
471 &dev_attr_fan2_ripple.attr,
472 &dev_attr_pwm2.attr,
473 &dev_attr_fan3_input.attr,
474 &dev_attr_fan3_status.attr,
475 &dev_attr_fan3_ripple.attr,
476 NULL
477};
478
479static const struct attribute_group fscpos_group = {
480 .attrs = fscpos_attributes,
481};
482
483/* Return 0 if detection is successful, -ENODEV otherwise */
484static int fscpos_detect(struct i2c_client *new_client, int kind,
485 struct i2c_board_info *info)
486{
487 struct i2c_adapter *adapter = new_client->adapter;
488
489 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
490 return -ENODEV;
491
492 /* Do the remaining detection unless force or force_fscpos parameter */
493 if (kind < 0) {
494 if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0)
495 != 0x50) /* 'P' */
496 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1)
497 != 0x45) /* 'E' */
498 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
499 != 0x47))/* 'G' */
500 return -ENODEV;
501 }
502
503 strlcpy(info->type, "fscpos", I2C_NAME_SIZE);
504
505 return 0;
506}
507
508static int fscpos_probe(struct i2c_client *new_client,
509 const struct i2c_device_id *id)
510{
511 struct fscpos_data *data;
512 int err;
513
514 data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL);
515 if (!data) {
516 err = -ENOMEM;
517 goto exit;
518 }
519
520 i2c_set_clientdata(new_client, data);
521 data->valid = 0;
522 mutex_init(&data->update_lock);
523
524 /* Inizialize the fscpos chip */
525 fscpos_init_client(new_client);
526
527 /* Announce that the chip was found */
528 dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
529
530 /* Register sysfs hooks */
531 if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group)))
532 goto exit_free;
533
534 data->hwmon_dev = hwmon_device_register(&new_client->dev);
535 if (IS_ERR(data->hwmon_dev)) {
536 err = PTR_ERR(data->hwmon_dev);
537 goto exit_remove_files;
538 }
539
540 return 0;
541
542exit_remove_files:
543 sysfs_remove_group(&new_client->dev.kobj, &fscpos_group);
544exit_free:
545 kfree(data);
546exit:
547 return err;
548}
549
550static int fscpos_remove(struct i2c_client *client)
551{
552 struct fscpos_data *data = i2c_get_clientdata(client);
553
554 hwmon_device_unregister(data->hwmon_dev);
555 sysfs_remove_group(&client->dev.kobj, &fscpos_group);
556
557 kfree(data);
558 return 0;
559}
560
561static int fscpos_read_value(struct i2c_client *client, u8 reg)
562{
563 dev_dbg(&client->dev, "Read reg 0x%02x\n", reg);
564 return i2c_smbus_read_byte_data(client, reg);
565}
566
567static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value)
568{
569 dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value);
570 return i2c_smbus_write_byte_data(client, reg, value);
571}
572
573/* Called when we have found a new FSCPOS chip */
574static void fscpos_init_client(struct i2c_client *client)
575{
576 struct fscpos_data *data = i2c_get_clientdata(client);
577
578 /* read revision from chip */
579 data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION);
580}
581
582static struct fscpos_data *fscpos_update_device(struct device *dev)
583{
584 struct i2c_client *client = to_i2c_client(dev);
585 struct fscpos_data *data = i2c_get_clientdata(client);
586
587 mutex_lock(&data->update_lock);
588
589 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
590 int i;
591
592 dev_dbg(&client->dev, "Starting fscpos update\n");
593
594 for (i = 0; i < 3; i++) {
595 data->temp_act[i] = fscpos_read_value(client,
596 FSCPOS_REG_TEMP_ACT[i]);
597 data->temp_status[i] = fscpos_read_value(client,
598 FSCPOS_REG_TEMP_STATE[i]);
599 data->fan_act[i] = fscpos_read_value(client,
600 FSCPOS_REG_FAN_ACT[i]);
601 data->fan_status[i] = fscpos_read_value(client,
602 FSCPOS_REG_FAN_STATE[i]);
603 data->fan_ripple[i] = fscpos_read_value(client,
604 FSCPOS_REG_FAN_RIPPLE[i]);
605 if (i < 2) {
606 /* fan2_min is not supported by the chip */
607 data->pwm[i] = fscpos_read_value(client,
608 FSCPOS_REG_PWM[i]);
609 }
610 /* reset fan status if speed is back to > 0 */
611 if (data->fan_status[i] != 0 && data->fan_act[i] > 0) {
612 reset_fan_alarm(client, i);
613 }
614 }
615
616 data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12);
617 data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5);
618 data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT);
619
620 data->wdog_preset = fscpos_read_value(client,
621 FSCPOS_REG_WDOG_PRESET);
622 data->wdog_state = fscpos_read_value(client,
623 FSCPOS_REG_WDOG_STATE);
624 data->wdog_control = fscpos_read_value(client,
625 FSCPOS_REG_WDOG_CONTROL);
626
627 data->global_event = fscpos_read_value(client,
628 FSCPOS_REG_EVENT_STATE);
629
630 data->last_updated = jiffies;
631 data->valid = 1;
632 }
633 mutex_unlock(&data->update_lock);
634 return data;
635}
636
637static int __init sm_fscpos_init(void)
638{
639 return i2c_add_driver(&fscpos_driver);
640}
641
642static void __exit sm_fscpos_exit(void)
643{
644 i2c_del_driver(&fscpos_driver);
645}
646
647MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
648 "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
649 " and Philip Edelbrock <phil@netroedge.com>");
650MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
651MODULE_LICENSE("GPL");
652
653module_init(sm_fscpos_init);
654module_exit(sm_fscpos_exit);
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 9386e2a39211..6c9a04136e0a 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -259,7 +259,7 @@ static int ltc4215_probe(struct i2c_client *client,
259 mutex_init(&data->update_lock); 259 mutex_init(&data->update_lock);
260 260
261 /* Initialize the LTC4215 chip */ 261 /* Initialize the LTC4215 chip */
262 /* TODO */ 262 i2c_smbus_write_byte_data(client, LTC4215_FAULT, 0x00);
263 263
264 /* Register sysfs hooks */ 264 /* Register sysfs hooks */
265 ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group); 265 ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group);
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index 034b2c515848..e38964333612 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -382,7 +382,8 @@ static int ltc4245_probe(struct i2c_client *client,
382 mutex_init(&data->update_lock); 382 mutex_init(&data->update_lock);
383 383
384 /* Initialize the LTC4245 chip */ 384 /* Initialize the LTC4245 chip */
385 /* TODO */ 385 i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00);
386 i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00);
386 387
387 /* Register sysfs hooks */ 388 /* Register sysfs hooks */
388 ret = sysfs_create_group(&client->dev.kobj, &ltc4245_group); 389 ret = sysfs_create_group(&client->dev.kobj, &ltc4245_group);