aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig47
-rw-r--r--drivers/hwmon/Makefile3
-rw-r--r--drivers/hwmon/asb100.c5
-rw-r--r--drivers/hwmon/dme1737.c5
-rw-r--r--drivers/hwmon/f71805f.c5
-rw-r--r--drivers/hwmon/f71882fg.c1549
-rw-r--r--drivers/hwmon/fschmd.c450
-rw-r--r--drivers/hwmon/hp_accel.c265
-rw-r--r--drivers/hwmon/i5k_amb.c7
-rw-r--r--drivers/hwmon/it87.c37
-rw-r--r--drivers/hwmon/lis3lv02d.c273
-rw-r--r--drivers/hwmon/lis3lv02d.h35
-rw-r--r--drivers/hwmon/lm70.c91
-rw-r--r--drivers/hwmon/ltc4245.c567
-rw-r--r--drivers/hwmon/pc87360.c6
-rw-r--r--drivers/hwmon/pc87427.c5
-rw-r--r--drivers/hwmon/sis5595.c5
-rw-r--r--drivers/hwmon/smsc47b397.c5
-rw-r--r--drivers/hwmon/smsc47m1.c5
-rw-r--r--drivers/hwmon/via686a.c5
-rw-r--r--drivers/hwmon/vt1211.c5
-rw-r--r--drivers/hwmon/vt8231.c5
-rw-r--r--drivers/hwmon/w83627ehf.c8
-rw-r--r--drivers/hwmon/w83627hf.c5
-rw-r--r--drivers/hwmon/w83781d.c5
-rw-r--r--drivers/hwmon/w83791d.c5
-rw-r--r--drivers/hwmon/w83792d.c5
-rw-r--r--drivers/hwmon/w83793.c5
28 files changed, 2830 insertions, 583 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c709e821f04b..4b33bc82cc24 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -284,11 +284,12 @@ config SENSORS_F71805F
284 will be called f71805f. 284 will be called f71805f.
285 285
286config SENSORS_F71882FG 286config SENSORS_F71882FG
287 tristate "Fintek F71882FG and F71883FG" 287 tristate "Fintek F71862FG, F71882FG and F8000"
288 depends on EXPERIMENTAL 288 depends on EXPERIMENTAL
289 help 289 help
290 If you say yes here you get support for hardware monitoring 290 If you say yes here you get support for hardware monitoring
291 features of the Fintek F71882FG and F71883FG Super-I/O chips. 291 features of the Fintek F71882FG/F71883FG, F71862FG/71863FG
292 and F8000 Super-I/O chips.
292 293
293 This driver can also be built as a module. If so, the module 294 This driver can also be built as a module. If so, the module
294 will be called f71882fg. 295 will be called f71882fg.
@@ -304,9 +305,13 @@ config SENSORS_F75375S
304 will be called f75375s. 305 will be called f75375s.
305 306
306config SENSORS_FSCHER 307config SENSORS_FSCHER
307 tristate "FSC Hermes" 308 tristate "FSC Hermes (DEPRECATED)"
308 depends on X86 && I2C 309 depends on X86 && I2C
309 help 310 help
311 This driver is DEPRECATED please use the new merged fschmd
312 ("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver
313 instead.
314
310 If you say yes here you get support for Fujitsu Siemens 315 If you say yes here you get support for Fujitsu Siemens
311 Computers Hermes sensor chips. 316 Computers Hermes sensor chips.
312 317
@@ -314,9 +319,13 @@ config SENSORS_FSCHER
314 will be called fscher. 319 will be called fscher.
315 320
316config SENSORS_FSCPOS 321config SENSORS_FSCPOS
317 tristate "FSC Poseidon" 322 tristate "FSC Poseidon (DEPRECATED)"
318 depends on X86 && I2C 323 depends on X86 && I2C
319 help 324 help
325 This driver is DEPRECATED please use the new merged fschmd
326 ("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver
327 instead.
328
320 If you say yes here you get support for Fujitsu Siemens 329 If you say yes here you get support for Fujitsu Siemens
321 Computers Poseidon sensor chips. 330 Computers Poseidon sensor chips.
322 331
@@ -325,14 +334,15 @@ config SENSORS_FSCPOS
325 334
326config SENSORS_FSCHMD 335config SENSORS_FSCHMD
327 tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles" 336 tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
328 depends on X86 && I2C && EXPERIMENTAL 337 depends on X86 && I2C
329 help 338 help
330 If you say yes here you get support for various Fujitsu Siemens 339 If you say yes here you get support for various Fujitsu Siemens
331 Computers sensor chips. 340 Computers sensor chips, including support for the integrated
341 watchdog.
332 342
333 This is a new merged driver for FSC sensor chips which is intended 343 This is a merged driver for FSC sensor chips replacing the fscpos,
334 as a replacment for the fscpos, fscscy and fscher drivers and adds 344 fscscy and fscher drivers and adding support for several other FSC
335 support for several other FCS sensor chips. 345 sensor chips.
336 346
337 This driver can also be built as a module. If so, the module 347 This driver can also be built as a module. If so, the module
338 will be called fschmd. 348 will be called fschmd.
@@ -399,7 +409,8 @@ config SENSORS_IT87
399 select HWMON_VID 409 select HWMON_VID
400 help 410 help
401 If you say yes here you get support for ITE IT8705F, IT8712F, 411 If you say yes here you get support for ITE IT8705F, IT8712F,
402 IT8716F, IT8718F and IT8726F sensor chips, and the SiS960 clone. 412 IT8716F, IT8718F, IT8720F and IT8726F sensor chips, and the
413 SiS960 clone.
403 414
404 This driver can also be built as a module. If so, the module 415 This driver can also be built as a module. If so, the module
405 will be called it87. 416 will be called it87.
@@ -417,11 +428,12 @@ config SENSORS_LM63
417 will be called lm63. 428 will be called lm63.
418 429
419config SENSORS_LM70 430config SENSORS_LM70
420 tristate "National Semiconductor LM70" 431 tristate "National Semiconductor LM70 / Texas Instruments TMP121"
421 depends on SPI_MASTER && EXPERIMENTAL 432 depends on SPI_MASTER && EXPERIMENTAL
422 help 433 help
423 If you say yes here you get support for the National Semiconductor 434 If you say yes here you get support for the National Semiconductor
424 LM70 digital temperature sensor chip. 435 LM70 and Texas Instruments TMP121/TMP123 digital temperature
436 sensor chips.
425 437
426 This driver can also be built as a module. If so, the module 438 This driver can also be built as a module. If so, the module
427 will be called lm70. 439 will be called lm70.
@@ -548,6 +560,17 @@ config SENSORS_LM93
548 This driver can also be built as a module. If so, the module 560 This driver can also be built as a module. If so, the module
549 will be called lm93. 561 will be called lm93.
550 562
563config SENSORS_LTC4245
564 tristate "Linear Technology LTC4245"
565 depends on I2C && EXPERIMENTAL
566 default n
567 help
568 If you say yes here you get support for Linear Technology LTC4245
569 Multiple Supply Hot Swap Controller I2C interface.
570
571 This driver can also be built as a module. If so, the module will
572 be called ltc4245.
573
551config SENSORS_MAX1111 574config SENSORS_MAX1111
552 tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" 575 tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
553 depends on SPI_MASTER 576 depends on SPI_MASTER
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 58fc5be5355d..19cb1ace3eb4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -49,7 +49,7 @@ obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
49obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o 49obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
50obj-$(CONFIG_SENSORS_IT87) += it87.o 50obj-$(CONFIG_SENSORS_IT87) += it87.o
51obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o 51obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
52obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o 52obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
53obj-$(CONFIG_SENSORS_LM63) += lm63.o 53obj-$(CONFIG_SENSORS_LM63) += lm63.o
54obj-$(CONFIG_SENSORS_LM70) += lm70.o 54obj-$(CONFIG_SENSORS_LM70) += lm70.o
55obj-$(CONFIG_SENSORS_LM75) += lm75.o 55obj-$(CONFIG_SENSORS_LM75) += lm75.o
@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o
62obj-$(CONFIG_SENSORS_LM90) += lm90.o 62obj-$(CONFIG_SENSORS_LM90) += lm90.o
63obj-$(CONFIG_SENSORS_LM92) += lm92.o 63obj-$(CONFIG_SENSORS_LM92) += lm92.o
64obj-$(CONFIG_SENSORS_LM93) += lm93.o 64obj-$(CONFIG_SENSORS_LM93) += lm93.o
65obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
65obj-$(CONFIG_SENSORS_MAX1111) += max1111.o 66obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
66obj-$(CONFIG_SENSORS_MAX1619) += max1619.o 67obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
67obj-$(CONFIG_SENSORS_MAX6650) += max6650.o 68obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 8a45a2e6ba8a..8acf82977e7b 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -53,7 +53,10 @@ static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
53 53
54/* Insmod parameters */ 54/* Insmod parameters */
55I2C_CLIENT_INSMOD_1(asb100); 55I2C_CLIENT_INSMOD_1(asb100);
56I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " 56
57static unsigned short force_subclients[4];
58module_param_array(force_subclients, short, NULL, 0);
59MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
57 "{bus, clientaddr, subclientaddr1, subclientaddr2}"); 60 "{bus, clientaddr, subclientaddr1, subclientaddr2}");
58 61
59/* Voltage IN registers 0-6 */ 62/* Voltage IN registers 0-6 */
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 27a5d397f9a1..3df202a9ad72 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -34,6 +34,7 @@
34#include <linux/hwmon-vid.h> 34#include <linux/hwmon-vid.h>
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/acpi.h>
37#include <asm/io.h> 38#include <asm/io.h>
38 39
39/* ISA device, if found */ 40/* ISA device, if found */
@@ -2361,6 +2362,10 @@ static int __init dme1737_isa_device_add(unsigned short addr)
2361 }; 2362 };
2362 int err; 2363 int err;
2363 2364
2365 err = acpi_check_resource_conflict(&res);
2366 if (err)
2367 goto exit;
2368
2364 if (!(pdev = platform_device_alloc("dme1737", addr))) { 2369 if (!(pdev = platform_device_alloc("dme1737", addr))) {
2365 printk(KERN_ERR "dme1737: Failed to allocate device.\n"); 2370 printk(KERN_ERR "dme1737: Failed to allocate device.\n");
2366 err = -ENOMEM; 2371 err = -ENOMEM;
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 7a14a2dbb752..899876579253 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -39,6 +39,7 @@
39#include <linux/mutex.h> 39#include <linux/mutex.h>
40#include <linux/sysfs.h> 40#include <linux/sysfs.h>
41#include <linux/ioport.h> 41#include <linux/ioport.h>
42#include <linux/acpi.h>
42#include <asm/io.h> 43#include <asm/io.h>
43 44
44static unsigned short force_id; 45static unsigned short force_id;
@@ -1455,6 +1456,10 @@ static int __init f71805f_device_add(unsigned short address,
1455 } 1456 }
1456 1457
1457 res.name = pdev->name; 1458 res.name = pdev->name;
1459 err = acpi_check_resource_conflict(&res);
1460 if (err)
1461 goto exit_device_put;
1462
1458 err = platform_device_add_resources(pdev, &res, 1); 1463 err = platform_device_add_resources(pdev, &res, 1);
1459 if (err) { 1464 if (err) {
1460 printk(KERN_ERR DRVNAME ": Device resource addition failed " 1465 printk(KERN_ERR DRVNAME ": Device resource addition failed "
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 67067e9a323e..609cafff86bc 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -1,6 +1,6 @@
1/*************************************************************************** 1/***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007 by Hans de Goede <j.w.r.degoede@hhs.nl> * 3 * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> *
4 * * 4 * *
5 * This program is free software; you can redistribute it and/or modify * 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 * 6 * it under the terms of the GNU General Public License as published by *
@@ -27,11 +27,12 @@
27#include <linux/hwmon-sysfs.h> 27#include <linux/hwmon-sysfs.h>
28#include <linux/err.h> 28#include <linux/err.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <asm/io.h> 30#include <linux/io.h>
31#include <linux/acpi.h>
31 32
32#define DRVNAME "f71882fg" 33#define DRVNAME "f71882fg"
33 34
34#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device*/ 35#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
35#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 36#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
36#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ 37#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
37 38
@@ -43,7 +44,9 @@
43#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 44#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
44 45
45#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 46#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
47#define SIO_F71862_ID 0x0601 /* Chipset ID */
46#define SIO_F71882_ID 0x0541 /* Chipset ID */ 48#define SIO_F71882_ID 0x0541 /* Chipset ID */
49#define SIO_F8000_ID 0x0581 /* Chipset ID */
47 50
48#define REGION_LENGTH 8 51#define REGION_LENGTH 8
49#define ADDR_REG_OFFSET 5 52#define ADDR_REG_OFFSET 5
@@ -51,25 +54,36 @@
51 54
52#define F71882FG_REG_PECI 0x0A 55#define F71882FG_REG_PECI 0x0A
53 56
54#define F71882FG_REG_IN_STATUS 0x12 57#define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
55#define F71882FG_REG_IN_BEEP 0x13 58#define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
56#define F71882FG_REG_IN(nr) (0x20 + (nr)) 59#define F71882FG_REG_IN(nr) (0x20 + (nr))
57#define F71882FG_REG_IN1_HIGH 0x32 60#define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
58 61
59#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) 62#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
63#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
64#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
60#define F71882FG_REG_FAN_STATUS 0x92 65#define F71882FG_REG_FAN_STATUS 0x92
61#define F71882FG_REG_FAN_BEEP 0x93 66#define F71882FG_REG_FAN_BEEP 0x93
62 67
63#define F71882FG_REG_TEMP(nr) (0x72 + 2 * (nr)) 68#define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
64#define F71882FG_REG_TEMP_OVT(nr) (0x82 + 2 * (nr)) 69#define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
65#define F71882FG_REG_TEMP_HIGH(nr) (0x83 + 2 * (nr)) 70#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
66#define F71882FG_REG_TEMP_STATUS 0x62 71#define F71882FG_REG_TEMP_STATUS 0x62
67#define F71882FG_REG_TEMP_BEEP 0x63 72#define F71882FG_REG_TEMP_BEEP 0x63
68#define F71882FG_REG_TEMP_HYST1 0x6C 73#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
69#define F71882FG_REG_TEMP_HYST23 0x6D
70#define F71882FG_REG_TEMP_TYPE 0x6B 74#define F71882FG_REG_TEMP_TYPE 0x6B
71#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F 75#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
72 76
77#define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
78#define F71882FG_REG_PWM_TYPE 0x94
79#define F71882FG_REG_PWM_ENABLE 0x96
80
81#define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
82
83#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
84#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
85#define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
86
73#define F71882FG_REG_START 0x01 87#define F71882FG_REG_START 0x01
74 88
75#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ 89#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
@@ -78,7 +92,15 @@ static unsigned short force_id;
78module_param(force_id, ushort, 0); 92module_param(force_id, ushort, 0);
79MODULE_PARM_DESC(force_id, "Override the detected device ID"); 93MODULE_PARM_DESC(force_id, "Override the detected device ID");
80 94
81static struct platform_device *f71882fg_pdev = NULL; 95enum chips { f71862fg, f71882fg, f8000 };
96
97static const char *f71882fg_names[] = {
98 "f71862fg",
99 "f71882fg",
100 "f8000",
101};
102
103static struct platform_device *f71882fg_pdev;
82 104
83/* Super-I/O Function prototypes */ 105/* Super-I/O Function prototypes */
84static inline int superio_inb(int base, int reg); 106static inline int superio_inb(int base, int reg);
@@ -87,8 +109,13 @@ static inline void superio_enter(int base);
87static inline void superio_select(int base, int ld); 109static inline void superio_select(int base, int ld);
88static inline void superio_exit(int base); 110static inline void superio_exit(int base);
89 111
112struct f71882fg_sio_data {
113 enum chips type;
114};
115
90struct f71882fg_data { 116struct f71882fg_data {
91 unsigned short addr; 117 unsigned short addr;
118 enum chips type;
92 struct device *hwmon_dev; 119 struct device *hwmon_dev;
93 120
94 struct mutex update_lock; 121 struct mutex update_lock;
@@ -102,19 +129,30 @@ struct f71882fg_data {
102 u8 in_status; 129 u8 in_status;
103 u8 in_beep; 130 u8 in_beep;
104 u16 fan[4]; 131 u16 fan[4];
132 u16 fan_target[4];
133 u16 fan_full_speed[4];
105 u8 fan_status; 134 u8 fan_status;
106 u8 fan_beep; 135 u8 fan_beep;
107 u8 temp[3]; 136 /* Note: all models have only 3 temperature channels, but on some
108 u8 temp_ovt[3]; 137 they are addressed as 0-2 and on others as 1-3, so for coding
109 u8 temp_high[3]; 138 convenience we reserve space for 4 channels */
110 u8 temp_hyst[3]; 139 u8 temp[4];
111 u8 temp_type[3]; 140 u8 temp_ovt[4];
141 u8 temp_high[4];
142 u8 temp_hyst[2]; /* 2 hysts stored per reg */
143 u8 temp_type[4];
112 u8 temp_status; 144 u8 temp_status;
113 u8 temp_beep; 145 u8 temp_beep;
114 u8 temp_diode_open; 146 u8 temp_diode_open;
147 u8 pwm[4];
148 u8 pwm_enable;
149 u8 pwm_auto_point_hyst[2];
150 u8 pwm_auto_point_mapping[4];
151 u8 pwm_auto_point_pwm[4][5];
152 u8 pwm_auto_point_temp[4][4];
115}; 153};
116 154
117/* Sysfs in*/ 155/* Sysfs in */
118static ssize_t show_in(struct device *dev, struct device_attribute *devattr, 156static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
119 char *buf); 157 char *buf);
120static ssize_t show_in_max(struct device *dev, struct device_attribute 158static ssize_t show_in_max(struct device *dev, struct device_attribute
@@ -130,6 +168,10 @@ static ssize_t show_in_alarm(struct device *dev, struct device_attribute
130/* Sysfs Fan */ 168/* Sysfs Fan */
131static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 169static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
132 char *buf); 170 char *buf);
171static ssize_t show_fan_full_speed(struct device *dev,
172 struct device_attribute *devattr, char *buf);
173static ssize_t store_fan_full_speed(struct device *dev,
174 struct device_attribute *devattr, const char *buf, size_t count);
133static ssize_t show_fan_beep(struct device *dev, struct device_attribute 175static ssize_t show_fan_beep(struct device *dev, struct device_attribute
134 *devattr, char *buf); 176 *devattr, char *buf);
135static ssize_t store_fan_beep(struct device *dev, struct device_attribute 177static ssize_t store_fan_beep(struct device *dev, struct device_attribute
@@ -163,16 +205,41 @@ static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
163 *devattr, char *buf); 205 *devattr, char *buf);
164static ssize_t show_temp_fault(struct device *dev, struct device_attribute 206static ssize_t show_temp_fault(struct device *dev, struct device_attribute
165 *devattr, char *buf); 207 *devattr, char *buf);
208/* PWM and Auto point control */
209static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
210 char *buf);
211static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
212 const char *buf, size_t count);
213static ssize_t show_pwm_enable(struct device *dev,
214 struct device_attribute *devattr, char *buf);
215static ssize_t store_pwm_enable(struct device *dev,
216 struct device_attribute *devattr, const char *buf, size_t count);
217static ssize_t show_pwm_interpolate(struct device *dev,
218 struct device_attribute *devattr, char *buf);
219static ssize_t store_pwm_interpolate(struct device *dev,
220 struct device_attribute *devattr, const char *buf, size_t count);
221static ssize_t show_pwm_auto_point_channel(struct device *dev,
222 struct device_attribute *devattr, char *buf);
223static ssize_t store_pwm_auto_point_channel(struct device *dev,
224 struct device_attribute *devattr, const char *buf, size_t count);
225static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
226 struct device_attribute *devattr, char *buf);
227static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
228 struct device_attribute *devattr, const char *buf, size_t count);
229static ssize_t show_pwm_auto_point_pwm(struct device *dev,
230 struct device_attribute *devattr, char *buf);
231static ssize_t store_pwm_auto_point_pwm(struct device *dev,
232 struct device_attribute *devattr, const char *buf, size_t count);
233static ssize_t show_pwm_auto_point_temp(struct device *dev,
234 struct device_attribute *devattr, char *buf);
235static ssize_t store_pwm_auto_point_temp(struct device *dev,
236 struct device_attribute *devattr, const char *buf, size_t count);
166/* Sysfs misc */ 237/* Sysfs misc */
167static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 238static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
168 char *buf); 239 char *buf);
169 240
170static int __devinit f71882fg_probe(struct platform_device * pdev); 241static int __devinit f71882fg_probe(struct platform_device * pdev);
171static int __devexit f71882fg_remove(struct platform_device *pdev); 242static int f71882fg_remove(struct platform_device *pdev);
172static int __init f71882fg_init(void);
173static int __init f71882fg_find(int sioaddr, unsigned short *address);
174static int __init f71882fg_device_add(unsigned short address);
175static void __exit f71882fg_exit(void);
176 243
177static struct platform_driver f71882fg_driver = { 244static struct platform_driver f71882fg_driver = {
178 .driver = { 245 .driver = {
@@ -183,86 +250,531 @@ static struct platform_driver f71882fg_driver = {
183 .remove = __devexit_p(f71882fg_remove), 250 .remove = __devexit_p(f71882fg_remove),
184}; 251};
185 252
186static struct device_attribute f71882fg_dev_attr[] = 253static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
187{ 254
188 __ATTR( name, S_IRUGO, show_name, NULL ), 255/* Temp and in attr common to both the f71862fg and f71882fg */
256static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
257 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
258 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
259 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
260 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
261 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
262 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
263 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
264 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
265 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
266 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
267 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
268 store_temp_max, 0, 1),
269 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
270 store_temp_max_hyst, 0, 1),
271 /* Should really be temp1_max_alarm, but older versions did not handle
272 the max and crit alarms separately and lm_sensors v2 depends on the
273 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
274 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
275 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
276 store_temp_beep, 0, 1),
277 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
278 store_temp_crit, 0, 1),
279 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
280 0, 1),
281 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
282 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
283 store_temp_beep, 0, 5),
284 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
285 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
286 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
287 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
288 store_temp_max, 0, 2),
289 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
290 store_temp_max_hyst, 0, 2),
291 /* Should be temp2_max_alarm, see temp1_alarm note */
292 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
293 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
294 store_temp_beep, 0, 2),
295 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
296 store_temp_crit, 0, 2),
297 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
298 0, 2),
299 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
300 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
301 store_temp_beep, 0, 6),
302 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
303 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
304 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
305 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
306 store_temp_max, 0, 3),
307 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
308 store_temp_max_hyst, 0, 3),
309 /* Should be temp3_max_alarm, see temp1_alarm note */
310 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
311 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
312 store_temp_beep, 0, 3),
313 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
314 store_temp_crit, 0, 3),
315 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
316 0, 3),
317 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
318 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
319 store_temp_beep, 0, 7),
320 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
321 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
322};
323
324/* Temp and in attr found only on the f71882fg */
325static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
326 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
327 0, 1),
328 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
329 0, 1),
330 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
331};
332
333/* Temp and in attr for the f8000
334 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
335 is used as hysteresis value to clear alarms
336 */
337static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
338 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
339 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
340 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
341 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
342 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
343 store_temp_crit, 0, 0),
344 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
345 store_temp_max, 0, 0),
346 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
347 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
348 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
349 store_temp_crit, 0, 1),
350 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
351 store_temp_max, 0, 1),
352 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
353 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
354 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
355 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
356 store_temp_crit, 0, 2),
357 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
358 store_temp_max, 0, 2),
359 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
360};
361
362/* Fan / PWM attr common to all models */
363static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
364 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
365 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
366 show_fan_full_speed,
367 store_fan_full_speed, 0, 0),
368 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
369 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
370 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
371 show_fan_full_speed,
372 store_fan_full_speed, 0, 1),
373 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
374 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
375 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
376 show_fan_full_speed,
377 store_fan_full_speed, 0, 2),
378 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
379
380 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
381 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
382 store_pwm_enable, 0, 0),
383 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
384 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
385 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
386 show_pwm_auto_point_channel,
387 store_pwm_auto_point_channel, 0, 0),
388
389 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
390 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
391 store_pwm_enable, 0, 1),
392 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
393 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
394 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
395 show_pwm_auto_point_channel,
396 store_pwm_auto_point_channel, 0, 1),
397
398 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
399 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
400 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
401 show_pwm_auto_point_channel,
402 store_pwm_auto_point_channel, 0, 2),
189}; 403};
190 404
191static struct sensor_device_attribute f71882fg_in_temp_attr[] = 405/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
192{ 406 f71882fg */
193 SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), 407static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
194 SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), 408 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
195 SENSOR_ATTR(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 1), 409 store_fan_beep, 0, 0),
196 SENSOR_ATTR(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 1), 410 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
197 SENSOR_ATTR(in1_alarm, S_IRUGO, show_in_alarm, NULL, 1), 411 store_fan_beep, 0, 1),
198 SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), 412 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
199 SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), 413 store_fan_beep, 0, 2),
200 SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), 414
201 SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), 415 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
202 SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), 416 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
203 SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), 417 1, 0),
204 SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), 418 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
205 SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0), 419 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
206 SENSOR_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 420 4, 0),
207 store_temp_max, 0), 421 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
208 SENSOR_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 422 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
209 store_temp_max_hyst, 0), 423 0, 0),
210 SENSOR_ATTR(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, 424 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
211 store_temp_crit, 0), 425 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
212 SENSOR_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0), 426 3, 0),
213 SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), 427 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
214 SENSOR_ATTR(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep, 428 show_pwm_auto_point_temp_hyst,
215 store_temp_beep, 0), 429 store_pwm_auto_point_temp_hyst,
216 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0), 430 0, 0),
217 SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0), 431 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
218 SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1), 432 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
219 SENSOR_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, 433
220 store_temp_max, 1), 434 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
221 SENSOR_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 435 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
222 store_temp_max_hyst, 1), 436 1, 1),
223 SENSOR_ATTR(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, 437 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
224 store_temp_crit, 1), 438 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
225 SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), 439 4, 1),
226 SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), 440 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
227 SENSOR_ATTR(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep, 441 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
228 store_temp_beep, 1), 442 0, 1),
229 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1), 443 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
230 SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1), 444 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
231 SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2), 445 3, 1),
232 SENSOR_ATTR(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 446 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
233 store_temp_max, 2), 447 show_pwm_auto_point_temp_hyst,
234 SENSOR_ATTR(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 448 store_pwm_auto_point_temp_hyst,
235 store_temp_max_hyst, 2), 449 0, 1),
236 SENSOR_ATTR(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, 450 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
237 store_temp_crit, 2), 451 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
238 SENSOR_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 2), 452
239 SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), 453 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
240 SENSOR_ATTR(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep, 454 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
241 store_temp_beep, 2), 455 store_pwm_enable, 0, 2),
242 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2), 456 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
243 SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2) 457 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
458 1, 2),
459 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
460 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
461 4, 2),
462 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
463 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
464 0, 2),
465 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
466 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
467 3, 2),
468 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
469 show_pwm_auto_point_temp_hyst,
470 store_pwm_auto_point_temp_hyst,
471 0, 2),
472 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
473 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
244}; 474};
245 475
246static struct sensor_device_attribute f71882fg_fan_attr[] = 476/* Fan / PWM attr for the f71882fg */
247{ 477static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
248 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), 478 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
249 SENSOR_ATTR(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 479 store_fan_beep, 0, 0),
250 store_fan_beep, 0), 480 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
251 SENSOR_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0), 481 store_fan_beep, 0, 1),
252 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), 482 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
253 SENSOR_ATTR(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, 483 store_fan_beep, 0, 2),
254 store_fan_beep, 1), 484 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
255 SENSOR_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1), 485 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
256 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), 486 show_fan_full_speed,
257 SENSOR_ATTR(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, 487 store_fan_full_speed, 0, 3),
258 store_fan_beep, 2), 488 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
259 SENSOR_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2), 489 store_fan_beep, 0, 3),
260 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), 490 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
261 SENSOR_ATTR(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, 491
262 store_fan_beep, 3), 492 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
263 SENSOR_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3) 493 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
494 0, 0),
495 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
496 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
497 1, 0),
498 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
499 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
500 2, 0),
501 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
502 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
503 3, 0),
504 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
505 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
506 4, 0),
507 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
508 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
509 0, 0),
510 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
511 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
512 1, 0),
513 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
514 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
515 2, 0),
516 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
517 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
518 3, 0),
519 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
520 show_pwm_auto_point_temp_hyst,
521 store_pwm_auto_point_temp_hyst,
522 0, 0),
523 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
524 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
525 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
526 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
527 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
528 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
529
530 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
531 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
532 0, 1),
533 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
534 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
535 1, 1),
536 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
537 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
538 2, 1),
539 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
540 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
541 3, 1),
542 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
543 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
544 4, 1),
545 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
546 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
547 0, 1),
548 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
549 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
550 1, 1),
551 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
552 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
553 2, 1),
554 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
555 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
556 3, 1),
557 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
558 show_pwm_auto_point_temp_hyst,
559 store_pwm_auto_point_temp_hyst,
560 0, 1),
561 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
562 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
563 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
564 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
565 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
566 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
567
568 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
569 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
570 store_pwm_enable, 0, 2),
571 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
572 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
573 0, 2),
574 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
575 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
576 1, 2),
577 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
578 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
579 2, 2),
580 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
581 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
582 3, 2),
583 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
584 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
585 4, 2),
586 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
587 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
588 0, 2),
589 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
590 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
591 1, 2),
592 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
593 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
594 2, 2),
595 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
596 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
597 3, 2),
598 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
599 show_pwm_auto_point_temp_hyst,
600 store_pwm_auto_point_temp_hyst,
601 0, 2),
602 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
603 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
604 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
605 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
606 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
607 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
608
609 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
610 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
611 store_pwm_enable, 0, 3),
612 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
613 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
614 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
615 show_pwm_auto_point_channel,
616 store_pwm_auto_point_channel, 0, 3),
617 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
618 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
619 0, 3),
620 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
621 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
622 1, 3),
623 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
624 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
625 2, 3),
626 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
627 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
628 3, 3),
629 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
630 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
631 4, 3),
632 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
633 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
634 0, 3),
635 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
636 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
637 1, 3),
638 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
639 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
640 2, 3),
641 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
642 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
643 3, 3),
644 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
645 show_pwm_auto_point_temp_hyst,
646 store_pwm_auto_point_temp_hyst,
647 0, 3),
648 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
649 show_pwm_auto_point_temp_hyst, NULL, 1, 3),
650 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
651 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
652 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
653 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
264}; 654};
265 655
656/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
657 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
658 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
659static struct sensor_device_attribute_2 f8000_fan_attr[] = {
660 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
661
662 SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2),
663
664 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
665 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
666 0, 2),
667 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
668 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
669 1, 2),
670 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
671 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
672 2, 2),
673 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
674 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
675 3, 2),
676 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
677 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
678 4, 2),
679 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
680 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
681 0, 2),
682 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
683 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
684 1, 2),
685 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
686 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
687 2, 2),
688 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
689 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
690 3, 2),
691 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
692 show_pwm_auto_point_temp_hyst,
693 store_pwm_auto_point_temp_hyst,
694 0, 2),
695 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
696 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
697 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
698 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
699 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
700 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
701
702 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
703 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
704 0, 0),
705 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
706 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
707 1, 0),
708 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
709 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
710 2, 0),
711 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
712 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
713 3, 0),
714 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
715 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
716 4, 0),
717 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
718 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
719 0, 0),
720 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
721 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
722 1, 0),
723 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
724 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
725 2, 0),
726 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
727 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
728 3, 0),
729 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
730 show_pwm_auto_point_temp_hyst,
731 store_pwm_auto_point_temp_hyst,
732 0, 0),
733 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
734 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
735 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
736 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
737 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
738 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
739
740 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
741 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
742 0, 1),
743 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
744 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
745 1, 1),
746 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
747 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
748 2, 1),
749 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
750 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
751 3, 1),
752 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
753 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
754 4, 1),
755 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
756 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
757 0, 1),
758 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
759 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
760 1, 1),
761 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
762 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
763 2, 1),
764 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
765 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
766 3, 1),
767 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
768 show_pwm_auto_point_temp_hyst,
769 store_pwm_auto_point_temp_hyst,
770 0, 1),
771 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
772 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
773 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
774 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
775 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
776 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
777};
266 778
267/* Super I/O functions */ 779/* Super I/O functions */
268static inline int superio_inb(int base, int reg) 780static inline int superio_inb(int base, int reg)
@@ -299,11 +811,16 @@ static inline void superio_exit(int base)
299 outb(SIO_LOCK_KEY, base); 811 outb(SIO_LOCK_KEY, base);
300} 812}
301 813
302static inline u16 fan_from_reg(u16 reg) 814static inline int fan_from_reg(u16 reg)
303{ 815{
304 return reg ? (1500000 / reg) : 0; 816 return reg ? (1500000 / reg) : 0;
305} 817}
306 818
819static inline u16 fan_to_reg(int fan)
820{
821 return fan ? (1500000 / fan) : 0;
822}
823
307static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg) 824static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
308{ 825{
309 u8 val; 826 u8 val;
@@ -332,52 +849,111 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
332 outb(val, data->addr + DATA_REG_OFFSET); 849 outb(val, data->addr + DATA_REG_OFFSET);
333} 850}
334 851
335static struct f71882fg_data *f71882fg_update_device(struct device * dev) 852static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
853{
854 outb(reg++, data->addr + ADDR_REG_OFFSET);
855 outb(val >> 8, data->addr + DATA_REG_OFFSET);
856 outb(reg, data->addr + ADDR_REG_OFFSET);
857 outb(val & 255, data->addr + DATA_REG_OFFSET);
858}
859
860static struct f71882fg_data *f71882fg_update_device(struct device *dev)
336{ 861{
337 struct f71882fg_data *data = dev_get_drvdata(dev); 862 struct f71882fg_data *data = dev_get_drvdata(dev);
338 int nr, reg, reg2; 863 int nr, reg = 0, reg2;
864 int nr_fans = (data->type == f71882fg) ? 4 : 3;
865 int nr_ins = (data->type == f8000) ? 3 : 9;
866 int temp_start = (data->type == f8000) ? 0 : 1;
339 867
340 mutex_lock(&data->update_lock); 868 mutex_lock(&data->update_lock);
341 869
342 /* Update once every 60 seconds */ 870 /* Update once every 60 seconds */
343 if ( time_after(jiffies, data->last_limits + 60 * HZ ) || 871 if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
344 !data->valid) { 872 !data->valid) {
345 data->in1_max = f71882fg_read8(data, F71882FG_REG_IN1_HIGH); 873 if (data->type == f71882fg) {
346 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); 874 data->in1_max =
875 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
876 data->in_beep =
877 f71882fg_read8(data, F71882FG_REG_IN_BEEP);
878 }
347 879
348 /* Get High & boundary temps*/ 880 /* Get High & boundary temps*/
349 for (nr = 0; nr < 3; nr++) { 881 for (nr = temp_start; nr < 3 + temp_start; nr++) {
350 data->temp_ovt[nr] = f71882fg_read8(data, 882 data->temp_ovt[nr] = f71882fg_read8(data,
351 F71882FG_REG_TEMP_OVT(nr)); 883 F71882FG_REG_TEMP_OVT(nr));
352 data->temp_high[nr] = f71882fg_read8(data, 884 data->temp_high[nr] = f71882fg_read8(data,
353 F71882FG_REG_TEMP_HIGH(nr)); 885 F71882FG_REG_TEMP_HIGH(nr));
354 } 886 }
355 887
356 /* Have to hardcode hyst*/ 888 if (data->type != f8000) {
357 data->temp_hyst[0] = f71882fg_read8(data, 889 data->fan_beep = f71882fg_read8(data,
358 F71882FG_REG_TEMP_HYST1) >> 4; 890 F71882FG_REG_FAN_BEEP);
359 /* Hyst temps 2 & 3 stored in same register */ 891 data->temp_beep = f71882fg_read8(data,
360 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST23); 892 F71882FG_REG_TEMP_BEEP);
361 data->temp_hyst[1] = reg & 0x0F; 893 data->temp_hyst[0] = f71882fg_read8(data,
362 data->temp_hyst[2] = reg >> 4; 894 F71882FG_REG_TEMP_HYST(0));
363 895 data->temp_hyst[1] = f71882fg_read8(data,
364 /* Have to hardcode type, because temp1 is special */ 896 F71882FG_REG_TEMP_HYST(1));
365 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 897 /* Have to hardcode type, because temp1 is special */
898 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
899 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
900 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
901 }
366 reg2 = f71882fg_read8(data, F71882FG_REG_PECI); 902 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
367 if ((reg2 & 0x03) == 0x01) 903 if ((reg2 & 0x03) == 0x01)
368 data->temp_type[0] = 6 /* PECI */; 904 data->temp_type[1] = 6 /* PECI */;
369 else if ((reg2 & 0x03) == 0x02) 905 else if ((reg2 & 0x03) == 0x02)
370 data->temp_type[0] = 5 /* AMDSI */; 906 data->temp_type[1] = 5 /* AMDSI */;
907 else if (data->type != f8000)
908 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
371 else 909 else
372 data->temp_type[0] = (reg & 0x02) ? 2 : 4; 910 data->temp_type[1] = 2; /* F8000 only supports BJT */
373 911
374 data->temp_type[1] = (reg & 0x04) ? 2 : 4; 912 data->pwm_enable = f71882fg_read8(data,
375 data->temp_type[2] = (reg & 0x08) ? 2 : 4; 913 F71882FG_REG_PWM_ENABLE);
376 914 data->pwm_auto_point_hyst[0] =
377 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); 915 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
378 916 data->pwm_auto_point_hyst[1] =
379 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); 917 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
380 918
919 for (nr = 0; nr < nr_fans; nr++) {
920 data->pwm_auto_point_mapping[nr] =
921 f71882fg_read8(data,
922 F71882FG_REG_POINT_MAPPING(nr));
923
924 if (data->type != f71862fg) {
925 int point;
926 for (point = 0; point < 5; point++) {
927 data->pwm_auto_point_pwm[nr][point] =
928 f71882fg_read8(data,
929 F71882FG_REG_POINT_PWM
930 (nr, point));
931 }
932 for (point = 0; point < 4; point++) {
933 data->pwm_auto_point_temp[nr][point] =
934 f71882fg_read8(data,
935 F71882FG_REG_POINT_TEMP
936 (nr, point));
937 }
938 } else {
939 data->pwm_auto_point_pwm[nr][1] =
940 f71882fg_read8(data,
941 F71882FG_REG_POINT_PWM
942 (nr, 1));
943 data->pwm_auto_point_pwm[nr][4] =
944 f71882fg_read8(data,
945 F71882FG_REG_POINT_PWM
946 (nr, 4));
947 data->pwm_auto_point_temp[nr][0] =
948 f71882fg_read8(data,
949 F71882FG_REG_POINT_TEMP
950 (nr, 0));
951 data->pwm_auto_point_temp[nr][3] =
952 f71882fg_read8(data,
953 F71882FG_REG_POINT_TEMP
954 (nr, 3));
955 }
956 }
381 data->last_limits = jiffies; 957 data->last_limits = jiffies;
382 } 958 }
383 959
@@ -387,19 +963,32 @@ static struct f71882fg_data *f71882fg_update_device(struct device * dev)
387 F71882FG_REG_TEMP_STATUS); 963 F71882FG_REG_TEMP_STATUS);
388 data->temp_diode_open = f71882fg_read8(data, 964 data->temp_diode_open = f71882fg_read8(data,
389 F71882FG_REG_TEMP_DIODE_OPEN); 965 F71882FG_REG_TEMP_DIODE_OPEN);
390 for (nr = 0; nr < 3; nr++) 966 for (nr = temp_start; nr < 3 + temp_start; nr++)
391 data->temp[nr] = f71882fg_read8(data, 967 data->temp[nr] = f71882fg_read8(data,
392 F71882FG_REG_TEMP(nr)); 968 F71882FG_REG_TEMP(nr));
393 969
394 data->fan_status = f71882fg_read8(data, 970 data->fan_status = f71882fg_read8(data,
395 F71882FG_REG_FAN_STATUS); 971 F71882FG_REG_FAN_STATUS);
396 for (nr = 0; nr < 4; nr++) 972 for (nr = 0; nr < nr_fans; nr++) {
397 data->fan[nr] = f71882fg_read16(data, 973 data->fan[nr] = f71882fg_read16(data,
398 F71882FG_REG_FAN(nr)); 974 F71882FG_REG_FAN(nr));
975 data->fan_target[nr] =
976 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
977 data->fan_full_speed[nr] =
978 f71882fg_read16(data,
979 F71882FG_REG_FAN_FULL_SPEED(nr));
980 data->pwm[nr] =
981 f71882fg_read8(data, F71882FG_REG_PWM(nr));
982 }
399 983
400 data->in_status = f71882fg_read8(data, 984 /* The f8000 can monitor 1 more fan, but has no pwm for it */
985 if (data->type == f8000)
986 data->fan[3] = f71882fg_read16(data,
987 F71882FG_REG_FAN(3));
988 if (data->type == f71882fg)
989 data->in_status = f71882fg_read8(data,
401 F71882FG_REG_IN_STATUS); 990 F71882FG_REG_IN_STATUS);
402 for (nr = 0; nr < 9; nr++) 991 for (nr = 0; nr < nr_ins; nr++)
403 data->in[nr] = f71882fg_read8(data, 992 data->in[nr] = f71882fg_read8(data,
404 F71882FG_REG_IN(nr)); 993 F71882FG_REG_IN(nr));
405 994
@@ -417,7 +1006,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
417 char *buf) 1006 char *buf)
418{ 1007{
419 struct f71882fg_data *data = f71882fg_update_device(dev); 1008 struct f71882fg_data *data = f71882fg_update_device(dev);
420 int nr = to_sensor_dev_attr(devattr)->index; 1009 int nr = to_sensor_dev_attr_2(devattr)->index;
421 int speed = fan_from_reg(data->fan[nr]); 1010 int speed = fan_from_reg(data->fan[nr]);
422 1011
423 if (speed == FAN_MIN_DETECT) 1012 if (speed == FAN_MIN_DETECT)
@@ -426,11 +1015,39 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
426 return sprintf(buf, "%d\n", speed); 1015 return sprintf(buf, "%d\n", speed);
427} 1016}
428 1017
1018static ssize_t show_fan_full_speed(struct device *dev,
1019 struct device_attribute *devattr, char *buf)
1020{
1021 struct f71882fg_data *data = f71882fg_update_device(dev);
1022 int nr = to_sensor_dev_attr_2(devattr)->index;
1023 int speed = fan_from_reg(data->fan_full_speed[nr]);
1024 return sprintf(buf, "%d\n", speed);
1025}
1026
1027static ssize_t store_fan_full_speed(struct device *dev,
1028 struct device_attribute *devattr,
1029 const char *buf, size_t count)
1030{
1031 struct f71882fg_data *data = dev_get_drvdata(dev);
1032 int nr = to_sensor_dev_attr_2(devattr)->index;
1033 long val = simple_strtol(buf, NULL, 10);
1034
1035 val = SENSORS_LIMIT(val, 23, 1500000);
1036 val = fan_to_reg(val);
1037
1038 mutex_lock(&data->update_lock);
1039 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1040 data->fan_full_speed[nr] = val;
1041 mutex_unlock(&data->update_lock);
1042
1043 return count;
1044}
1045
429static ssize_t show_fan_beep(struct device *dev, struct device_attribute 1046static ssize_t show_fan_beep(struct device *dev, struct device_attribute
430 *devattr, char *buf) 1047 *devattr, char *buf)
431{ 1048{
432 struct f71882fg_data *data = f71882fg_update_device(dev); 1049 struct f71882fg_data *data = f71882fg_update_device(dev);
433 int nr = to_sensor_dev_attr(devattr)->index; 1050 int nr = to_sensor_dev_attr_2(devattr)->index;
434 1051
435 if (data->fan_beep & (1 << nr)) 1052 if (data->fan_beep & (1 << nr))
436 return sprintf(buf, "1\n"); 1053 return sprintf(buf, "1\n");
@@ -442,10 +1059,11 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute
442 *devattr, const char *buf, size_t count) 1059 *devattr, const char *buf, size_t count)
443{ 1060{
444 struct f71882fg_data *data = dev_get_drvdata(dev); 1061 struct f71882fg_data *data = dev_get_drvdata(dev);
445 int nr = to_sensor_dev_attr(devattr)->index; 1062 int nr = to_sensor_dev_attr_2(devattr)->index;
446 int val = simple_strtoul(buf, NULL, 10); 1063 unsigned long val = simple_strtoul(buf, NULL, 10);
447 1064
448 mutex_lock(&data->update_lock); 1065 mutex_lock(&data->update_lock);
1066 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
449 if (val) 1067 if (val)
450 data->fan_beep |= 1 << nr; 1068 data->fan_beep |= 1 << nr;
451 else 1069 else
@@ -461,7 +1079,7 @@ static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
461 *devattr, char *buf) 1079 *devattr, char *buf)
462{ 1080{
463 struct f71882fg_data *data = f71882fg_update_device(dev); 1081 struct f71882fg_data *data = f71882fg_update_device(dev);
464 int nr = to_sensor_dev_attr(devattr)->index; 1082 int nr = to_sensor_dev_attr_2(devattr)->index;
465 1083
466 if (data->fan_status & (1 << nr)) 1084 if (data->fan_status & (1 << nr))
467 return sprintf(buf, "1\n"); 1085 return sprintf(buf, "1\n");
@@ -473,7 +1091,7 @@ static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
473 char *buf) 1091 char *buf)
474{ 1092{
475 struct f71882fg_data *data = f71882fg_update_device(dev); 1093 struct f71882fg_data *data = f71882fg_update_device(dev);
476 int nr = to_sensor_dev_attr(devattr)->index; 1094 int nr = to_sensor_dev_attr_2(devattr)->index;
477 1095
478 return sprintf(buf, "%d\n", data->in[nr] * 8); 1096 return sprintf(buf, "%d\n", data->in[nr] * 8);
479} 1097}
@@ -490,10 +1108,8 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute
490 *devattr, const char *buf, size_t count) 1108 *devattr, const char *buf, size_t count)
491{ 1109{
492 struct f71882fg_data *data = dev_get_drvdata(dev); 1110 struct f71882fg_data *data = dev_get_drvdata(dev);
493 int val = simple_strtoul(buf, NULL, 10) / 8; 1111 long val = simple_strtol(buf, NULL, 10) / 8;
494 1112 val = SENSORS_LIMIT(val, 0, 255);
495 if (val > 255)
496 val = 255;
497 1113
498 mutex_lock(&data->update_lock); 1114 mutex_lock(&data->update_lock);
499 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val); 1115 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
@@ -507,7 +1123,7 @@ static ssize_t show_in_beep(struct device *dev, struct device_attribute
507 *devattr, char *buf) 1123 *devattr, char *buf)
508{ 1124{
509 struct f71882fg_data *data = f71882fg_update_device(dev); 1125 struct f71882fg_data *data = f71882fg_update_device(dev);
510 int nr = to_sensor_dev_attr(devattr)->index; 1126 int nr = to_sensor_dev_attr_2(devattr)->index;
511 1127
512 if (data->in_beep & (1 << nr)) 1128 if (data->in_beep & (1 << nr))
513 return sprintf(buf, "1\n"); 1129 return sprintf(buf, "1\n");
@@ -519,10 +1135,11 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute
519 *devattr, const char *buf, size_t count) 1135 *devattr, const char *buf, size_t count)
520{ 1136{
521 struct f71882fg_data *data = dev_get_drvdata(dev); 1137 struct f71882fg_data *data = dev_get_drvdata(dev);
522 int nr = to_sensor_dev_attr(devattr)->index; 1138 int nr = to_sensor_dev_attr_2(devattr)->index;
523 int val = simple_strtoul(buf, NULL, 10); 1139 unsigned long val = simple_strtoul(buf, NULL, 10);
524 1140
525 mutex_lock(&data->update_lock); 1141 mutex_lock(&data->update_lock);
1142 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
526 if (val) 1143 if (val)
527 data->in_beep |= 1 << nr; 1144 data->in_beep |= 1 << nr;
528 else 1145 else
@@ -538,7 +1155,7 @@ static ssize_t show_in_alarm(struct device *dev, struct device_attribute
538 *devattr, char *buf) 1155 *devattr, char *buf)
539{ 1156{
540 struct f71882fg_data *data = f71882fg_update_device(dev); 1157 struct f71882fg_data *data = f71882fg_update_device(dev);
541 int nr = to_sensor_dev_attr(devattr)->index; 1158 int nr = to_sensor_dev_attr_2(devattr)->index;
542 1159
543 if (data->in_status & (1 << nr)) 1160 if (data->in_status & (1 << nr))
544 return sprintf(buf, "1\n"); 1161 return sprintf(buf, "1\n");
@@ -550,7 +1167,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
550 char *buf) 1167 char *buf)
551{ 1168{
552 struct f71882fg_data *data = f71882fg_update_device(dev); 1169 struct f71882fg_data *data = f71882fg_update_device(dev);
553 int nr = to_sensor_dev_attr(devattr)->index; 1170 int nr = to_sensor_dev_attr_2(devattr)->index;
554 1171
555 return sprintf(buf, "%d\n", data->temp[nr] * 1000); 1172 return sprintf(buf, "%d\n", data->temp[nr] * 1000);
556} 1173}
@@ -559,7 +1176,7 @@ static ssize_t show_temp_max(struct device *dev, struct device_attribute
559 *devattr, char *buf) 1176 *devattr, char *buf)
560{ 1177{
561 struct f71882fg_data *data = f71882fg_update_device(dev); 1178 struct f71882fg_data *data = f71882fg_update_device(dev);
562 int nr = to_sensor_dev_attr(devattr)->index; 1179 int nr = to_sensor_dev_attr_2(devattr)->index;
563 1180
564 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000); 1181 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
565} 1182}
@@ -568,11 +1185,9 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
568 *devattr, const char *buf, size_t count) 1185 *devattr, const char *buf, size_t count)
569{ 1186{
570 struct f71882fg_data *data = dev_get_drvdata(dev); 1187 struct f71882fg_data *data = dev_get_drvdata(dev);
571 int nr = to_sensor_dev_attr(devattr)->index; 1188 int nr = to_sensor_dev_attr_2(devattr)->index;
572 int val = simple_strtoul(buf, NULL, 10) / 1000; 1189 long val = simple_strtol(buf, NULL, 10) / 1000;
573 1190 val = SENSORS_LIMIT(val, 0, 255);
574 if (val > 255)
575 val = 255;
576 1191
577 mutex_lock(&data->update_lock); 1192 mutex_lock(&data->update_lock);
578 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val); 1193 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
@@ -586,48 +1201,46 @@ static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
586 *devattr, char *buf) 1201 *devattr, char *buf)
587{ 1202{
588 struct f71882fg_data *data = f71882fg_update_device(dev); 1203 struct f71882fg_data *data = f71882fg_update_device(dev);
589 int nr = to_sensor_dev_attr(devattr)->index; 1204 int nr = to_sensor_dev_attr_2(devattr)->index;
1205 int temp_max_hyst;
1206
1207 mutex_lock(&data->update_lock);
1208 if (nr & 1)
1209 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1210 else
1211 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1212 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1213 mutex_unlock(&data->update_lock);
590 1214
591 return sprintf(buf, "%d\n", 1215 return sprintf(buf, "%d\n", temp_max_hyst);
592 (data->temp_high[nr] - data->temp_hyst[nr]) * 1000);
593} 1216}
594 1217
595static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute 1218static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
596 *devattr, const char *buf, size_t count) 1219 *devattr, const char *buf, size_t count)
597{ 1220{
598 struct f71882fg_data *data = dev_get_drvdata(dev); 1221 struct f71882fg_data *data = dev_get_drvdata(dev);
599 int nr = to_sensor_dev_attr(devattr)->index; 1222 int nr = to_sensor_dev_attr_2(devattr)->index;
600 int val = simple_strtoul(buf, NULL, 10) / 1000; 1223 long val = simple_strtol(buf, NULL, 10) / 1000;
601 ssize_t ret = count; 1224 ssize_t ret = count;
1225 u8 reg;
602 1226
603 mutex_lock(&data->update_lock); 1227 mutex_lock(&data->update_lock);
604 1228
605 /* convert abs to relative and check */ 1229 /* convert abs to relative and check */
1230 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1231 val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1232 data->temp_high[nr]);
606 val = data->temp_high[nr] - val; 1233 val = data->temp_high[nr] - val;
607 if (val < 0 || val > 15) {
608 ret = -EINVAL;
609 goto store_temp_max_hyst_exit;
610 }
611
612 data->temp_hyst[nr] = val;
613 1234
614 /* convert value to register contents */ 1235 /* convert value to register contents */
615 switch (nr) { 1236 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
616 case 0: 1237 if (nr & 1)
617 val = val << 4; 1238 reg = (reg & 0x0f) | (val << 4);
618 break; 1239 else
619 case 1: 1240 reg = (reg & 0xf0) | val;
620 val = val | (data->temp_hyst[2] << 4); 1241 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
621 break; 1242 data->temp_hyst[nr / 2] = reg;
622 case 2:
623 val = data->temp_hyst[1] | (val << 4);
624 break;
625 }
626
627 f71882fg_write8(data, nr ? F71882FG_REG_TEMP_HYST23 :
628 F71882FG_REG_TEMP_HYST1, val);
629 1243
630store_temp_max_hyst_exit:
631 mutex_unlock(&data->update_lock); 1244 mutex_unlock(&data->update_lock);
632 return ret; 1245 return ret;
633} 1246}
@@ -636,7 +1249,7 @@ static ssize_t show_temp_crit(struct device *dev, struct device_attribute
636 *devattr, char *buf) 1249 *devattr, char *buf)
637{ 1250{
638 struct f71882fg_data *data = f71882fg_update_device(dev); 1251 struct f71882fg_data *data = f71882fg_update_device(dev);
639 int nr = to_sensor_dev_attr(devattr)->index; 1252 int nr = to_sensor_dev_attr_2(devattr)->index;
640 1253
641 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000); 1254 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
642} 1255}
@@ -645,11 +1258,9 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute
645 *devattr, const char *buf, size_t count) 1258 *devattr, const char *buf, size_t count)
646{ 1259{
647 struct f71882fg_data *data = dev_get_drvdata(dev); 1260 struct f71882fg_data *data = dev_get_drvdata(dev);
648 int nr = to_sensor_dev_attr(devattr)->index; 1261 int nr = to_sensor_dev_attr_2(devattr)->index;
649 int val = simple_strtoul(buf, NULL, 10) / 1000; 1262 long val = simple_strtol(buf, NULL, 10) / 1000;
650 1263 val = SENSORS_LIMIT(val, 0, 255);
651 if (val > 255)
652 val = 255;
653 1264
654 mutex_lock(&data->update_lock); 1265 mutex_lock(&data->update_lock);
655 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val); 1266 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
@@ -663,17 +1274,25 @@ static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
663 *devattr, char *buf) 1274 *devattr, char *buf)
664{ 1275{
665 struct f71882fg_data *data = f71882fg_update_device(dev); 1276 struct f71882fg_data *data = f71882fg_update_device(dev);
666 int nr = to_sensor_dev_attr(devattr)->index; 1277 int nr = to_sensor_dev_attr_2(devattr)->index;
1278 int temp_crit_hyst;
1279
1280 mutex_lock(&data->update_lock);
1281 if (nr & 1)
1282 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1283 else
1284 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1285 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1286 mutex_unlock(&data->update_lock);
667 1287
668 return sprintf(buf, "%d\n", 1288 return sprintf(buf, "%d\n", temp_crit_hyst);
669 (data->temp_ovt[nr] - data->temp_hyst[nr]) * 1000);
670} 1289}
671 1290
672static ssize_t show_temp_type(struct device *dev, struct device_attribute 1291static ssize_t show_temp_type(struct device *dev, struct device_attribute
673 *devattr, char *buf) 1292 *devattr, char *buf)
674{ 1293{
675 struct f71882fg_data *data = f71882fg_update_device(dev); 1294 struct f71882fg_data *data = f71882fg_update_device(dev);
676 int nr = to_sensor_dev_attr(devattr)->index; 1295 int nr = to_sensor_dev_attr_2(devattr)->index;
677 1296
678 return sprintf(buf, "%d\n", data->temp_type[nr]); 1297 return sprintf(buf, "%d\n", data->temp_type[nr]);
679} 1298}
@@ -682,9 +1301,9 @@ static ssize_t show_temp_beep(struct device *dev, struct device_attribute
682 *devattr, char *buf) 1301 *devattr, char *buf)
683{ 1302{
684 struct f71882fg_data *data = f71882fg_update_device(dev); 1303 struct f71882fg_data *data = f71882fg_update_device(dev);
685 int nr = to_sensor_dev_attr(devattr)->index; 1304 int nr = to_sensor_dev_attr_2(devattr)->index;
686 1305
687 if (data->temp_beep & (1 << (nr + 1))) 1306 if (data->temp_beep & (1 << nr))
688 return sprintf(buf, "1\n"); 1307 return sprintf(buf, "1\n");
689 else 1308 else
690 return sprintf(buf, "0\n"); 1309 return sprintf(buf, "0\n");
@@ -694,14 +1313,15 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute
694 *devattr, const char *buf, size_t count) 1313 *devattr, const char *buf, size_t count)
695{ 1314{
696 struct f71882fg_data *data = dev_get_drvdata(dev); 1315 struct f71882fg_data *data = dev_get_drvdata(dev);
697 int nr = to_sensor_dev_attr(devattr)->index; 1316 int nr = to_sensor_dev_attr_2(devattr)->index;
698 int val = simple_strtoul(buf, NULL, 10); 1317 unsigned long val = simple_strtoul(buf, NULL, 10);
699 1318
700 mutex_lock(&data->update_lock); 1319 mutex_lock(&data->update_lock);
1320 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
701 if (val) 1321 if (val)
702 data->temp_beep |= 1 << (nr + 1); 1322 data->temp_beep |= 1 << nr;
703 else 1323 else
704 data->temp_beep &= ~(1 << (nr + 1)); 1324 data->temp_beep &= ~(1 << nr);
705 1325
706 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep); 1326 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
707 mutex_unlock(&data->update_lock); 1327 mutex_unlock(&data->update_lock);
@@ -713,9 +1333,9 @@ static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
713 *devattr, char *buf) 1333 *devattr, char *buf)
714{ 1334{
715 struct f71882fg_data *data = f71882fg_update_device(dev); 1335 struct f71882fg_data *data = f71882fg_update_device(dev);
716 int nr = to_sensor_dev_attr(devattr)->index; 1336 int nr = to_sensor_dev_attr_2(devattr)->index;
717 1337
718 if (data->temp_status & (1 << (nr + 1))) 1338 if (data->temp_status & (1 << nr))
719 return sprintf(buf, "1\n"); 1339 return sprintf(buf, "1\n");
720 else 1340 else
721 return sprintf(buf, "0\n"); 1341 return sprintf(buf, "0\n");
@@ -725,113 +1345,528 @@ static ssize_t show_temp_fault(struct device *dev, struct device_attribute
725 *devattr, char *buf) 1345 *devattr, char *buf)
726{ 1346{
727 struct f71882fg_data *data = f71882fg_update_device(dev); 1347 struct f71882fg_data *data = f71882fg_update_device(dev);
728 int nr = to_sensor_dev_attr(devattr)->index; 1348 int nr = to_sensor_dev_attr_2(devattr)->index;
729 1349
730 if (data->temp_diode_open & (1 << (nr + 1))) 1350 if (data->temp_diode_open & (1 << nr))
731 return sprintf(buf, "1\n"); 1351 return sprintf(buf, "1\n");
732 else 1352 else
733 return sprintf(buf, "0\n"); 1353 return sprintf(buf, "0\n");
734} 1354}
735 1355
1356static ssize_t show_pwm(struct device *dev,
1357 struct device_attribute *devattr, char *buf)
1358{
1359 struct f71882fg_data *data = f71882fg_update_device(dev);
1360 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1361 mutex_lock(&data->update_lock);
1362 if (data->pwm_enable & (1 << (2 * nr)))
1363 /* PWM mode */
1364 val = data->pwm[nr];
1365 else {
1366 /* RPM mode */
1367 val = 255 * fan_from_reg(data->fan_target[nr])
1368 / fan_from_reg(data->fan_full_speed[nr]);
1369 }
1370 mutex_unlock(&data->update_lock);
1371 return sprintf(buf, "%d\n", val);
1372}
1373
1374static ssize_t store_pwm(struct device *dev,
1375 struct device_attribute *devattr, const char *buf,
1376 size_t count)
1377{
1378 struct f71882fg_data *data = dev_get_drvdata(dev);
1379 int nr = to_sensor_dev_attr_2(devattr)->index;
1380 long val = simple_strtol(buf, NULL, 10);
1381 val = SENSORS_LIMIT(val, 0, 255);
1382
1383 mutex_lock(&data->update_lock);
1384 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1385 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1386 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1387 count = -EROFS;
1388 goto leave;
1389 }
1390 if (data->pwm_enable & (1 << (2 * nr))) {
1391 /* PWM mode */
1392 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1393 data->pwm[nr] = val;
1394 } else {
1395 /* RPM mode */
1396 int target, full_speed;
1397 full_speed = f71882fg_read16(data,
1398 F71882FG_REG_FAN_FULL_SPEED(nr));
1399 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1400 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1401 data->fan_target[nr] = target;
1402 data->fan_full_speed[nr] = full_speed;
1403 }
1404leave:
1405 mutex_unlock(&data->update_lock);
1406
1407 return count;
1408}
1409
1410static ssize_t show_pwm_enable(struct device *dev,
1411 struct device_attribute *devattr, char *buf)
1412{
1413 int result = 0;
1414 struct f71882fg_data *data = f71882fg_update_device(dev);
1415 int nr = to_sensor_dev_attr_2(devattr)->index;
1416
1417 switch ((data->pwm_enable >> 2 * nr) & 3) {
1418 case 0:
1419 case 1:
1420 result = 2; /* Normal auto mode */
1421 break;
1422 case 2:
1423 result = 1; /* Manual mode */
1424 break;
1425 case 3:
1426 if (data->type == f8000)
1427 result = 3; /* Thermostat mode */
1428 else
1429 result = 1; /* Manual mode */
1430 break;
1431 }
1432
1433 return sprintf(buf, "%d\n", result);
1434}
1435
1436static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1437 *devattr, const char *buf, size_t count)
1438{
1439 struct f71882fg_data *data = dev_get_drvdata(dev);
1440 int nr = to_sensor_dev_attr_2(devattr)->index;
1441 long val = simple_strtol(buf, NULL, 10);
1442
1443 mutex_lock(&data->update_lock);
1444 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1445 /* Special case for F8000 auto PWM mode / Thermostat mode */
1446 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1447 switch (val) {
1448 case 2:
1449 data->pwm_enable &= ~(2 << (2 * nr));
1450 break; /* Normal auto mode */
1451 case 3:
1452 data->pwm_enable |= 2 << (2 * nr);
1453 break; /* Thermostat mode */
1454 default:
1455 count = -EINVAL;
1456 goto leave;
1457 }
1458 } else {
1459 switch (val) {
1460 case 1:
1461 data->pwm_enable |= 2 << (2 * nr);
1462 break; /* Manual */
1463 case 2:
1464 data->pwm_enable &= ~(2 << (2 * nr));
1465 break; /* Normal auto mode */
1466 default:
1467 count = -EINVAL;
1468 goto leave;
1469 }
1470 }
1471 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1472leave:
1473 mutex_unlock(&data->update_lock);
1474
1475 return count;
1476}
1477
1478static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1479 struct device_attribute *devattr,
1480 char *buf)
1481{
1482 int result;
1483 struct f71882fg_data *data = f71882fg_update_device(dev);
1484 int pwm = to_sensor_dev_attr_2(devattr)->index;
1485 int point = to_sensor_dev_attr_2(devattr)->nr;
1486
1487 mutex_lock(&data->update_lock);
1488 if (data->pwm_enable & (1 << (2 * pwm))) {
1489 /* PWM mode */
1490 result = data->pwm_auto_point_pwm[pwm][point];
1491 } else {
1492 /* RPM mode */
1493 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1494 }
1495 mutex_unlock(&data->update_lock);
1496
1497 return sprintf(buf, "%d\n", result);
1498}
1499
1500static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1501 struct device_attribute *devattr,
1502 const char *buf, size_t count)
1503{
1504 struct f71882fg_data *data = dev_get_drvdata(dev);
1505 int pwm = to_sensor_dev_attr_2(devattr)->index;
1506 int point = to_sensor_dev_attr_2(devattr)->nr;
1507 long val = simple_strtol(buf, NULL, 10);
1508 val = SENSORS_LIMIT(val, 0, 255);
1509
1510 mutex_lock(&data->update_lock);
1511 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1512 if (data->pwm_enable & (1 << (2 * pwm))) {
1513 /* PWM mode */
1514 } else {
1515 /* RPM mode */
1516 if (val < 29) /* Prevent negative numbers */
1517 val = 255;
1518 else
1519 val = (255 - val) * 32 / val;
1520 }
1521 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1522 data->pwm_auto_point_pwm[pwm][point] = val;
1523 mutex_unlock(&data->update_lock);
1524
1525 return count;
1526}
1527
1528static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1529 struct device_attribute *devattr,
1530 char *buf)
1531{
1532 int result = 0;
1533 struct f71882fg_data *data = f71882fg_update_device(dev);
1534 int nr = to_sensor_dev_attr_2(devattr)->index;
1535 int point = to_sensor_dev_attr_2(devattr)->nr;
1536
1537 mutex_lock(&data->update_lock);
1538 if (nr & 1)
1539 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1540 else
1541 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1542 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1543 mutex_unlock(&data->update_lock);
1544
1545 return sprintf(buf, "%d\n", result);
1546}
1547
1548static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1549 struct device_attribute *devattr,
1550 const char *buf, size_t count)
1551{
1552 struct f71882fg_data *data = dev_get_drvdata(dev);
1553 int nr = to_sensor_dev_attr_2(devattr)->index;
1554 int point = to_sensor_dev_attr_2(devattr)->nr;
1555 long val = simple_strtol(buf, NULL, 10) / 1000;
1556 u8 reg;
1557
1558 mutex_lock(&data->update_lock);
1559 data->pwm_auto_point_temp[nr][point] =
1560 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1561 val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1562 data->pwm_auto_point_temp[nr][point]);
1563 val = data->pwm_auto_point_temp[nr][point] - val;
1564
1565 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1566 if (nr & 1)
1567 reg = (reg & 0x0f) | (val << 4);
1568 else
1569 reg = (reg & 0xf0) | val;
1570
1571 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1572 data->pwm_auto_point_hyst[nr / 2] = reg;
1573 mutex_unlock(&data->update_lock);
1574
1575 return count;
1576}
1577
1578static ssize_t show_pwm_interpolate(struct device *dev,
1579 struct device_attribute *devattr, char *buf)
1580{
1581 int result;
1582 struct f71882fg_data *data = f71882fg_update_device(dev);
1583 int nr = to_sensor_dev_attr_2(devattr)->index;
1584
1585 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
1586
1587 return sprintf(buf, "%d\n", result);
1588}
1589
1590static ssize_t store_pwm_interpolate(struct device *dev,
1591 struct device_attribute *devattr,
1592 const char *buf, size_t count)
1593{
1594 struct f71882fg_data *data = dev_get_drvdata(dev);
1595 int nr = to_sensor_dev_attr_2(devattr)->index;
1596 unsigned long val = simple_strtoul(buf, NULL, 10);
1597
1598 mutex_lock(&data->update_lock);
1599 data->pwm_auto_point_mapping[nr] =
1600 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1601 if (val)
1602 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
1603 else
1604 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
1605 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1606 data->pwm_auto_point_mapping[nr] = val;
1607 mutex_unlock(&data->update_lock);
1608
1609 return count;
1610}
1611
1612static ssize_t show_pwm_auto_point_channel(struct device *dev,
1613 struct device_attribute *devattr,
1614 char *buf)
1615{
1616 int result;
1617 struct f71882fg_data *data = f71882fg_update_device(dev);
1618 int nr = to_sensor_dev_attr_2(devattr)->index;
1619 int temp_start = (data->type == f8000) ? 0 : 1;
1620
1621 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start);
1622
1623 return sprintf(buf, "%d\n", result);
1624}
1625
1626static ssize_t store_pwm_auto_point_channel(struct device *dev,
1627 struct device_attribute *devattr,
1628 const char *buf, size_t count)
1629{
1630 struct f71882fg_data *data = dev_get_drvdata(dev);
1631 int nr = to_sensor_dev_attr_2(devattr)->index;
1632 int temp_start = (data->type == f8000) ? 0 : 1;
1633 long val = simple_strtol(buf, NULL, 10);
1634
1635 switch (val) {
1636 case 1:
1637 val = 0;
1638 break;
1639 case 2:
1640 val = 1;
1641 break;
1642 case 4:
1643 val = 2;
1644 break;
1645 default:
1646 return -EINVAL;
1647 }
1648 val += temp_start;
1649 mutex_lock(&data->update_lock);
1650 data->pwm_auto_point_mapping[nr] =
1651 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1652 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
1653 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1654 data->pwm_auto_point_mapping[nr] = val;
1655 mutex_unlock(&data->update_lock);
1656
1657 return count;
1658}
1659
1660static ssize_t show_pwm_auto_point_temp(struct device *dev,
1661 struct device_attribute *devattr,
1662 char *buf)
1663{
1664 int result;
1665 struct f71882fg_data *data = f71882fg_update_device(dev);
1666 int pwm = to_sensor_dev_attr_2(devattr)->index;
1667 int point = to_sensor_dev_attr_2(devattr)->nr;
1668
1669 result = data->pwm_auto_point_temp[pwm][point];
1670 return sprintf(buf, "%d\n", 1000 * result);
1671}
1672
1673static ssize_t store_pwm_auto_point_temp(struct device *dev,
1674 struct device_attribute *devattr,
1675 const char *buf, size_t count)
1676{
1677 struct f71882fg_data *data = dev_get_drvdata(dev);
1678 int pwm = to_sensor_dev_attr_2(devattr)->index;
1679 int point = to_sensor_dev_attr_2(devattr)->nr;
1680 long val = simple_strtol(buf, NULL, 10) / 1000;
1681 val = SENSORS_LIMIT(val, 0, 255);
1682
1683 mutex_lock(&data->update_lock);
1684 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
1685 data->pwm_auto_point_temp[pwm][point] = val;
1686 mutex_unlock(&data->update_lock);
1687
1688 return count;
1689}
1690
736static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 1691static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
737 char *buf) 1692 char *buf)
738{ 1693{
739 return sprintf(buf, DRVNAME "\n"); 1694 struct f71882fg_data *data = dev_get_drvdata(dev);
1695 return sprintf(buf, "%s\n", f71882fg_names[data->type]);
740} 1696}
741 1697
1698static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1699 struct sensor_device_attribute_2 *attr, int count)
1700{
1701 int err, i;
1702
1703 for (i = 0; i < count; i++) {
1704 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
1705 if (err)
1706 return err;
1707 }
1708 return 0;
1709}
742 1710
743static int __devinit f71882fg_probe(struct platform_device * pdev) 1711static int __devinit f71882fg_probe(struct platform_device *pdev)
744{ 1712{
745 struct f71882fg_data *data; 1713 struct f71882fg_data *data;
746 int err, i; 1714 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1715 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
747 u8 start_reg; 1716 u8 start_reg;
748 1717
749 if (!(data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL))) 1718 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1719 if (!data)
750 return -ENOMEM; 1720 return -ENOMEM;
751 1721
752 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 1722 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1723 data->type = sio_data->type;
753 mutex_init(&data->update_lock); 1724 mutex_init(&data->update_lock);
754 platform_set_drvdata(pdev, data); 1725 platform_set_drvdata(pdev, data);
755 1726
756 /* Register sysfs interface files */ 1727 start_reg = f71882fg_read8(data, F71882FG_REG_START);
757 for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) { 1728 if (start_reg & 0x04) {
758 err = device_create_file(&pdev->dev, &f71882fg_dev_attr[i]); 1729 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
759 if (err) 1730 err = -ENODEV;
760 goto exit_unregister_sysfs; 1731 goto exit_free;
1732 }
1733 if (!(start_reg & 0x03)) {
1734 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
1735 err = -ENODEV;
1736 goto exit_free;
761 } 1737 }
762 1738
763 start_reg = f71882fg_read8(data, F71882FG_REG_START); 1739 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1740 /* If it is a 71862 and the fan / pwm part is enabled sanity check
1741 the pwm settings */
1742 if (data->type == f71862fg && (start_reg & 0x02)) {
1743 if ((data->pwm_enable & 0x15) != 0x15) {
1744 dev_err(&pdev->dev,
1745 "Invalid (reserved) pwm settings: 0x%02x\n",
1746 (unsigned int)data->pwm_enable);
1747 err = -ENODEV;
1748 goto exit_free;
1749 }
1750 }
1751
1752 /* Register sysfs interface files */
1753 err = device_create_file(&pdev->dev, &dev_attr_name);
1754 if (err)
1755 goto exit_unregister_sysfs;
1756
764 if (start_reg & 0x01) { 1757 if (start_reg & 0x01) {
765 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) { 1758 switch (data->type) {
766 err = device_create_file(&pdev->dev, 1759 case f71882fg:
767 &f71882fg_in_temp_attr[i].dev_attr); 1760 err = f71882fg_create_sysfs_files(pdev,
1761 f71882fg_in_temp_attr,
1762 ARRAY_SIZE(f71882fg_in_temp_attr));
768 if (err) 1763 if (err)
769 goto exit_unregister_sysfs; 1764 goto exit_unregister_sysfs;
1765 /* fall through! */
1766 case f71862fg:
1767 err = f71882fg_create_sysfs_files(pdev,
1768 f718x2fg_in_temp_attr,
1769 ARRAY_SIZE(f718x2fg_in_temp_attr));
1770 break;
1771 case f8000:
1772 err = f71882fg_create_sysfs_files(pdev,
1773 f8000_in_temp_attr,
1774 ARRAY_SIZE(f8000_in_temp_attr));
1775 break;
770 } 1776 }
1777 if (err)
1778 goto exit_unregister_sysfs;
771 } 1779 }
772 1780
773 if (start_reg & 0x02) { 1781 if (start_reg & 0x02) {
774 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) { 1782 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
775 err = device_create_file(&pdev->dev, 1783 ARRAY_SIZE(fxxxx_fan_attr));
776 &f71882fg_fan_attr[i].dev_attr); 1784 if (err)
777 if (err) 1785 goto exit_unregister_sysfs;
778 goto exit_unregister_sysfs; 1786
1787 switch (data->type) {
1788 case f71862fg:
1789 err = f71882fg_create_sysfs_files(pdev,
1790 f71862fg_fan_attr,
1791 ARRAY_SIZE(f71862fg_fan_attr));
1792 break;
1793 case f71882fg:
1794 err = f71882fg_create_sysfs_files(pdev,
1795 f71882fg_fan_attr,
1796 ARRAY_SIZE(f71882fg_fan_attr));
1797 break;
1798 case f8000:
1799 err = f71882fg_create_sysfs_files(pdev,
1800 f8000_fan_attr,
1801 ARRAY_SIZE(f8000_fan_attr));
1802 break;
779 } 1803 }
1804 if (err)
1805 goto exit_unregister_sysfs;
1806
1807 for (i = 0; i < nr_fans; i++)
1808 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
1809 (data->pwm_enable & (1 << 2 * i)) ?
1810 "duty-cycle" : "RPM");
780 } 1811 }
781 1812
782 data->hwmon_dev = hwmon_device_register(&pdev->dev); 1813 data->hwmon_dev = hwmon_device_register(&pdev->dev);
783 if (IS_ERR(data->hwmon_dev)) { 1814 if (IS_ERR(data->hwmon_dev)) {
784 err = PTR_ERR(data->hwmon_dev); 1815 err = PTR_ERR(data->hwmon_dev);
1816 data->hwmon_dev = NULL;
785 goto exit_unregister_sysfs; 1817 goto exit_unregister_sysfs;
786 } 1818 }
787 1819
788 return 0; 1820 return 0;
789 1821
790exit_unregister_sysfs: 1822exit_unregister_sysfs:
791 for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) 1823 f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
792 device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); 1824 return err; /* f71882fg_remove() also frees our data */
793 1825exit_free:
794 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
795 device_remove_file(&pdev->dev,
796 &f71882fg_in_temp_attr[i].dev_attr);
797
798 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
799 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
800
801 kfree(data); 1826 kfree(data);
802
803 return err; 1827 return err;
804} 1828}
805 1829
806static int __devexit f71882fg_remove(struct platform_device *pdev) 1830static int f71882fg_remove(struct platform_device *pdev)
807{ 1831{
808 int i; 1832 int i;
809 struct f71882fg_data *data = platform_get_drvdata(pdev); 1833 struct f71882fg_data *data = platform_get_drvdata(pdev);
810 1834
811 platform_set_drvdata(pdev, NULL); 1835 platform_set_drvdata(pdev, NULL);
812 hwmon_device_unregister(data->hwmon_dev); 1836 if (data->hwmon_dev)
1837 hwmon_device_unregister(data->hwmon_dev);
1838
1839 /* Note we are not looping over all attr arrays we have as the ones
1840 below are supersets of the ones skipped. */
1841 device_remove_file(&pdev->dev, &dev_attr_name);
813 1842
814 for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) 1843 for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
815 device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); 1844 device_remove_file(&pdev->dev,
1845 &f718x2fg_in_temp_attr[i].dev_attr);
816 1846
817 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) 1847 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
818 device_remove_file(&pdev->dev, 1848 device_remove_file(&pdev->dev,
819 &f71882fg_in_temp_attr[i].dev_attr); 1849 &f71882fg_in_temp_attr[i].dev_attr);
820 1850
1851 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
1852 device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
1853
821 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) 1854 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
822 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); 1855 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
823 1856
1857 for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
1858 device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
1859
824 kfree(data); 1860 kfree(data);
825 1861
826 return 0; 1862 return 0;
827} 1863}
828 1864
829static int __init f71882fg_find(int sioaddr, unsigned short *address) 1865static int __init f71882fg_find(int sioaddr, unsigned short *address,
1866 struct f71882fg_sio_data *sio_data)
830{ 1867{
831 int err = -ENODEV; 1868 int err = -ENODEV;
832 u16 devid; 1869 u16 devid;
833 u8 start_reg;
834 struct f71882fg_data data;
835 1870
836 superio_enter(sioaddr); 1871 superio_enter(sioaddr);
837 1872
@@ -842,7 +1877,17 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address)
842 } 1877 }
843 1878
844 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 1879 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
845 if (devid != SIO_F71882_ID) { 1880 switch (devid) {
1881 case SIO_F71862_ID:
1882 sio_data->type = f71862fg;
1883 break;
1884 case SIO_F71882_ID:
1885 sio_data->type = f71882fg;
1886 break;
1887 case SIO_F8000_ID:
1888 sio_data->type = f8000;
1889 break;
1890 default:
846 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 1891 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
847 goto exit; 1892 goto exit;
848 } 1893 }
@@ -861,24 +1906,17 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address)
861 } 1906 }
862 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ 1907 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
863 1908
864 data.addr = *address;
865 start_reg = f71882fg_read8(&data, F71882FG_REG_START);
866 if (!(start_reg & 0x03)) {
867 printk(KERN_WARNING DRVNAME
868 ": Hardware monitoring not activated\n");
869 goto exit;
870 }
871
872 err = 0; 1909 err = 0;
873 printk(KERN_INFO DRVNAME ": Found F71882FG chip at %#x, revision %d\n", 1910 printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
874 (unsigned int)*address, 1911 f71882fg_names[sio_data->type], (unsigned int)*address,
875 (int)superio_inb(sioaddr, SIO_REG_DEVREV)); 1912 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
876exit: 1913exit:
877 superio_exit(sioaddr); 1914 superio_exit(sioaddr);
878 return err; 1915 return err;
879} 1916}
880 1917
881static int __init f71882fg_device_add(unsigned short address) 1918static int __init f71882fg_device_add(unsigned short address,
1919 const struct f71882fg_sio_data *sio_data)
882{ 1920{
883 struct resource res = { 1921 struct resource res = {
884 .start = address, 1922 .start = address,
@@ -892,12 +1930,23 @@ static int __init f71882fg_device_add(unsigned short address)
892 return -ENOMEM; 1930 return -ENOMEM;
893 1931
894 res.name = f71882fg_pdev->name; 1932 res.name = f71882fg_pdev->name;
1933 err = acpi_check_resource_conflict(&res);
1934 if (err)
1935 return err;
1936
895 err = platform_device_add_resources(f71882fg_pdev, &res, 1); 1937 err = platform_device_add_resources(f71882fg_pdev, &res, 1);
896 if (err) { 1938 if (err) {
897 printk(KERN_ERR DRVNAME ": Device resource addition failed\n"); 1939 printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
898 goto exit_device_put; 1940 goto exit_device_put;
899 } 1941 }
900 1942
1943 err = platform_device_add_data(f71882fg_pdev, sio_data,
1944 sizeof(struct f71882fg_sio_data));
1945 if (err) {
1946 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
1947 goto exit_device_put;
1948 }
1949
901 err = platform_device_add(f71882fg_pdev); 1950 err = platform_device_add(f71882fg_pdev);
902 if (err) { 1951 if (err) {
903 printk(KERN_ERR DRVNAME ": Device addition failed\n"); 1952 printk(KERN_ERR DRVNAME ": Device addition failed\n");
@@ -916,14 +1965,20 @@ static int __init f71882fg_init(void)
916{ 1965{
917 int err = -ENODEV; 1966 int err = -ENODEV;
918 unsigned short address; 1967 unsigned short address;
1968 struct f71882fg_sio_data sio_data;
1969
1970 memset(&sio_data, 0, sizeof(sio_data));
919 1971
920 if (f71882fg_find(0x2e, &address) && f71882fg_find(0x4e, &address)) 1972 if (f71882fg_find(0x2e, &address, &sio_data) &&
1973 f71882fg_find(0x4e, &address, &sio_data))
921 goto exit; 1974 goto exit;
922 1975
923 if ((err = platform_driver_register(&f71882fg_driver))) 1976 err = platform_driver_register(&f71882fg_driver);
1977 if (err)
924 goto exit; 1978 goto exit;
925 1979
926 if ((err = f71882fg_device_add(address))) 1980 err = f71882fg_device_add(address, &sio_data);
1981 if (err)
927 goto exit_driver; 1982 goto exit_driver;
928 1983
929 return 0; 1984 return 0;
@@ -941,7 +1996,7 @@ static void __exit f71882fg_exit(void)
941} 1996}
942 1997
943MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver"); 1998MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
944MODULE_AUTHOR("Hans Edgington (hans@edgington.nl)"); 1999MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
945MODULE_LICENSE("GPL"); 2000MODULE_LICENSE("GPL");
946 2001
947module_init(f71882fg_init); 2002module_init(f71882fg_init);
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index 967170368933..d07f4ef75092 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -1,6 +1,6 @@
1/* fschmd.c 1/* fschmd.c
2 * 2 *
3 * Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl> 3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License as published by
@@ -42,11 +42,20 @@
42#include <linux/mutex.h> 42#include <linux/mutex.h>
43#include <linux/sysfs.h> 43#include <linux/sysfs.h>
44#include <linux/dmi.h> 44#include <linux/dmi.h>
45#include <linux/fs.h>
46#include <linux/watchdog.h>
47#include <linux/miscdevice.h>
48#include <linux/uaccess.h>
49#include <linux/kref.h>
45 50
46/* Addresses to scan */ 51/* Addresses to scan */
47static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; 52static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
48 53
49/* Insmod parameters */ 54/* Insmod parameters */
55static int nowayout = WATCHDOG_NOWAYOUT;
56module_param(nowayout, int, 0);
57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
50I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd); 59I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
51 60
52/* 61/*
@@ -63,19 +72,26 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
63#define FSCHMD_REG_EVENT_STATE 0x04 72#define FSCHMD_REG_EVENT_STATE 0x04
64#define FSCHMD_REG_CONTROL 0x05 73#define FSCHMD_REG_CONTROL 0x05
65 74
66#define FSCHMD_CONTROL_ALERT_LED_MASK 0x01 75#define FSCHMD_CONTROL_ALERT_LED 0x01
67 76
68/* watchdog (support to be implemented) */ 77/* watchdog */
69#define FSCHMD_REG_WDOG_PRESET 0x28 78#define FSCHMD_REG_WDOG_PRESET 0x28
70#define FSCHMD_REG_WDOG_STATE 0x23 79#define FSCHMD_REG_WDOG_STATE 0x23
71#define FSCHMD_REG_WDOG_CONTROL 0x21 80#define FSCHMD_REG_WDOG_CONTROL 0x21
72 81
82#define FSCHMD_WDOG_CONTROL_TRIGGER 0x10
83#define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */
84#define FSCHMD_WDOG_CONTROL_STOP 0x20
85#define FSCHMD_WDOG_CONTROL_RESOLUTION 0x40
86
87#define FSCHMD_WDOG_STATE_CARDRESET 0x02
88
73/* voltages, weird order is to keep the same order as the old drivers */ 89/* voltages, weird order is to keep the same order as the old drivers */
74static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 }; 90static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
75 91
76/* minimum pwm at which the fan is driven (pwm can by increased depending on 92/* minimum pwm at which the fan is driven (pwm can by increased depending on
77 the temp. Notice that for the scy some fans share there minimum speed. 93 the temp. Notice that for the scy some fans share there minimum speed.
78 Also notice that with the scy the sensor order is different then with the 94 Also notice that with the scy the sensor order is different than with the
79 other chips, this order was in the 2.4 driver and kept for consistency. */ 95 other chips, this order was in the 2.4 driver and kept for consistency. */
80static const u8 FSCHMD_REG_FAN_MIN[5][6] = { 96static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
81 { 0x55, 0x65 }, /* pos */ 97 { 0x55, 0x65 }, /* pos */
@@ -115,8 +131,8 @@ static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
115static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 }; 131static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
116 132
117/* Fan status register bitmasks */ 133/* Fan status register bitmasks */
118#define FSCHMD_FAN_ALARM_MASK 0x04 /* called fault by FSC! */ 134#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */
119#define FSCHMD_FAN_NOT_PRESENT_MASK 0x08 /* not documented */ 135#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */
120 136
121 137
122/* actual temperature registers */ 138/* actual temperature registers */
@@ -158,14 +174,11 @@ static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
158static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 }; 174static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
159 175
160/* temp status register bitmasks */ 176/* temp status register bitmasks */
161#define FSCHMD_TEMP_WORKING_MASK 0x01 177#define FSCHMD_TEMP_WORKING 0x01
162#define FSCHMD_TEMP_ALERT_MASK 0x02 178#define FSCHMD_TEMP_ALERT 0x02
163/* there only really is an alarm if the sensor is working and alert == 1 */ 179/* there only really is an alarm if the sensor is working and alert == 1 */
164#define FSCHMD_TEMP_ALARM_MASK \ 180#define FSCHMD_TEMP_ALARM_MASK \
165 (FSCHMD_TEMP_WORKING_MASK | FSCHMD_TEMP_ALERT_MASK) 181 (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
166
167/* our driver name */
168#define FSCHMD_NAME "fschmd"
169 182
170/* 183/*
171 * Functions declarations 184 * Functions declarations
@@ -195,7 +208,7 @@ MODULE_DEVICE_TABLE(i2c, fschmd_id);
195static struct i2c_driver fschmd_driver = { 208static struct i2c_driver fschmd_driver = {
196 .class = I2C_CLASS_HWMON, 209 .class = I2C_CLASS_HWMON,
197 .driver = { 210 .driver = {
198 .name = FSCHMD_NAME, 211 .name = "fschmd",
199 }, 212 },
200 .probe = fschmd_probe, 213 .probe = fschmd_probe,
201 .remove = fschmd_remove, 214 .remove = fschmd_remove,
@@ -209,14 +222,26 @@ static struct i2c_driver fschmd_driver = {
209 */ 222 */
210 223
211struct fschmd_data { 224struct fschmd_data {
225 struct i2c_client *client;
212 struct device *hwmon_dev; 226 struct device *hwmon_dev;
213 struct mutex update_lock; 227 struct mutex update_lock;
228 struct mutex watchdog_lock;
229 struct list_head list; /* member of the watchdog_data_list */
230 struct kref kref;
231 struct miscdevice watchdog_miscdev;
214 int kind; 232 int kind;
233 unsigned long watchdog_is_open;
234 char watchdog_expect_close;
235 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
215 char valid; /* zero until following fields are valid */ 236 char valid; /* zero until following fields are valid */
216 unsigned long last_updated; /* in jiffies */ 237 unsigned long last_updated; /* in jiffies */
217 238
218 /* register values */ 239 /* register values */
240 u8 revision; /* chip revision */
219 u8 global_control; /* global control register */ 241 u8 global_control; /* global control register */
242 u8 watchdog_control; /* watchdog control register */
243 u8 watchdog_state; /* watchdog status register */
244 u8 watchdog_preset; /* watchdog counter preset on trigger val */
220 u8 volt[3]; /* 12, 5, battery voltage */ 245 u8 volt[3]; /* 12, 5, battery voltage */
221 u8 temp_act[5]; /* temperature */ 246 u8 temp_act[5]; /* temperature */
222 u8 temp_status[5]; /* status of sensor */ 247 u8 temp_status[5]; /* status of sensor */
@@ -228,11 +253,28 @@ struct fschmd_data {
228}; 253};
229 254
230/* Global variables to hold information read from special DMI tables, which are 255/* Global variables to hold information read from special DMI tables, which are
231 available on FSC machines with an fscher or later chip. */ 256 available on FSC machines with an fscher or later chip. There is no need to
257 protect these with a lock as they are only modified from our attach function
258 which always gets called with the i2c-core lock held and never accessed
259 before the attach function is done with them. */
232static int dmi_mult[3] = { 490, 200, 100 }; 260static int dmi_mult[3] = { 490, 200, 100 };
233static int dmi_offset[3] = { 0, 0, 0 }; 261static int dmi_offset[3] = { 0, 0, 0 };
234static int dmi_vref = -1; 262static int dmi_vref = -1;
235 263
264/* Somewhat ugly :( global data pointer list with all fschmd devices, so that
265 we can find our device data as when using misc_register there is no other
266 method to get to ones device data from the open fop. */
267static LIST_HEAD(watchdog_data_list);
268/* Note this lock not only protect list access, but also data.kref access */
269static DEFINE_MUTEX(watchdog_data_mutex);
270
271/* Release our data struct when we're detached from the i2c client *and* all
272 references to our watchdog device are released */
273static void fschmd_release_resources(struct kref *ref)
274{
275 struct fschmd_data *data = container_of(ref, struct fschmd_data, kref);
276 kfree(data);
277}
236 278
237/* 279/*
238 * Sysfs attr show / store functions 280 * Sysfs attr show / store functions
@@ -300,7 +342,7 @@ static ssize_t show_temp_fault(struct device *dev,
300 struct fschmd_data *data = fschmd_update_device(dev); 342 struct fschmd_data *data = fschmd_update_device(dev);
301 343
302 /* bit 0 set means sensor working ok, so no fault! */ 344 /* bit 0 set means sensor working ok, so no fault! */
303 if (data->temp_status[index] & FSCHMD_TEMP_WORKING_MASK) 345 if (data->temp_status[index] & FSCHMD_TEMP_WORKING)
304 return sprintf(buf, "0\n"); 346 return sprintf(buf, "0\n");
305 else 347 else
306 return sprintf(buf, "1\n"); 348 return sprintf(buf, "1\n");
@@ -385,7 +427,7 @@ static ssize_t show_fan_alarm(struct device *dev,
385 int index = to_sensor_dev_attr(devattr)->index; 427 int index = to_sensor_dev_attr(devattr)->index;
386 struct fschmd_data *data = fschmd_update_device(dev); 428 struct fschmd_data *data = fschmd_update_device(dev);
387 429
388 if (data->fan_status[index] & FSCHMD_FAN_ALARM_MASK) 430 if (data->fan_status[index] & FSCHMD_FAN_ALARM)
389 return sprintf(buf, "1\n"); 431 return sprintf(buf, "1\n");
390 else 432 else
391 return sprintf(buf, "0\n"); 433 return sprintf(buf, "0\n");
@@ -397,7 +439,7 @@ static ssize_t show_fan_fault(struct device *dev,
397 int index = to_sensor_dev_attr(devattr)->index; 439 int index = to_sensor_dev_attr(devattr)->index;
398 struct fschmd_data *data = fschmd_update_device(dev); 440 struct fschmd_data *data = fschmd_update_device(dev);
399 441
400 if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT_MASK) 442 if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT)
401 return sprintf(buf, "1\n"); 443 return sprintf(buf, "1\n");
402 else 444 else
403 return sprintf(buf, "0\n"); 445 return sprintf(buf, "0\n");
@@ -449,7 +491,7 @@ static ssize_t show_alert_led(struct device *dev,
449{ 491{
450 struct fschmd_data *data = fschmd_update_device(dev); 492 struct fschmd_data *data = fschmd_update_device(dev);
451 493
452 if (data->global_control & FSCHMD_CONTROL_ALERT_LED_MASK) 494 if (data->global_control & FSCHMD_CONTROL_ALERT_LED)
453 return sprintf(buf, "1\n"); 495 return sprintf(buf, "1\n");
454 else 496 else
455 return sprintf(buf, "0\n"); 497 return sprintf(buf, "0\n");
@@ -467,9 +509,9 @@ static ssize_t store_alert_led(struct device *dev,
467 reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL); 509 reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
468 510
469 if (v) 511 if (v)
470 reg |= FSCHMD_CONTROL_ALERT_LED_MASK; 512 reg |= FSCHMD_CONTROL_ALERT_LED;
471 else 513 else
472 reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK; 514 reg &= ~FSCHMD_CONTROL_ALERT_LED;
473 515
474 i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg); 516 i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
475 517
@@ -551,7 +593,265 @@ static struct sensor_device_attribute fschmd_fan_attr[] = {
551 593
552 594
553/* 595/*
554 * Real code 596 * Watchdog routines
597 */
598
599static int watchdog_set_timeout(struct fschmd_data *data, int timeout)
600{
601 int ret, resolution;
602 int kind = data->kind + 1; /* 0-x array index -> 1-x module param */
603
604 /* 2 second or 60 second resolution? */
605 if (timeout <= 510 || kind == fscpos || kind == fscscy)
606 resolution = 2;
607 else
608 resolution = 60;
609
610 if (timeout < resolution || timeout > (resolution * 255))
611 return -EINVAL;
612
613 mutex_lock(&data->watchdog_lock);
614 if (!data->client) {
615 ret = -ENODEV;
616 goto leave;
617 }
618
619 if (resolution == 2)
620 data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_RESOLUTION;
621 else
622 data->watchdog_control |= FSCHMD_WDOG_CONTROL_RESOLUTION;
623
624 data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
625
626 /* Write new timeout value */
627 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET,
628 data->watchdog_preset);
629 /* Write new control register, do not trigger! */
630 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
631 data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER);
632
633 ret = data->watchdog_preset * resolution;
634
635leave:
636 mutex_unlock(&data->watchdog_lock);
637 return ret;
638}
639
640static int watchdog_get_timeout(struct fschmd_data *data)
641{
642 int timeout;
643
644 mutex_lock(&data->watchdog_lock);
645 if (data->watchdog_control & FSCHMD_WDOG_CONTROL_RESOLUTION)
646 timeout = data->watchdog_preset * 60;
647 else
648 timeout = data->watchdog_preset * 2;
649 mutex_unlock(&data->watchdog_lock);
650
651 return timeout;
652}
653
654static int watchdog_trigger(struct fschmd_data *data)
655{
656 int ret = 0;
657
658 mutex_lock(&data->watchdog_lock);
659 if (!data->client) {
660 ret = -ENODEV;
661 goto leave;
662 }
663
664 data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER;
665 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
666 data->watchdog_control);
667leave:
668 mutex_unlock(&data->watchdog_lock);
669 return ret;
670}
671
672static int watchdog_stop(struct fschmd_data *data)
673{
674 int ret = 0;
675
676 mutex_lock(&data->watchdog_lock);
677 if (!data->client) {
678 ret = -ENODEV;
679 goto leave;
680 }
681
682 data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
683 /* Don't store the stop flag in our watchdog control register copy, as
684 its a write only bit (read always returns 0) */
685 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
686 data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
687leave:
688 mutex_unlock(&data->watchdog_lock);
689 return ret;
690}
691
692static int watchdog_open(struct inode *inode, struct file *filp)
693{
694 struct fschmd_data *pos, *data = NULL;
695
696 /* We get called from drivers/char/misc.c with misc_mtx hold, and we
697 call misc_register() from fschmd_probe() with watchdog_data_mutex
698 hold, as misc_register() takes the misc_mtx lock, this is a possible
699 deadlock, so we use mutex_trylock here. */
700 if (!mutex_trylock(&watchdog_data_mutex))
701 return -ERESTARTSYS;
702 list_for_each_entry(pos, &watchdog_data_list, list) {
703 if (pos->watchdog_miscdev.minor == iminor(inode)) {
704 data = pos;
705 break;
706 }
707 }
708 /* Note we can never not have found data, so we don't check for this */
709 kref_get(&data->kref);
710 mutex_unlock(&watchdog_data_mutex);
711
712 if (test_and_set_bit(0, &data->watchdog_is_open))
713 return -EBUSY;
714
715 /* Start the watchdog */
716 watchdog_trigger(data);
717 filp->private_data = data;
718
719 return nonseekable_open(inode, filp);
720}
721
722static int watchdog_release(struct inode *inode, struct file *filp)
723{
724 struct fschmd_data *data = filp->private_data;
725
726 if (data->watchdog_expect_close) {
727 watchdog_stop(data);
728 data->watchdog_expect_close = 0;
729 } else {
730 watchdog_trigger(data);
731 dev_crit(&data->client->dev,
732 "unexpected close, not stopping watchdog!\n");
733 }
734
735 clear_bit(0, &data->watchdog_is_open);
736
737 mutex_lock(&watchdog_data_mutex);
738 kref_put(&data->kref, fschmd_release_resources);
739 mutex_unlock(&watchdog_data_mutex);
740
741 return 0;
742}
743
744static ssize_t watchdog_write(struct file *filp, const char __user *buf,
745 size_t count, loff_t *offset)
746{
747 size_t ret;
748 struct fschmd_data *data = filp->private_data;
749
750 if (count) {
751 if (!nowayout) {
752 size_t i;
753
754 /* Clear it in case it was set with a previous write */
755 data->watchdog_expect_close = 0;
756
757 for (i = 0; i != count; i++) {
758 char c;
759 if (get_user(c, buf + i))
760 return -EFAULT;
761 if (c == 'V')
762 data->watchdog_expect_close = 1;
763 }
764 }
765 ret = watchdog_trigger(data);
766 if (ret < 0)
767 return ret;
768 }
769 return count;
770}
771
772static int watchdog_ioctl(struct inode *inode, struct file *filp,
773 unsigned int cmd, unsigned long arg)
774{
775 static struct watchdog_info ident = {
776 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
777 WDIOF_CARDRESET,
778 .identity = "FSC watchdog"
779 };
780 int i, ret = 0;
781 struct fschmd_data *data = filp->private_data;
782
783 switch (cmd) {
784 case WDIOC_GETSUPPORT:
785 ident.firmware_version = data->revision;
786 if (!nowayout)
787 ident.options |= WDIOF_MAGICCLOSE;
788 if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
789 ret = -EFAULT;
790 break;
791
792 case WDIOC_GETSTATUS:
793 ret = put_user(0, (int __user *)arg);
794 break;
795
796 case WDIOC_GETBOOTSTATUS:
797 if (data->watchdog_state & FSCHMD_WDOG_STATE_CARDRESET)
798 ret = put_user(WDIOF_CARDRESET, (int __user *)arg);
799 else
800 ret = put_user(0, (int __user *)arg);
801 break;
802
803 case WDIOC_KEEPALIVE:
804 ret = watchdog_trigger(data);
805 break;
806
807 case WDIOC_GETTIMEOUT:
808 i = watchdog_get_timeout(data);
809 ret = put_user(i, (int __user *)arg);
810 break;
811
812 case WDIOC_SETTIMEOUT:
813 if (get_user(i, (int __user *)arg)) {
814 ret = -EFAULT;
815 break;
816 }
817 ret = watchdog_set_timeout(data, i);
818 if (ret > 0)
819 ret = put_user(ret, (int __user *)arg);
820 break;
821
822 case WDIOC_SETOPTIONS:
823 if (get_user(i, (int __user *)arg)) {
824 ret = -EFAULT;
825 break;
826 }
827
828 if (i & WDIOS_DISABLECARD)
829 ret = watchdog_stop(data);
830 else if (i & WDIOS_ENABLECARD)
831 ret = watchdog_trigger(data);
832 else
833 ret = -EINVAL;
834
835 break;
836 default:
837 ret = -ENOTTY;
838 }
839
840 return ret;
841}
842
843static struct file_operations watchdog_fops = {
844 .owner = THIS_MODULE,
845 .llseek = no_llseek,
846 .open = watchdog_open,
847 .release = watchdog_release,
848 .write = watchdog_write,
849 .ioctl = watchdog_ioctl,
850};
851
852
853/*
854 * Detect, register, unregister and update device functions
555 */ 855 */
556 856
557/* DMI decode routine to read voltage scaling factors from special DMI tables, 857/* DMI decode routine to read voltage scaling factors from special DMI tables,
@@ -661,9 +961,9 @@ static int fschmd_probe(struct i2c_client *client,
661 const struct i2c_device_id *id) 961 const struct i2c_device_id *id)
662{ 962{
663 struct fschmd_data *data; 963 struct fschmd_data *data;
664 u8 revision;
665 const char * const names[5] = { "Poseidon", "Hermes", "Scylla", 964 const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
666 "Heracles", "Heimdall" }; 965 "Heracles", "Heimdall" };
966 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
667 int i, err; 967 int i, err;
668 enum chips kind = id->driver_data; 968 enum chips kind = id->driver_data;
669 969
@@ -673,6 +973,13 @@ static int fschmd_probe(struct i2c_client *client,
673 973
674 i2c_set_clientdata(client, data); 974 i2c_set_clientdata(client, data);
675 mutex_init(&data->update_lock); 975 mutex_init(&data->update_lock);
976 mutex_init(&data->watchdog_lock);
977 INIT_LIST_HEAD(&data->list);
978 kref_init(&data->kref);
979 /* Store client pointer in our data struct for watchdog usage
980 (where the client is found through a data ptr instead of the
981 otherway around) */
982 data->client = client;
676 983
677 if (kind == fscpos) { 984 if (kind == fscpos) {
678 /* The Poseidon has hardwired temp limits, fill these 985 /* The Poseidon has hardwired temp limits, fill these
@@ -683,16 +990,27 @@ static int fschmd_probe(struct i2c_client *client,
683 } 990 }
684 991
685 /* Read the special DMI table for fscher and newer chips */ 992 /* Read the special DMI table for fscher and newer chips */
686 if (kind == fscher || kind >= fschrc) { 993 if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
687 dmi_walk(fschmd_dmi_decode); 994 dmi_walk(fschmd_dmi_decode);
688 if (dmi_vref == -1) { 995 if (dmi_vref == -1) {
689 printk(KERN_WARNING FSCHMD_NAME 996 dev_warn(&client->dev,
690 ": Couldn't get voltage scaling factors from " 997 "Couldn't get voltage scaling factors from "
691 "BIOS DMI table, using builtin defaults\n"); 998 "BIOS DMI table, using builtin defaults\n");
692 dmi_vref = 33; 999 dmi_vref = 33;
693 } 1000 }
694 } 1001 }
695 1002
1003 /* Read in some never changing registers */
1004 data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
1005 data->global_control = i2c_smbus_read_byte_data(client,
1006 FSCHMD_REG_CONTROL);
1007 data->watchdog_control = i2c_smbus_read_byte_data(client,
1008 FSCHMD_REG_WDOG_CONTROL);
1009 data->watchdog_state = i2c_smbus_read_byte_data(client,
1010 FSCHMD_REG_WDOG_STATE);
1011 data->watchdog_preset = i2c_smbus_read_byte_data(client,
1012 FSCHMD_REG_WDOG_PRESET);
1013
696 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */ 1014 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
697 data->kind = kind - 1; 1015 data->kind = kind - 1;
698 1016
@@ -735,9 +1053,43 @@ static int fschmd_probe(struct i2c_client *client,
735 goto exit_detach; 1053 goto exit_detach;
736 } 1054 }
737 1055
738 revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); 1056 /* We take the data_mutex lock early so that watchdog_open() cannot
739 printk(KERN_INFO FSCHMD_NAME ": Detected FSC %s chip, revision: %d\n", 1057 run when misc_register() has completed, but we've not yet added
740 names[data->kind], (int) revision); 1058 our data to the watchdog_data_list (and set the default timeout) */
1059 mutex_lock(&watchdog_data_mutex);
1060 for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
1061 /* Register our watchdog part */
1062 snprintf(data->watchdog_name, sizeof(data->watchdog_name),
1063 "watchdog%c", (i == 0) ? '\0' : ('0' + i));
1064 data->watchdog_miscdev.name = data->watchdog_name;
1065 data->watchdog_miscdev.fops = &watchdog_fops;
1066 data->watchdog_miscdev.minor = watchdog_minors[i];
1067 err = misc_register(&data->watchdog_miscdev);
1068 if (err == -EBUSY)
1069 continue;
1070 if (err) {
1071 data->watchdog_miscdev.minor = 0;
1072 dev_err(&client->dev,
1073 "Registering watchdog chardev: %d\n", err);
1074 break;
1075 }
1076
1077 list_add(&data->list, &watchdog_data_list);
1078 watchdog_set_timeout(data, 60);
1079 dev_info(&client->dev,
1080 "Registered watchdog chardev major 10, minor: %d\n",
1081 watchdog_minors[i]);
1082 break;
1083 }
1084 if (i == ARRAY_SIZE(watchdog_minors)) {
1085 data->watchdog_miscdev.minor = 0;
1086 dev_warn(&client->dev, "Couldn't register watchdog chardev "
1087 "(due to no free minor)\n");
1088 }
1089 mutex_unlock(&watchdog_data_mutex);
1090
1091 dev_info(&client->dev, "Detected FSC %s chip, revision: %d\n",
1092 names[data->kind], (int) data->revision);
741 1093
742 return 0; 1094 return 0;
743 1095
@@ -751,6 +1103,24 @@ static int fschmd_remove(struct i2c_client *client)
751 struct fschmd_data *data = i2c_get_clientdata(client); 1103 struct fschmd_data *data = i2c_get_clientdata(client);
752 int i; 1104 int i;
753 1105
1106 /* Unregister the watchdog (if registered) */
1107 if (data->watchdog_miscdev.minor) {
1108 misc_deregister(&data->watchdog_miscdev);
1109 if (data->watchdog_is_open) {
1110 dev_warn(&client->dev,
1111 "i2c client detached with watchdog open! "
1112 "Stopping watchdog.\n");
1113 watchdog_stop(data);
1114 }
1115 mutex_lock(&watchdog_data_mutex);
1116 list_del(&data->list);
1117 mutex_unlock(&watchdog_data_mutex);
1118 /* Tell the watchdog code the client is gone */
1119 mutex_lock(&data->watchdog_lock);
1120 data->client = NULL;
1121 mutex_unlock(&data->watchdog_lock);
1122 }
1123
754 /* Check if registered in case we're called from fschmd_detect 1124 /* Check if registered in case we're called from fschmd_detect
755 to cleanup after an error */ 1125 to cleanup after an error */
756 if (data->hwmon_dev) 1126 if (data->hwmon_dev)
@@ -765,7 +1135,10 @@ static int fschmd_remove(struct i2c_client *client)
765 device_remove_file(&client->dev, 1135 device_remove_file(&client->dev,
766 &fschmd_fan_attr[i].dev_attr); 1136 &fschmd_fan_attr[i].dev_attr);
767 1137
768 kfree(data); 1138 mutex_lock(&watchdog_data_mutex);
1139 kref_put(&data->kref, fschmd_release_resources);
1140 mutex_unlock(&watchdog_data_mutex);
1141
769 return 0; 1142 return 0;
770} 1143}
771 1144
@@ -798,7 +1171,7 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
798 data->temp_act[i] < data->temp_max[i]) 1171 data->temp_act[i] < data->temp_max[i])
799 i2c_smbus_write_byte_data(client, 1172 i2c_smbus_write_byte_data(client,
800 FSCHMD_REG_TEMP_STATE[data->kind][i], 1173 FSCHMD_REG_TEMP_STATE[data->kind][i],
801 FSCHMD_TEMP_ALERT_MASK); 1174 FSCHMD_TEMP_ALERT);
802 } 1175 }
803 1176
804 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) { 1177 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
@@ -816,28 +1189,17 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
816 FSCHMD_REG_FAN_MIN[data->kind][i]); 1189 FSCHMD_REG_FAN_MIN[data->kind][i]);
817 1190
818 /* reset fan status if speed is back to > 0 */ 1191 /* reset fan status if speed is back to > 0 */
819 if ((data->fan_status[i] & FSCHMD_FAN_ALARM_MASK) && 1192 if ((data->fan_status[i] & FSCHMD_FAN_ALARM) &&
820 data->fan_act[i]) 1193 data->fan_act[i])
821 i2c_smbus_write_byte_data(client, 1194 i2c_smbus_write_byte_data(client,
822 FSCHMD_REG_FAN_STATE[data->kind][i], 1195 FSCHMD_REG_FAN_STATE[data->kind][i],
823 FSCHMD_FAN_ALARM_MASK); 1196 FSCHMD_FAN_ALARM);
824 } 1197 }
825 1198
826 for (i = 0; i < 3; i++) 1199 for (i = 0; i < 3; i++)
827 data->volt[i] = i2c_smbus_read_byte_data(client, 1200 data->volt[i] = i2c_smbus_read_byte_data(client,
828 FSCHMD_REG_VOLT[i]); 1201 FSCHMD_REG_VOLT[i]);
829 1202
830 data->global_control = i2c_smbus_read_byte_data(client,
831 FSCHMD_REG_CONTROL);
832
833 /* To be implemented in the future
834 data->watchdog[0] = i2c_smbus_read_byte_data(client,
835 FSCHMD_REG_WDOG_PRESET);
836 data->watchdog[1] = i2c_smbus_read_byte_data(client,
837 FSCHMD_REG_WDOG_STATE);
838 data->watchdog[2] = i2c_smbus_read_byte_data(client,
839 FSCHMD_REG_WDOG_CONTROL); */
840
841 data->last_updated = jiffies; 1203 data->last_updated = jiffies;
842 data->valid = 1; 1204 data->valid = 1;
843 } 1205 }
@@ -857,7 +1219,7 @@ static void __exit fschmd_exit(void)
857 i2c_del_driver(&fschmd_driver); 1219 i2c_del_driver(&fschmd_driver);
858} 1220}
859 1221
860MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); 1222MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
861MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and " 1223MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
862 "Heimdall driver"); 1224 "Heimdall driver");
863MODULE_LICENSE("GPL"); 1225MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
new file mode 100644
index 000000000000..bf8d40580577
--- /dev/null
+++ b/drivers/hwmon/hp_accel.c
@@ -0,0 +1,265 @@
1/*
2 * hp_accel.c - Interface between LIS3LV02DL driver and HP ACPI BIOS
3 *
4 * Copyright (C) 2007-2008 Yan Burman
5 * Copyright (C) 2008 Eric Piel
6 * Copyright (C) 2008 Pavel Machek
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/dmi.h>
26#include <linux/module.h>
27#include <linux/types.h>
28#include <linux/platform_device.h>
29#include <linux/interrupt.h>
30#include <linux/input.h>
31#include <linux/kthread.h>
32#include <linux/semaphore.h>
33#include <linux/delay.h>
34#include <linux/wait.h>
35#include <linux/poll.h>
36#include <linux/freezer.h>
37#include <linux/version.h>
38#include <linux/uaccess.h>
39#include <acpi/acpi_drivers.h>
40#include <asm/atomic.h>
41#include "lis3lv02d.h"
42
43#define DRIVER_NAME "lis3lv02d"
44#define ACPI_MDPS_CLASS "accelerometer"
45
46
47/* For automatic insertion of the module */
48static struct acpi_device_id lis3lv02d_device_ids[] = {
49 {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
50 {"", 0},
51};
52MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
53
54
55/**
56 * lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
57 * @handle: the handle of the device
58 *
59 * Returns AE_OK on success.
60 */
61acpi_status lis3lv02d_acpi_init(acpi_handle handle)
62{
63 return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL);
64}
65
66/**
67 * lis3lv02d_acpi_read - ACPI ALRD method: read a register
68 * @handle: the handle of the device
69 * @reg: the register to read
70 * @ret: result of the operation
71 *
72 * Returns AE_OK on success.
73 */
74acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
75{
76 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
77 struct acpi_object_list args = { 1, &arg0 };
78 unsigned long long lret;
79 acpi_status status;
80
81 arg0.integer.value = reg;
82
83 status = acpi_evaluate_integer(handle, "ALRD", &args, &lret);
84 *ret = lret;
85 return status;
86}
87
88/**
89 * lis3lv02d_acpi_write - ACPI ALWR method: write to a register
90 * @handle: the handle of the device
91 * @reg: the register to write to
92 * @val: the value to write
93 *
94 * Returns AE_OK on success.
95 */
96acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
97{
98 unsigned long long ret; /* Not used when writting */
99 union acpi_object in_obj[2];
100 struct acpi_object_list args = { 2, in_obj };
101
102 in_obj[0].type = ACPI_TYPE_INTEGER;
103 in_obj[0].integer.value = reg;
104 in_obj[1].type = ACPI_TYPE_INTEGER;
105 in_obj[1].integer.value = val;
106
107 return acpi_evaluate_integer(handle, "ALWR", &args, &ret);
108}
109
110static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
111{
112 adev.ac = *((struct axis_conversion *)dmi->driver_data);
113 printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
114
115 return 1;
116}
117
118/* Represents, for each axis seen by userspace, the corresponding hw axis (+1).
119 * If the value is negative, the opposite of the hw value is used. */
120static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3};
121static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3};
122static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3};
123static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3};
124static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3};
125static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
126
127#define AXIS_DMI_MATCH(_ident, _name, _axis) { \
128 .ident = _ident, \
129 .callback = lis3lv02d_dmi_matched, \
130 .matches = { \
131 DMI_MATCH(DMI_PRODUCT_NAME, _name) \
132 }, \
133 .driver_data = &lis3lv02d_axis_##_axis \
134}
135static struct dmi_system_id lis3lv02d_dmi_ids[] = {
136 /* product names are truncated to match all kinds of a same model */
137 AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted),
138 AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted),
139 AXIS_DMI_MATCH("NX9420", "HP Compaq nx9420", x_inverted),
140 AXIS_DMI_MATCH("NW9440", "HP Compaq nw9440", x_inverted),
141 AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
142 AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
143 AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
144 { NULL, }
145/* Laptop models without axis info (yet):
146 * "NC651xx" "HP Compaq 651"
147 * "NC671xx" "HP Compaq 671"
148 * "NC6910" "HP Compaq 6910"
149 * HP Compaq 8710x Notebook PC / Mobile Workstation
150 * "NC2400" "HP Compaq nc2400"
151 * "NX74x0" "HP Compaq nx74"
152 * "NX6325" "HP Compaq nx6325"
153 * "NC4400" "HP Compaq nc4400"
154 */
155};
156
157
158static int lis3lv02d_add(struct acpi_device *device)
159{
160 u8 val;
161
162 if (!device)
163 return -EINVAL;
164
165 adev.device = device;
166 adev.init = lis3lv02d_acpi_init;
167 adev.read = lis3lv02d_acpi_read;
168 adev.write = lis3lv02d_acpi_write;
169 strcpy(acpi_device_name(device), DRIVER_NAME);
170 strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
171 device->driver_data = &adev;
172
173 lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val);
174 if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) {
175 printk(KERN_ERR DRIVER_NAME
176 ": Accelerometer chip not LIS3LV02D{L,Q}\n");
177 }
178
179 /* If possible use a "standard" axes order */
180 if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
181 printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
182 "using default axes configuration\n");
183 adev.ac = lis3lv02d_axis_normal;
184 }
185
186 return lis3lv02d_init_device(&adev);
187}
188
189static int lis3lv02d_remove(struct acpi_device *device, int type)
190{
191 if (!device)
192 return -EINVAL;
193
194 lis3lv02d_joystick_disable();
195 lis3lv02d_poweroff(device->handle);
196
197 return lis3lv02d_remove_fs();
198}
199
200
201#ifdef CONFIG_PM
202static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
203{
204 /* make sure the device is off when we suspend */
205 lis3lv02d_poweroff(device->handle);
206 return 0;
207}
208
209static int lis3lv02d_resume(struct acpi_device *device)
210{
211 /* put back the device in the right state (ACPI might turn it on) */
212 mutex_lock(&adev.lock);
213 if (adev.usage > 0)
214 lis3lv02d_poweron(device->handle);
215 else
216 lis3lv02d_poweroff(device->handle);
217 mutex_unlock(&adev.lock);
218 return 0;
219}
220#else
221#define lis3lv02d_suspend NULL
222#define lis3lv02d_resume NULL
223#endif
224
225/* For the HP MDPS aka 3D Driveguard */
226static struct acpi_driver lis3lv02d_driver = {
227 .name = DRIVER_NAME,
228 .class = ACPI_MDPS_CLASS,
229 .ids = lis3lv02d_device_ids,
230 .ops = {
231 .add = lis3lv02d_add,
232 .remove = lis3lv02d_remove,
233 .suspend = lis3lv02d_suspend,
234 .resume = lis3lv02d_resume,
235 }
236};
237
238static int __init lis3lv02d_init_module(void)
239{
240 int ret;
241
242 if (acpi_disabled)
243 return -ENODEV;
244
245 ret = acpi_bus_register_driver(&lis3lv02d_driver);
246 if (ret < 0)
247 return ret;
248
249 printk(KERN_INFO DRIVER_NAME " driver loaded.\n");
250
251 return 0;
252}
253
254static void __exit lis3lv02d_exit_module(void)
255{
256 acpi_bus_unregister_driver(&lis3lv02d_driver);
257}
258
259MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS");
260MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
261MODULE_LICENSE("GPL");
262
263module_init(lis3lv02d_init_module);
264module_exit(lis3lv02d_exit_module);
265
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index 2ede9388096b..27d7f72a5f11 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -490,6 +490,13 @@ static unsigned long chipset_ids[] = {
490 0 490 0
491}; 491};
492 492
493static struct pci_device_id i5k_amb_ids[] __devinitdata = {
494 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
495 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) },
496 { 0, }
497};
498MODULE_DEVICE_TABLE(pci, i5k_amb_ids);
499
493static int __devinit i5k_amb_probe(struct platform_device *pdev) 500static int __devinit i5k_amb_probe(struct platform_device *pdev)
494{ 501{
495 struct i5k_amb_data *data; 502 struct i5k_amb_data *data;
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index b74c95735f95..95a99c590da2 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -14,6 +14,7 @@
14 IT8712F Super I/O chip w/LPC interface 14 IT8712F Super I/O chip w/LPC interface
15 IT8716F Super I/O chip w/LPC interface 15 IT8716F Super I/O chip w/LPC interface
16 IT8718F Super I/O chip w/LPC interface 16 IT8718F Super I/O chip w/LPC interface
17 IT8720F Super I/O chip w/LPC interface
17 IT8726F Super I/O chip w/LPC interface 18 IT8726F Super I/O chip w/LPC interface
18 Sis950 A clone of the IT8705F 19 Sis950 A clone of the IT8705F
19 20
@@ -48,11 +49,12 @@
48#include <linux/sysfs.h> 49#include <linux/sysfs.h>
49#include <linux/string.h> 50#include <linux/string.h>
50#include <linux/dmi.h> 51#include <linux/dmi.h>
52#include <linux/acpi.h>
51#include <asm/io.h> 53#include <asm/io.h>
52 54
53#define DRVNAME "it87" 55#define DRVNAME "it87"
54 56
55enum chips { it87, it8712, it8716, it8718 }; 57enum chips { it87, it8712, it8716, it8718, it8720 };
56 58
57static unsigned short force_id; 59static unsigned short force_id;
58module_param(force_id, ushort, 0); 60module_param(force_id, ushort, 0);
@@ -64,7 +66,10 @@ static struct platform_device *pdev;
64#define DEV 0x07 /* Register: Logical device select */ 66#define DEV 0x07 /* Register: Logical device select */
65#define VAL 0x2f /* The value to read/write */ 67#define VAL 0x2f /* The value to read/write */
66#define PME 0x04 /* The device with the fan registers in it */ 68#define PME 0x04 /* The device with the fan registers in it */
67#define GPIO 0x07 /* The device with the IT8718F VID value in it */ 69
70/* The device with the IT8718F/IT8720F VID value in it */
71#define GPIO 0x07
72
68#define DEVID 0x20 /* Register: Device ID */ 73#define DEVID 0x20 /* Register: Device ID */
69#define DEVREV 0x22 /* Register: Device Revision */ 74#define DEVREV 0x22 /* Register: Device Revision */
70 75
@@ -113,6 +118,7 @@ superio_exit(void)
113#define IT8705F_DEVID 0x8705 118#define IT8705F_DEVID 0x8705
114#define IT8716F_DEVID 0x8716 119#define IT8716F_DEVID 0x8716
115#define IT8718F_DEVID 0x8718 120#define IT8718F_DEVID 0x8718
121#define IT8720F_DEVID 0x8720
116#define IT8726F_DEVID 0x8726 122#define IT8726F_DEVID 0x8726
117#define IT87_ACT_REG 0x30 123#define IT87_ACT_REG 0x30
118#define IT87_BASE_REG 0x60 124#define IT87_BASE_REG 0x60
@@ -150,8 +156,8 @@ static int fix_pwm_polarity;
150#define IT87_REG_ALARM2 0x02 156#define IT87_REG_ALARM2 0x02
151#define IT87_REG_ALARM3 0x03 157#define IT87_REG_ALARM3 0x03
152 158
153/* The IT8718F has the VID value in a different register, in Super-I/O 159/* The IT8718F and IT8720F have the VID value in a different register, in
154 configuration space. */ 160 Super-I/O configuration space. */
155#define IT87_REG_VID 0x0a 161#define IT87_REG_VID 0x0a
156/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b 162/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
157 for fan divisors. Later IT8712F revisions must use 16-bit tachometer 163 for fan divisors. Later IT8712F revisions must use 16-bit tachometer
@@ -282,7 +288,8 @@ static inline int has_16bit_fans(const struct it87_data *data)
282 return (data->type == it87 && data->revision >= 0x03) 288 return (data->type == it87 && data->revision >= 0x03)
283 || (data->type == it8712 && data->revision >= 0x08) 289 || (data->type == it8712 && data->revision >= 0x08)
284 || data->type == it8716 290 || data->type == it8716
285 || data->type == it8718; 291 || data->type == it8718
292 || data->type == it8720;
286} 293}
287 294
288static int it87_probe(struct platform_device *pdev); 295static int it87_probe(struct platform_device *pdev);
@@ -992,6 +999,9 @@ static int __init it87_find(unsigned short *address,
992 case IT8718F_DEVID: 999 case IT8718F_DEVID:
993 sio_data->type = it8718; 1000 sio_data->type = it8718;
994 break; 1001 break;
1002 case IT8720F_DEVID:
1003 sio_data->type = it8720;
1004 break;
995 case 0xffff: /* No device at all */ 1005 case 0xffff: /* No device at all */
996 goto exit; 1006 goto exit;
997 default: 1007 default:
@@ -1022,7 +1032,8 @@ static int __init it87_find(unsigned short *address,
1022 int reg; 1032 int reg;
1023 1033
1024 superio_select(GPIO); 1034 superio_select(GPIO);
1025 if (chip_type == it8718) 1035 if ((chip_type == it8718) ||
1036 (chip_type == it8720))
1026 sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); 1037 sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
1027 1038
1028 reg = superio_inb(IT87_SIO_PINX2_REG); 1039 reg = superio_inb(IT87_SIO_PINX2_REG);
@@ -1068,6 +1079,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1068 "it8712", 1079 "it8712",
1069 "it8716", 1080 "it8716",
1070 "it8718", 1081 "it8718",
1082 "it8720",
1071 }; 1083 };
1072 1084
1073 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1085 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1226,7 +1238,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1226 } 1238 }
1227 1239
1228 if (data->type == it8712 || data->type == it8716 1240 if (data->type == it8712 || data->type == it8716
1229 || data->type == it8718) { 1241 || data->type == it8718 || data->type == it8720) {
1230 data->vrm = vid_which_vrm(); 1242 data->vrm = vid_which_vrm();
1231 /* VID reading from Super-I/O config space if available */ 1243 /* VID reading from Super-I/O config space if available */
1232 data->vid = sio_data->vid_value; 1244 data->vid = sio_data->vid_value;
@@ -1374,7 +1386,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1374 it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); 1386 it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
1375 } 1387 }
1376 1388
1377 /* Check if temperature channnels are reset manually or by some reason */ 1389 /* Check if temperature channels are reset manually or by some reason */
1378 tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE); 1390 tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
1379 if ((tmp & 0x3f) == 0) { 1391 if ((tmp & 0x3f) == 0) {
1380 /* Temp1,Temp3=thermistor; Temp2=thermal diode */ 1392 /* Temp1,Temp3=thermistor; Temp2=thermal diode */
@@ -1513,7 +1525,8 @@ static struct it87_data *it87_update_device(struct device *dev)
1513 1525
1514 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 1526 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
1515 /* The 8705 does not have VID capability. 1527 /* The 8705 does not have VID capability.
1516 The 8718 does not use IT87_REG_VID for the same purpose. */ 1528 The 8718 and the 8720 don't use IT87_REG_VID for the
1529 same purpose. */
1517 if (data->type == it8712 || data->type == it8716) { 1530 if (data->type == it8712 || data->type == it8716) {
1518 data->vid = it87_read_value(data, IT87_REG_VID); 1531 data->vid = it87_read_value(data, IT87_REG_VID);
1519 /* The older IT8712F revisions had only 5 VID pins, 1532 /* The older IT8712F revisions had only 5 VID pins,
@@ -1540,6 +1553,10 @@ static int __init it87_device_add(unsigned short address,
1540 }; 1553 };
1541 int err; 1554 int err;
1542 1555
1556 err = acpi_check_resource_conflict(&res);
1557 if (err)
1558 goto exit;
1559
1543 pdev = platform_device_alloc(DRVNAME, address); 1560 pdev = platform_device_alloc(DRVNAME, address);
1544 if (!pdev) { 1561 if (!pdev) {
1545 err = -ENOMEM; 1562 err = -ENOMEM;
@@ -1608,7 +1625,7 @@ static void __exit sm_it87_exit(void)
1608 1625
1609MODULE_AUTHOR("Chris Gauthron, " 1626MODULE_AUTHOR("Chris Gauthron, "
1610 "Jean Delvare <khali@linux-fr.org>"); 1627 "Jean Delvare <khali@linux-fr.org>");
1611MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8726F, SiS950 driver"); 1628MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8720F/8726F, SiS950 driver");
1612module_param(update_vbat, bool, 0); 1629module_param(update_vbat, bool, 0);
1613MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); 1630MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
1614module_param(fix_pwm_polarity, bool, 0); 1631module_param(fix_pwm_polarity, bool, 0);
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index c002144c76bc..219d2d0d5a62 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2007-2008 Yan Burman 4 * Copyright (C) 2007-2008 Yan Burman
5 * Copyright (C) 2008 Eric Piel 5 * Copyright (C) 2008 Eric Piel
6 * Copyright (C) 2008 Pavel Machek
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -39,7 +40,6 @@
39#include "lis3lv02d.h" 40#include "lis3lv02d.h"
40 41
41#define DRIVER_NAME "lis3lv02d" 42#define DRIVER_NAME "lis3lv02d"
42#define ACPI_MDPS_CLASS "accelerometer"
43 43
44/* joystick device poll interval in milliseconds */ 44/* joystick device poll interval in milliseconds */
45#define MDPS_POLL_INTERVAL 50 45#define MDPS_POLL_INTERVAL 50
@@ -55,100 +55,17 @@
55/* Maximum value our axis may get for the input device (signed 12 bits) */ 55/* Maximum value our axis may get for the input device (signed 12 bits) */
56#define MDPS_MAX_VAL 2048 56#define MDPS_MAX_VAL 2048
57 57
58struct axis_conversion { 58struct acpi_lis3lv02d adev;
59 s8 x; 59EXPORT_SYMBOL_GPL(adev);
60 s8 y;
61 s8 z;
62};
63
64struct acpi_lis3lv02d {
65 struct acpi_device *device; /* The ACPI device */
66 struct input_dev *idev; /* input device */
67 struct task_struct *kthread; /* kthread for input */
68 struct mutex lock;
69 struct platform_device *pdev; /* platform device */
70 atomic_t count; /* interrupt count after last read */
71 int xcalib; /* calibrated null value for x */
72 int ycalib; /* calibrated null value for y */
73 int zcalib; /* calibrated null value for z */
74 unsigned char is_on; /* whether the device is on or off */
75 unsigned char usage; /* usage counter */
76 struct axis_conversion ac; /* hw -> logical axis */
77};
78 60
79static struct acpi_lis3lv02d adev;
80
81static int lis3lv02d_remove_fs(void);
82static int lis3lv02d_add_fs(struct acpi_device *device); 61static int lis3lv02d_add_fs(struct acpi_device *device);
83 62
84/* For automatic insertion of the module */
85static struct acpi_device_id lis3lv02d_device_ids[] = {
86 {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
87 {"", 0},
88};
89MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
90
91/**
92 * lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
93 * @handle: the handle of the device
94 *
95 * Returns AE_OK on success.
96 */
97static inline acpi_status lis3lv02d_acpi_init(acpi_handle handle)
98{
99 return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL);
100}
101
102/**
103 * lis3lv02d_acpi_read - ACPI ALRD method: read a register
104 * @handle: the handle of the device
105 * @reg: the register to read
106 * @ret: result of the operation
107 *
108 * Returns AE_OK on success.
109 */
110static acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
111{
112 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
113 struct acpi_object_list args = { 1, &arg0 };
114 unsigned long long lret;
115 acpi_status status;
116
117 arg0.integer.value = reg;
118
119 status = acpi_evaluate_integer(handle, "ALRD", &args, &lret);
120 *ret = lret;
121 return status;
122}
123
124/**
125 * lis3lv02d_acpi_write - ACPI ALWR method: write to a register
126 * @handle: the handle of the device
127 * @reg: the register to write to
128 * @val: the value to write
129 *
130 * Returns AE_OK on success.
131 */
132static acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
133{
134 unsigned long long ret; /* Not used when writting */
135 union acpi_object in_obj[2];
136 struct acpi_object_list args = { 2, in_obj };
137
138 in_obj[0].type = ACPI_TYPE_INTEGER;
139 in_obj[0].integer.value = reg;
140 in_obj[1].type = ACPI_TYPE_INTEGER;
141 in_obj[1].integer.value = val;
142
143 return acpi_evaluate_integer(handle, "ALWR", &args, &ret);
144}
145
146static s16 lis3lv02d_read_16(acpi_handle handle, int reg) 63static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
147{ 64{
148 u8 lo, hi; 65 u8 lo, hi;
149 66
150 lis3lv02d_acpi_read(handle, reg, &lo); 67 adev.read(handle, reg, &lo);
151 lis3lv02d_acpi_read(handle, reg + 1, &hi); 68 adev.read(handle, reg + 1, &hi);
152 /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ 69 /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
153 return (s16)((hi << 8) | lo); 70 return (s16)((hi << 8) | lo);
154} 71}
@@ -190,54 +107,31 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
190 *z = lis3lv02d_get_axis(adev.ac.z, position); 107 *z = lis3lv02d_get_axis(adev.ac.z, position);
191} 108}
192 109
193static inline void lis3lv02d_poweroff(acpi_handle handle) 110void lis3lv02d_poweroff(acpi_handle handle)
194{ 111{
195 adev.is_on = 0; 112 adev.is_on = 0;
196 /* disable X,Y,Z axis and power down */ 113 /* disable X,Y,Z axis and power down */
197 lis3lv02d_acpi_write(handle, CTRL_REG1, 0x00); 114 adev.write(handle, CTRL_REG1, 0x00);
198} 115}
116EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
199 117
200static void lis3lv02d_poweron(acpi_handle handle) 118void lis3lv02d_poweron(acpi_handle handle)
201{ 119{
202 u8 val; 120 u8 val;
203 121
204 adev.is_on = 1; 122 adev.is_on = 1;
205 lis3lv02d_acpi_init(handle); 123 adev.init(handle);
206 lis3lv02d_acpi_write(handle, FF_WU_CFG, 0); 124 adev.write(handle, FF_WU_CFG, 0);
207 /* 125 /*
208 * BDU: LSB and MSB values are not updated until both have been read. 126 * BDU: LSB and MSB values are not updated until both have been read.
209 * So the value read will always be correct. 127 * So the value read will always be correct.
210 * IEN: Interrupt for free-fall and DD, not for data-ready. 128 * IEN: Interrupt for free-fall and DD, not for data-ready.
211 */ 129 */
212 lis3lv02d_acpi_read(handle, CTRL_REG2, &val); 130 adev.read(handle, CTRL_REG2, &val);
213 val |= CTRL2_BDU | CTRL2_IEN; 131 val |= CTRL2_BDU | CTRL2_IEN;
214 lis3lv02d_acpi_write(handle, CTRL_REG2, val); 132 adev.write(handle, CTRL_REG2, val);
215}
216
217#ifdef CONFIG_PM
218static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
219{
220 /* make sure the device is off when we suspend */
221 lis3lv02d_poweroff(device->handle);
222 return 0;
223}
224
225static int lis3lv02d_resume(struct acpi_device *device)
226{
227 /* put back the device in the right state (ACPI might turn it on) */
228 mutex_lock(&adev.lock);
229 if (adev.usage > 0)
230 lis3lv02d_poweron(device->handle);
231 else
232 lis3lv02d_poweroff(device->handle);
233 mutex_unlock(&adev.lock);
234 return 0;
235} 133}
236#else 134EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
237#define lis3lv02d_suspend NULL
238#define lis3lv02d_resume NULL
239#endif
240
241 135
242/* 136/*
243 * To be called before starting to use the device. It makes sure that the 137 * To be called before starting to use the device. It makes sure that the
@@ -315,7 +209,7 @@ static inline void lis3lv02d_calibrate_joystick(void)
315 lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); 209 lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
316} 210}
317 211
318static int lis3lv02d_joystick_enable(void) 212int lis3lv02d_joystick_enable(void)
319{ 213{
320 int err; 214 int err;
321 215
@@ -349,8 +243,9 @@ static int lis3lv02d_joystick_enable(void)
349 243
350 return err; 244 return err;
351} 245}
246EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
352 247
353static void lis3lv02d_joystick_disable(void) 248void lis3lv02d_joystick_disable(void)
354{ 249{
355 if (!adev.idev) 250 if (!adev.idev)
356 return; 251 return;
@@ -358,13 +253,13 @@ static void lis3lv02d_joystick_disable(void)
358 input_unregister_device(adev.idev); 253 input_unregister_device(adev.idev);
359 adev.idev = NULL; 254 adev.idev = NULL;
360} 255}
361 256EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
362 257
363/* 258/*
364 * Initialise the accelerometer and the various subsystems. 259 * Initialise the accelerometer and the various subsystems.
365 * Should be rather independant of the bus system. 260 * Should be rather independant of the bus system.
366 */ 261 */
367static int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) 262int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
368{ 263{
369 mutex_init(&dev->lock); 264 mutex_init(&dev->lock);
370 lis3lv02d_add_fs(dev->device); 265 lis3lv02d_add_fs(dev->device);
@@ -376,93 +271,7 @@ static int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
376 lis3lv02d_decrease_use(dev); 271 lis3lv02d_decrease_use(dev);
377 return 0; 272 return 0;
378} 273}
379 274EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
380static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
381{
382 adev.ac = *((struct axis_conversion *)dmi->driver_data);
383 printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
384
385 return 1;
386}
387
388/* Represents, for each axis seen by userspace, the corresponding hw axis (+1).
389 * If the value is negative, the opposite of the hw value is used. */
390static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3};
391static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3};
392static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3};
393static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3};
394static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3};
395static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
396
397#define AXIS_DMI_MATCH(_ident, _name, _axis) { \
398 .ident = _ident, \
399 .callback = lis3lv02d_dmi_matched, \
400 .matches = { \
401 DMI_MATCH(DMI_PRODUCT_NAME, _name) \
402 }, \
403 .driver_data = &lis3lv02d_axis_##_axis \
404}
405static struct dmi_system_id lis3lv02d_dmi_ids[] = {
406 /* product names are truncated to match all kinds of a same model */
407 AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted),
408 AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted),
409 AXIS_DMI_MATCH("NX9420", "HP Compaq nx9420", x_inverted),
410 AXIS_DMI_MATCH("NW9440", "HP Compaq nw9440", x_inverted),
411 AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
412 AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
413 AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
414 { NULL, }
415/* Laptop models without axis info (yet):
416 * "NC651xx" "HP Compaq 651"
417 * "NC671xx" "HP Compaq 671"
418 * "NC6910" "HP Compaq 6910"
419 * HP Compaq 8710x Notebook PC / Mobile Workstation
420 * "NC2400" "HP Compaq nc2400"
421 * "NX74x0" "HP Compaq nx74"
422 * "NX6325" "HP Compaq nx6325"
423 * "NC4400" "HP Compaq nc4400"
424 */
425};
426
427static int lis3lv02d_add(struct acpi_device *device)
428{
429 u8 val;
430
431 if (!device)
432 return -EINVAL;
433
434 adev.device = device;
435 strcpy(acpi_device_name(device), DRIVER_NAME);
436 strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
437 device->driver_data = &adev;
438
439 lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val);
440 if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) {
441 printk(KERN_ERR DRIVER_NAME
442 ": Accelerometer chip not LIS3LV02D{L,Q}\n");
443 }
444
445 /* If possible use a "standard" axes order */
446 if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
447 printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
448 "using default axes configuration\n");
449 adev.ac = lis3lv02d_axis_normal;
450 }
451
452 return lis3lv02d_init_device(&adev);
453}
454
455static int lis3lv02d_remove(struct acpi_device *device, int type)
456{
457 if (!device)
458 return -EINVAL;
459
460 lis3lv02d_joystick_disable();
461 lis3lv02d_poweroff(device->handle);
462
463 return lis3lv02d_remove_fs();
464}
465
466 275
467/* Sysfs stuff */ 276/* Sysfs stuff */
468static ssize_t lis3lv02d_position_show(struct device *dev, 277static ssize_t lis3lv02d_position_show(struct device *dev,
@@ -501,7 +310,7 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
501 int val; 310 int val;
502 311
503 lis3lv02d_increase_use(&adev); 312 lis3lv02d_increase_use(&adev);
504 lis3lv02d_acpi_read(adev.device->handle, CTRL_REG1, &ctrl); 313 adev.read(adev.device->handle, CTRL_REG1, &ctrl);
505 lis3lv02d_decrease_use(&adev); 314 lis3lv02d_decrease_use(&adev);
506 val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; 315 val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
507 return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); 316 return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
@@ -523,6 +332,7 @@ static struct attribute_group lis3lv02d_attribute_group = {
523 .attrs = lis3lv02d_attributes 332 .attrs = lis3lv02d_attributes
524}; 333};
525 334
335
526static int lis3lv02d_add_fs(struct acpi_device *device) 336static int lis3lv02d_add_fs(struct acpi_device *device)
527{ 337{
528 adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); 338 adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
@@ -532,50 +342,15 @@ static int lis3lv02d_add_fs(struct acpi_device *device)
532 return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); 342 return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
533} 343}
534 344
535static int lis3lv02d_remove_fs(void) 345int lis3lv02d_remove_fs(void)
536{ 346{
537 sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); 347 sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
538 platform_device_unregister(adev.pdev); 348 platform_device_unregister(adev.pdev);
539 return 0; 349 return 0;
540} 350}
541 351EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
542/* For the HP MDPS aka 3D Driveguard */
543static struct acpi_driver lis3lv02d_driver = {
544 .name = DRIVER_NAME,
545 .class = ACPI_MDPS_CLASS,
546 .ids = lis3lv02d_device_ids,
547 .ops = {
548 .add = lis3lv02d_add,
549 .remove = lis3lv02d_remove,
550 .suspend = lis3lv02d_suspend,
551 .resume = lis3lv02d_resume,
552 }
553};
554
555static int __init lis3lv02d_init_module(void)
556{
557 int ret;
558
559 if (acpi_disabled)
560 return -ENODEV;
561
562 ret = acpi_bus_register_driver(&lis3lv02d_driver);
563 if (ret < 0)
564 return ret;
565
566 printk(KERN_INFO DRIVER_NAME " driver loaded.\n");
567
568 return 0;
569}
570
571static void __exit lis3lv02d_exit_module(void)
572{
573 acpi_bus_unregister_driver(&lis3lv02d_driver);
574}
575 352
576MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); 353MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
577MODULE_AUTHOR("Yan Burman and Eric Piel"); 354MODULE_AUTHOR("Yan Burman and Eric Piel");
578MODULE_LICENSE("GPL"); 355MODULE_LICENSE("GPL");
579 356
580module_init(lis3lv02d_init_module);
581module_exit(lis3lv02d_exit_module);
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 330cfc60e948..223f1c0763bb 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -23,7 +23,7 @@
23 * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to 23 * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
24 * be connected via SPI. There exists also several similar chips (such as LIS302DL or 24 * be connected via SPI. There exists also several similar chips (such as LIS302DL or
25 * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. 25 * LIS3L02DQ) but not in the HP laptops and they have slightly different registers.
26 * They can also be connected via I²C. 26 * They can also be connected via I²C.
27 */ 27 */
28 28
29#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ 29#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */
@@ -147,3 +147,36 @@ enum lis3lv02d_dd_src {
147 DD_SRC_IA = 0x40, 147 DD_SRC_IA = 0x40,
148}; 148};
149 149
150struct axis_conversion {
151 s8 x;
152 s8 y;
153 s8 z;
154};
155
156struct acpi_lis3lv02d {
157 struct acpi_device *device; /* The ACPI device */
158 acpi_status (*init) (acpi_handle handle);
159 acpi_status (*write) (acpi_handle handle, int reg, u8 val);
160 acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
161
162 struct input_dev *idev; /* input device */
163 struct task_struct *kthread; /* kthread for input */
164 struct mutex lock;
165 struct platform_device *pdev; /* platform device */
166 atomic_t count; /* interrupt count after last read */
167 int xcalib; /* calibrated null value for x */
168 int ycalib; /* calibrated null value for y */
169 int zcalib; /* calibrated null value for z */
170 unsigned char is_on; /* whether the device is on or off */
171 unsigned char usage; /* usage counter */
172 struct axis_conversion ac; /* hw -> logical axis */
173};
174
175int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
176int lis3lv02d_joystick_enable(void);
177void lis3lv02d_joystick_disable(void);
178void lis3lv02d_poweroff(acpi_handle handle);
179void lis3lv02d_poweron(acpi_handle handle);
180int lis3lv02d_remove_fs(void);
181
182extern struct acpi_lis3lv02d adev;
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index d435f003292d..ae6204f33214 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -37,9 +37,13 @@
37 37
38#define DRVNAME "lm70" 38#define DRVNAME "lm70"
39 39
40#define LM70_CHIP_LM70 0 /* original NS LM70 */
41#define LM70_CHIP_TMP121 1 /* TI TMP121/TMP123 */
42
40struct lm70 { 43struct lm70 {
41 struct device *hwmon_dev; 44 struct device *hwmon_dev;
42 struct mutex lock; 45 struct mutex lock;
46 unsigned int chip;
43}; 47};
44 48
45/* sysfs hook function */ 49/* sysfs hook function */
@@ -47,7 +51,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
47 struct device_attribute *attr, char *buf) 51 struct device_attribute *attr, char *buf)
48{ 52{
49 struct spi_device *spi = to_spi_device(dev); 53 struct spi_device *spi = to_spi_device(dev);
50 int status, val; 54 int status, val = 0;
51 u8 rxbuf[2]; 55 u8 rxbuf[2];
52 s16 raw=0; 56 s16 raw=0;
53 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); 57 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
@@ -65,12 +69,12 @@ static ssize_t lm70_sense_temp(struct device *dev,
65 "spi_write_then_read failed with status %d\n", status); 69 "spi_write_then_read failed with status %d\n", status);
66 goto out; 70 goto out;
67 } 71 }
68 dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]); 72 raw = (rxbuf[0] << 8) + rxbuf[1];
69 73 dev_dbg(dev, "rxbuf[0] : 0x%02x rxbuf[1] : 0x%02x raw=0x%04x\n",
70 raw = (rxbuf[1] << 8) + rxbuf[0]; 74 rxbuf[0], rxbuf[1], raw);
71 dev_dbg(dev, "raw=0x%x\n", raw);
72 75
73 /* 76 /*
77 * LM70:
74 * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's 78 * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's
75 * complement value. Only the MSB 11 bits (1 sign + 10 temperature 79 * complement value. Only the MSB 11 bits (1 sign + 10 temperature
76 * bits) are meaningful; the LSB 5 bits are to be discarded. 80 * bits) are meaningful; the LSB 5 bits are to be discarded.
@@ -80,8 +84,21 @@ static ssize_t lm70_sense_temp(struct device *dev,
80 * by 0.25. Also multiply by 1000 to represent in millidegrees 84 * by 0.25. Also multiply by 1000 to represent in millidegrees
81 * Celsius. 85 * Celsius.
82 * So it's equivalent to multiplying by 0.25 * 1000 = 250. 86 * So it's equivalent to multiplying by 0.25 * 1000 = 250.
87 *
88 * TMP121/TMP123:
89 * 13 bits of 2's complement data, discard LSB 3 bits,
90 * resolution 0.0625 degrees celsius.
83 */ 91 */
84 val = ((int)raw/32) * 250; 92 switch (p_lm70->chip) {
93 case LM70_CHIP_LM70:
94 val = ((int)raw / 32) * 250;
95 break;
96
97 case LM70_CHIP_TMP121:
98 val = ((int)raw / 8) * 625 / 10;
99 break;
100 }
101
85 status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ 102 status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
86out: 103out:
87 mutex_unlock(&p_lm70->lock); 104 mutex_unlock(&p_lm70->lock);
@@ -93,27 +110,39 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
93static ssize_t lm70_show_name(struct device *dev, struct device_attribute 110static ssize_t lm70_show_name(struct device *dev, struct device_attribute
94 *devattr, char *buf) 111 *devattr, char *buf)
95{ 112{
96 return sprintf(buf, "lm70\n"); 113 struct lm70 *p_lm70 = dev_get_drvdata(dev);
114 int ret;
115
116 switch (p_lm70->chip) {
117 case LM70_CHIP_LM70:
118 ret = sprintf(buf, "lm70\n");
119 break;
120 case LM70_CHIP_TMP121:
121 ret = sprintf(buf, "tmp121\n");
122 break;
123 default:
124 ret = -EINVAL;
125 }
126 return ret;
97} 127}
98 128
99static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); 129static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
100 130
101/*----------------------------------------------------------------------*/ 131/*----------------------------------------------------------------------*/
102 132
103static int __devinit lm70_probe(struct spi_device *spi) 133static int __devinit common_probe(struct spi_device *spi, int chip)
104{ 134{
105 struct lm70 *p_lm70; 135 struct lm70 *p_lm70;
106 int status; 136 int status;
107 137
108 /* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */ 138 /* NOTE: we assume 8-bit words, and convert to 16 bits manually */
109 if ((spi->mode & (SPI_CPOL|SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
110 return -EINVAL;
111 139
112 p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); 140 p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
113 if (!p_lm70) 141 if (!p_lm70)
114 return -ENOMEM; 142 return -ENOMEM;
115 143
116 mutex_init(&p_lm70->lock); 144 mutex_init(&p_lm70->lock);
145 p_lm70->chip = chip;
117 146
118 /* sysfs hook */ 147 /* sysfs hook */
119 p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); 148 p_lm70->hwmon_dev = hwmon_device_register(&spi->dev);
@@ -141,6 +170,24 @@ out_dev_reg_failed:
141 return status; 170 return status;
142} 171}
143 172
173static int __devinit lm70_probe(struct spi_device *spi)
174{
175 /* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
176 if ((spi->mode & (SPI_CPOL | SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
177 return -EINVAL;
178
179 return common_probe(spi, LM70_CHIP_LM70);
180}
181
182static int __devinit tmp121_probe(struct spi_device *spi)
183{
184 /* signaling is SPI_MODE_0 with only MISO connected */
185 if (spi->mode & (SPI_CPOL | SPI_CPHA))
186 return -EINVAL;
187
188 return common_probe(spi, LM70_CHIP_TMP121);
189}
190
144static int __devexit lm70_remove(struct spi_device *spi) 191static int __devexit lm70_remove(struct spi_device *spi)
145{ 192{
146 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); 193 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
@@ -154,6 +201,15 @@ static int __devexit lm70_remove(struct spi_device *spi)
154 return 0; 201 return 0;
155} 202}
156 203
204static struct spi_driver tmp121_driver = {
205 .driver = {
206 .name = "tmp121",
207 .owner = THIS_MODULE,
208 },
209 .probe = tmp121_probe,
210 .remove = __devexit_p(lm70_remove),
211};
212
157static struct spi_driver lm70_driver = { 213static struct spi_driver lm70_driver = {
158 .driver = { 214 .driver = {
159 .name = "lm70", 215 .name = "lm70",
@@ -165,17 +221,26 @@ static struct spi_driver lm70_driver = {
165 221
166static int __init init_lm70(void) 222static int __init init_lm70(void)
167{ 223{
168 return spi_register_driver(&lm70_driver); 224 int ret = spi_register_driver(&lm70_driver);
225 if (ret)
226 return ret;
227
228 ret = spi_register_driver(&tmp121_driver);
229 if (ret)
230 spi_unregister_driver(&lm70_driver);
231
232 return ret;
169} 233}
170 234
171static void __exit cleanup_lm70(void) 235static void __exit cleanup_lm70(void)
172{ 236{
173 spi_unregister_driver(&lm70_driver); 237 spi_unregister_driver(&lm70_driver);
238 spi_unregister_driver(&tmp121_driver);
174} 239}
175 240
176module_init(init_lm70); 241module_init(init_lm70);
177module_exit(cleanup_lm70); 242module_exit(cleanup_lm70);
178 243
179MODULE_AUTHOR("Kaiwan N Billimoria"); 244MODULE_AUTHOR("Kaiwan N Billimoria");
180MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver"); 245MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
181MODULE_LICENSE("GPL"); 246MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
new file mode 100644
index 000000000000..034b2c515848
--- /dev/null
+++ b/drivers/hwmon/ltc4245.c
@@ -0,0 +1,567 @@
1/*
2 * Driver for Linear Technology LTC4245 I2C Multiple Supply Hot Swap Controller
3 *
4 * Copyright (C) 2008 Ira W. Snyder <iws@ovro.caltech.edu>
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; version 2 of the License.
9 *
10 * This driver is based on the ds1621 and ina209 drivers.
11 *
12 * Datasheet:
13 * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1140,P19392,D13517
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/err.h>
20#include <linux/slab.h>
21#include <linux/i2c.h>
22#include <linux/hwmon.h>
23#include <linux/hwmon-sysfs.h>
24
25/* Valid addresses are 0x20 - 0x3f
26 *
27 * For now, we do not probe, since some of these addresses
28 * are known to be unfriendly to probing */
29static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
30
31/* Insmod parameters */
32I2C_CLIENT_INSMOD_1(ltc4245);
33
34/* Here are names of the chip's registers (a.k.a. commands) */
35enum ltc4245_cmd {
36 LTC4245_STATUS = 0x00, /* readonly */
37 LTC4245_ALERT = 0x01,
38 LTC4245_CONTROL = 0x02,
39 LTC4245_ON = 0x03,
40 LTC4245_FAULT1 = 0x04,
41 LTC4245_FAULT2 = 0x05,
42 LTC4245_GPIO = 0x06,
43 LTC4245_ADCADR = 0x07,
44
45 LTC4245_12VIN = 0x10,
46 LTC4245_12VSENSE = 0x11,
47 LTC4245_12VOUT = 0x12,
48 LTC4245_5VIN = 0x13,
49 LTC4245_5VSENSE = 0x14,
50 LTC4245_5VOUT = 0x15,
51 LTC4245_3VIN = 0x16,
52 LTC4245_3VSENSE = 0x17,
53 LTC4245_3VOUT = 0x18,
54 LTC4245_VEEIN = 0x19,
55 LTC4245_VEESENSE = 0x1a,
56 LTC4245_VEEOUT = 0x1b,
57 LTC4245_GPIOADC1 = 0x1c,
58 LTC4245_GPIOADC2 = 0x1d,
59 LTC4245_GPIOADC3 = 0x1e,
60};
61
62struct ltc4245_data {
63 struct device *hwmon_dev;
64
65 struct mutex update_lock;
66 bool valid;
67 unsigned long last_updated; /* in jiffies */
68
69 /* Control registers */
70 u8 cregs[0x08];
71
72 /* Voltage registers */
73 u8 vregs[0x0f];
74};
75
76static struct ltc4245_data *ltc4245_update_device(struct device *dev)
77{
78 struct i2c_client *client = to_i2c_client(dev);
79 struct ltc4245_data *data = i2c_get_clientdata(client);
80 s32 val;
81 int i;
82
83 mutex_lock(&data->update_lock);
84
85 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
86
87 dev_dbg(&client->dev, "Starting ltc4245 update\n");
88
89 /* Read control registers -- 0x00 to 0x07 */
90 for (i = 0; i < ARRAY_SIZE(data->cregs); i++) {
91 val = i2c_smbus_read_byte_data(client, i);
92 if (unlikely(val < 0))
93 data->cregs[i] = 0;
94 else
95 data->cregs[i] = val;
96 }
97
98 /* Read voltage registers -- 0x10 to 0x1f */
99 for (i = 0; i < ARRAY_SIZE(data->vregs); i++) {
100 val = i2c_smbus_read_byte_data(client, i+0x10);
101 if (unlikely(val < 0))
102 data->vregs[i] = 0;
103 else
104 data->vregs[i] = val;
105 }
106
107 data->last_updated = jiffies;
108 data->valid = 1;
109 }
110
111 mutex_unlock(&data->update_lock);
112
113 return data;
114}
115
116/* Return the voltage from the given register in millivolts */
117static int ltc4245_get_voltage(struct device *dev, u8 reg)
118{
119 struct ltc4245_data *data = ltc4245_update_device(dev);
120 const u8 regval = data->vregs[reg - 0x10];
121 u32 voltage = 0;
122
123 switch (reg) {
124 case LTC4245_12VIN:
125 case LTC4245_12VOUT:
126 voltage = regval * 55;
127 break;
128 case LTC4245_5VIN:
129 case LTC4245_5VOUT:
130 voltage = regval * 22;
131 break;
132 case LTC4245_3VIN:
133 case LTC4245_3VOUT:
134 voltage = regval * 15;
135 break;
136 case LTC4245_VEEIN:
137 case LTC4245_VEEOUT:
138 voltage = regval * -55;
139 break;
140 case LTC4245_GPIOADC1:
141 case LTC4245_GPIOADC2:
142 case LTC4245_GPIOADC3:
143 voltage = regval * 10;
144 break;
145 default:
146 /* If we get here, the developer messed up */
147 WARN_ON_ONCE(1);
148 break;
149 }
150
151 return voltage;
152}
153
154/* Return the current in the given sense register in milliAmperes */
155static unsigned int ltc4245_get_current(struct device *dev, u8 reg)
156{
157 struct ltc4245_data *data = ltc4245_update_device(dev);
158 const u8 regval = data->vregs[reg - 0x10];
159 unsigned int voltage;
160 unsigned int curr;
161
162 /* The strange looking conversions that follow are fixed-point
163 * math, since we cannot do floating point in the kernel.
164 *
165 * Step 1: convert sense register to microVolts
166 * Step 2: convert voltage to milliAmperes
167 *
168 * If you play around with the V=IR equation, you come up with
169 * the following: X uV / Y mOhm == Z mA
170 *
171 * With the resistors that are fractions of a milliOhm, we multiply
172 * the voltage and resistance by 10, to shift the decimal point.
173 * Now we can use the normal division operator again.
174 */
175
176 switch (reg) {
177 case LTC4245_12VSENSE:
178 voltage = regval * 250; /* voltage in uV */
179 curr = voltage / 50; /* sense resistor 50 mOhm */
180 break;
181 case LTC4245_5VSENSE:
182 voltage = regval * 125; /* voltage in uV */
183 curr = (voltage * 10) / 35; /* sense resistor 3.5 mOhm */
184 break;
185 case LTC4245_3VSENSE:
186 voltage = regval * 125; /* voltage in uV */
187 curr = (voltage * 10) / 25; /* sense resistor 2.5 mOhm */
188 break;
189 case LTC4245_VEESENSE:
190 voltage = regval * 250; /* voltage in uV */
191 curr = voltage / 100; /* sense resistor 100 mOhm */
192 break;
193 default:
194 /* If we get here, the developer messed up */
195 WARN_ON_ONCE(1);
196 curr = 0;
197 break;
198 }
199
200 return curr;
201}
202
203static ssize_t ltc4245_show_voltage(struct device *dev,
204 struct device_attribute *da,
205 char *buf)
206{
207 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
208 const int voltage = ltc4245_get_voltage(dev, attr->index);
209
210 return snprintf(buf, PAGE_SIZE, "%d\n", voltage);
211}
212
213static ssize_t ltc4245_show_current(struct device *dev,
214 struct device_attribute *da,
215 char *buf)
216{
217 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
218 const unsigned int curr = ltc4245_get_current(dev, attr->index);
219
220 return snprintf(buf, PAGE_SIZE, "%u\n", curr);
221}
222
223static ssize_t ltc4245_show_power(struct device *dev,
224 struct device_attribute *da,
225 char *buf)
226{
227 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
228 const unsigned int curr = ltc4245_get_current(dev, attr->index);
229 const int output_voltage = ltc4245_get_voltage(dev, attr->index+1);
230
231 /* current in mA * voltage in mV == power in uW */
232 const unsigned int power = abs(output_voltage * curr);
233
234 return snprintf(buf, PAGE_SIZE, "%u\n", power);
235}
236
237static ssize_t ltc4245_show_alarm(struct device *dev,
238 struct device_attribute *da,
239 char *buf)
240{
241 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
242 struct ltc4245_data *data = ltc4245_update_device(dev);
243 const u8 reg = data->cregs[attr->index];
244 const u32 mask = attr->nr;
245
246 return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
247}
248
249/* These macros are used below in constructing device attribute objects
250 * for use with sysfs_create_group() to make a sysfs device file
251 * for each register.
252 */
253
254#define LTC4245_VOLTAGE(name, ltc4245_cmd_idx) \
255 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
256 ltc4245_show_voltage, NULL, ltc4245_cmd_idx)
257
258#define LTC4245_CURRENT(name, ltc4245_cmd_idx) \
259 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
260 ltc4245_show_current, NULL, ltc4245_cmd_idx)
261
262#define LTC4245_POWER(name, ltc4245_cmd_idx) \
263 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
264 ltc4245_show_power, NULL, ltc4245_cmd_idx)
265
266#define LTC4245_ALARM(name, mask, reg) \
267 static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \
268 ltc4245_show_alarm, NULL, (mask), reg)
269
270/* Construct a sensor_device_attribute structure for each register */
271
272/* Input voltages */
273LTC4245_VOLTAGE(in1_input, LTC4245_12VIN);
274LTC4245_VOLTAGE(in2_input, LTC4245_5VIN);
275LTC4245_VOLTAGE(in3_input, LTC4245_3VIN);
276LTC4245_VOLTAGE(in4_input, LTC4245_VEEIN);
277
278/* Input undervoltage alarms */
279LTC4245_ALARM(in1_min_alarm, (1 << 0), LTC4245_FAULT1);
280LTC4245_ALARM(in2_min_alarm, (1 << 1), LTC4245_FAULT1);
281LTC4245_ALARM(in3_min_alarm, (1 << 2), LTC4245_FAULT1);
282LTC4245_ALARM(in4_min_alarm, (1 << 3), LTC4245_FAULT1);
283
284/* Currents (via sense resistor) */
285LTC4245_CURRENT(curr1_input, LTC4245_12VSENSE);
286LTC4245_CURRENT(curr2_input, LTC4245_5VSENSE);
287LTC4245_CURRENT(curr3_input, LTC4245_3VSENSE);
288LTC4245_CURRENT(curr4_input, LTC4245_VEESENSE);
289
290/* Overcurrent alarms */
291LTC4245_ALARM(curr1_max_alarm, (1 << 4), LTC4245_FAULT1);
292LTC4245_ALARM(curr2_max_alarm, (1 << 5), LTC4245_FAULT1);
293LTC4245_ALARM(curr3_max_alarm, (1 << 6), LTC4245_FAULT1);
294LTC4245_ALARM(curr4_max_alarm, (1 << 7), LTC4245_FAULT1);
295
296/* Output voltages */
297LTC4245_VOLTAGE(in5_input, LTC4245_12VOUT);
298LTC4245_VOLTAGE(in6_input, LTC4245_5VOUT);
299LTC4245_VOLTAGE(in7_input, LTC4245_3VOUT);
300LTC4245_VOLTAGE(in8_input, LTC4245_VEEOUT);
301
302/* Power Bad alarms */
303LTC4245_ALARM(in5_min_alarm, (1 << 0), LTC4245_FAULT2);
304LTC4245_ALARM(in6_min_alarm, (1 << 1), LTC4245_FAULT2);
305LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2);
306LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2);
307
308/* GPIO voltages */
309LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC1);
310LTC4245_VOLTAGE(in10_input, LTC4245_GPIOADC2);
311LTC4245_VOLTAGE(in11_input, LTC4245_GPIOADC3);
312
313/* Power Consumption (virtual) */
314LTC4245_POWER(power1_input, LTC4245_12VSENSE);
315LTC4245_POWER(power2_input, LTC4245_5VSENSE);
316LTC4245_POWER(power3_input, LTC4245_3VSENSE);
317LTC4245_POWER(power4_input, LTC4245_VEESENSE);
318
319/* Finally, construct an array of pointers to members of the above objects,
320 * as required for sysfs_create_group()
321 */
322static struct attribute *ltc4245_attributes[] = {
323 &sensor_dev_attr_in1_input.dev_attr.attr,
324 &sensor_dev_attr_in2_input.dev_attr.attr,
325 &sensor_dev_attr_in3_input.dev_attr.attr,
326 &sensor_dev_attr_in4_input.dev_attr.attr,
327
328 &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
329 &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
330 &sensor_dev_attr_in3_min_alarm.dev_attr.attr,
331 &sensor_dev_attr_in4_min_alarm.dev_attr.attr,
332
333 &sensor_dev_attr_curr1_input.dev_attr.attr,
334 &sensor_dev_attr_curr2_input.dev_attr.attr,
335 &sensor_dev_attr_curr3_input.dev_attr.attr,
336 &sensor_dev_attr_curr4_input.dev_attr.attr,
337
338 &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
339 &sensor_dev_attr_curr2_max_alarm.dev_attr.attr,
340 &sensor_dev_attr_curr3_max_alarm.dev_attr.attr,
341 &sensor_dev_attr_curr4_max_alarm.dev_attr.attr,
342
343 &sensor_dev_attr_in5_input.dev_attr.attr,
344 &sensor_dev_attr_in6_input.dev_attr.attr,
345 &sensor_dev_attr_in7_input.dev_attr.attr,
346 &sensor_dev_attr_in8_input.dev_attr.attr,
347
348 &sensor_dev_attr_in5_min_alarm.dev_attr.attr,
349 &sensor_dev_attr_in6_min_alarm.dev_attr.attr,
350 &sensor_dev_attr_in7_min_alarm.dev_attr.attr,
351 &sensor_dev_attr_in8_min_alarm.dev_attr.attr,
352
353 &sensor_dev_attr_in9_input.dev_attr.attr,
354 &sensor_dev_attr_in10_input.dev_attr.attr,
355 &sensor_dev_attr_in11_input.dev_attr.attr,
356
357 &sensor_dev_attr_power1_input.dev_attr.attr,
358 &sensor_dev_attr_power2_input.dev_attr.attr,
359 &sensor_dev_attr_power3_input.dev_attr.attr,
360 &sensor_dev_attr_power4_input.dev_attr.attr,
361
362 NULL,
363};
364
365static const struct attribute_group ltc4245_group = {
366 .attrs = ltc4245_attributes,
367};
368
369static int ltc4245_probe(struct i2c_client *client,
370 const struct i2c_device_id *id)
371{
372 struct ltc4245_data *data;
373 int ret;
374
375 data = kzalloc(sizeof(*data), GFP_KERNEL);
376 if (!data) {
377 ret = -ENOMEM;
378 goto out_kzalloc;
379 }
380
381 i2c_set_clientdata(client, data);
382 mutex_init(&data->update_lock);
383
384 /* Initialize the LTC4245 chip */
385 /* TODO */
386
387 /* Register sysfs hooks */
388 ret = sysfs_create_group(&client->dev.kobj, &ltc4245_group);
389 if (ret)
390 goto out_sysfs_create_group;
391
392 data->hwmon_dev = hwmon_device_register(&client->dev);
393 if (IS_ERR(data->hwmon_dev)) {
394 ret = PTR_ERR(data->hwmon_dev);
395 goto out_hwmon_device_register;
396 }
397
398 return 0;
399
400out_hwmon_device_register:
401 sysfs_remove_group(&client->dev.kobj, &ltc4245_group);
402out_sysfs_create_group:
403 kfree(data);
404out_kzalloc:
405 return ret;
406}
407
408static int ltc4245_remove(struct i2c_client *client)
409{
410 struct ltc4245_data *data = i2c_get_clientdata(client);
411
412 hwmon_device_unregister(data->hwmon_dev);
413 sysfs_remove_group(&client->dev.kobj, &ltc4245_group);
414
415 kfree(data);
416
417 return 0;
418}
419
420/* Check that some bits in a control register appear at all possible
421 * locations without changing value
422 *
423 * @client: the i2c client to use
424 * @reg: the register to read
425 * @bits: the bits to check (0xff checks all bits,
426 * 0x03 checks only the last two bits)
427 *
428 * return -ERRNO if the register read failed
429 * return -ENODEV if the register value doesn't stay constant at all
430 * possible addresses
431 *
432 * return 0 for success
433 */
434static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits)
435{
436 int i;
437 s32 v, voff1, voff2;
438
439 /* Read register and check for error */
440 v = i2c_smbus_read_byte_data(client, reg);
441 if (v < 0)
442 return v;
443
444 v &= bits;
445
446 for (i = 0x00; i < 0xff; i += 0x20) {
447
448 voff1 = i2c_smbus_read_byte_data(client, reg + i);
449 if (voff1 < 0)
450 return voff1;
451
452 voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08);
453 if (voff2 < 0)
454 return voff2;
455
456 voff1 &= bits;
457 voff2 &= bits;
458
459 if (v != voff1 || v != voff2)
460 return -ENODEV;
461 }
462
463 return 0;
464}
465
466static int ltc4245_detect(struct i2c_client *client,
467 int kind,
468 struct i2c_board_info *info)
469{
470 struct i2c_adapter *adapter = client->adapter;
471
472 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
473 return -ENODEV;
474
475 if (kind < 0) { /* probed detection - check the chip type */
476 s32 v; /* 8 bits from the chip, or -ERRNO */
477
478 /* Chip registers 0x00-0x07 are control registers
479 * Chip registers 0x10-0x1f are data registers
480 *
481 * Address bits b7-b5 are ignored. This makes the chip "repeat"
482 * in steps of 0x20. Any control registers should appear with
483 * the same values across all duplicated addresses.
484 *
485 * Register 0x02 bit b2 is reserved, expect 0
486 * Register 0x07 bits b7 to b4 are reserved, expect 0
487 *
488 * Registers 0x01, 0x02 are control registers and should not
489 * change on their own.
490 *
491 * Register 0x06 bits b6 and b7 are control bits, and should
492 * not change on their own.
493 *
494 * Register 0x07 bits b3 to b0 are control bits, and should
495 * not change on their own.
496 */
497
498 /* read register 0x02 reserved bit, expect 0 */
499 v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL);
500 if (v < 0 || (v & 0x04) != 0)
501 return -ENODEV;
502
503 /* read register 0x07 reserved bits, expect 0 */
504 v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR);
505 if (v < 0 || (v & 0xf0) != 0)
506 return -ENODEV;
507
508 /* check that the alert register appears at all locations */
509 if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff))
510 return -ENODEV;
511
512 /* check that the control register appears at all locations */
513 if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff))
514 return -ENODEV;
515
516 /* check that register 0x06 bits b6 and b7 stay constant */
517 if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0))
518 return -ENODEV;
519
520 /* check that register 0x07 bits b3-b0 stay constant */
521 if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f))
522 return -ENODEV;
523 }
524
525 strlcpy(info->type, "ltc4245", I2C_NAME_SIZE);
526 dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n",
527 kind < 0 ? "probed" : "forced",
528 client->addr);
529
530 return 0;
531}
532
533static const struct i2c_device_id ltc4245_id[] = {
534 { "ltc4245", ltc4245 },
535 { }
536};
537MODULE_DEVICE_TABLE(i2c, ltc4245_id);
538
539/* This is the driver that will be inserted */
540static struct i2c_driver ltc4245_driver = {
541 .class = I2C_CLASS_HWMON,
542 .driver = {
543 .name = "ltc4245",
544 },
545 .probe = ltc4245_probe,
546 .remove = ltc4245_remove,
547 .id_table = ltc4245_id,
548 .detect = ltc4245_detect,
549 .address_data = &addr_data,
550};
551
552static int __init ltc4245_init(void)
553{
554 return i2c_add_driver(&ltc4245_driver);
555}
556
557static void __exit ltc4245_exit(void)
558{
559 i2c_del_driver(&ltc4245_driver);
560}
561
562MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
563MODULE_DESCRIPTION("LTC4245 driver");
564MODULE_LICENSE("GPL");
565
566module_init(ltc4245_init);
567module_exit(ltc4245_exit);
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 5fbfa34c110e..fb052fea3744 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -43,6 +43,7 @@
43#include <linux/hwmon-vid.h> 43#include <linux/hwmon-vid.h>
44#include <linux/err.h> 44#include <linux/err.h>
45#include <linux/mutex.h> 45#include <linux/mutex.h>
46#include <linux/acpi.h>
46#include <asm/io.h> 47#include <asm/io.h>
47 48
48static u8 devid; 49static u8 devid;
@@ -1627,6 +1628,11 @@ static int __init pc87360_device_add(unsigned short address)
1627 continue; 1628 continue;
1628 res.start = extra_isa[i]; 1629 res.start = extra_isa[i];
1629 res.end = extra_isa[i] + PC87360_EXTENT - 1; 1630 res.end = extra_isa[i] + PC87360_EXTENT - 1;
1631
1632 err = acpi_check_resource_conflict(&res);
1633 if (err)
1634 goto exit_device_put;
1635
1630 err = platform_device_add_resources(pdev, &res, 1); 1636 err = platform_device_add_resources(pdev, &res, 1);
1631 if (err) { 1637 if (err) {
1632 printk(KERN_ERR "pc87360: Device resource[%d] " 1638 printk(KERN_ERR "pc87360: Device resource[%d] "
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 7265f22ae5cd..3a8a0f7a7736 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -32,6 +32,7 @@
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/sysfs.h> 33#include <linux/sysfs.h>
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/acpi.h>
35#include <asm/io.h> 36#include <asm/io.h>
36 37
37static unsigned short force_id; 38static unsigned short force_id;
@@ -524,6 +525,10 @@ static int __init pc87427_device_add(unsigned short address)
524 }; 525 };
525 int err; 526 int err;
526 527
528 err = acpi_check_resource_conflict(&res);
529 if (err)
530 goto exit;
531
527 pdev = platform_device_alloc(DRVNAME, address); 532 pdev = platform_device_alloc(DRVNAME, address);
528 if (!pdev) { 533 if (!pdev) {
529 err = -ENOMEM; 534 err = -ENOMEM;
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index a276806f3d53..aa2e8318f167 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -62,6 +62,7 @@
62#include <linux/jiffies.h> 62#include <linux/jiffies.h>
63#include <linux/mutex.h> 63#include <linux/mutex.h>
64#include <linux/sysfs.h> 64#include <linux/sysfs.h>
65#include <linux/acpi.h>
65#include <asm/io.h> 66#include <asm/io.h>
66 67
67 68
@@ -727,6 +728,10 @@ static int __devinit sis5595_device_add(unsigned short address)
727 }; 728 };
728 int err; 729 int err;
729 730
731 err = acpi_check_resource_conflict(&res);
732 if (err)
733 goto exit;
734
730 pdev = platform_device_alloc("sis5595", address); 735 pdev = platform_device_alloc("sis5595", address);
731 if (!pdev) { 736 if (!pdev) {
732 err = -ENOMEM; 737 err = -ENOMEM;
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index eb03544c731c..6f6d52b4fb64 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -36,6 +36,7 @@
36#include <linux/err.h> 36#include <linux/err.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <linux/acpi.h>
39#include <asm/io.h> 40#include <asm/io.h>
40 41
41static unsigned short force_id; 42static unsigned short force_id;
@@ -303,6 +304,10 @@ static int __init smsc47b397_device_add(unsigned short address)
303 }; 304 };
304 int err; 305 int err;
305 306
307 err = acpi_check_resource_conflict(&res);
308 if (err)
309 goto exit;
310
306 pdev = platform_device_alloc(DRVNAME, address); 311 pdev = platform_device_alloc(DRVNAME, address);
307 if (!pdev) { 312 if (!pdev) {
308 err = -ENOMEM; 313 err = -ENOMEM;
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index d1b498548736..a92dbb97ee99 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -37,6 +37,7 @@
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <linux/sysfs.h> 39#include <linux/sysfs.h>
40#include <linux/acpi.h>
40#include <asm/io.h> 41#include <asm/io.h>
41 42
42static unsigned short force_id; 43static unsigned short force_id;
@@ -705,6 +706,10 @@ static int __init smsc47m1_device_add(unsigned short address,
705 }; 706 };
706 int err; 707 int err;
707 708
709 err = acpi_check_resource_conflict(&res);
710 if (err)
711 goto exit;
712
708 pdev = platform_device_alloc(DRVNAME, address); 713 pdev = platform_device_alloc(DRVNAME, address);
709 if (!pdev) { 714 if (!pdev) {
710 err = -ENOMEM; 715 err = -ENOMEM;
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index f1ee5e731968..a022aedcaacb 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -41,6 +41,7 @@
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/mutex.h> 42#include <linux/mutex.h>
43#include <linux/sysfs.h> 43#include <linux/sysfs.h>
44#include <linux/acpi.h>
44#include <asm/io.h> 45#include <asm/io.h>
45 46
46 47
@@ -783,6 +784,10 @@ static int __devinit via686a_device_add(unsigned short address)
783 }; 784 };
784 int err; 785 int err;
785 786
787 err = acpi_check_resource_conflict(&res);
788 if (err)
789 goto exit;
790
786 pdev = platform_device_alloc("via686a", address); 791 pdev = platform_device_alloc("via686a", address);
787 if (!pdev) { 792 if (!pdev) {
788 err = -ENOMEM; 793 err = -ENOMEM;
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 12b43590fa53..b0ce37852281 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -32,6 +32,7 @@
32#include <linux/err.h> 32#include <linux/err.h>
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/acpi.h>
35#include <asm/io.h> 36#include <asm/io.h>
36 37
37static int uch_config = -1; 38static int uch_config = -1;
@@ -1259,6 +1260,10 @@ static int __init vt1211_device_add(unsigned short address)
1259 } 1260 }
1260 1261
1261 res.name = pdev->name; 1262 res.name = pdev->name;
1263 err = acpi_check_resource_conflict(&res);
1264 if (err)
1265 goto EXIT;
1266
1262 err = platform_device_add_resources(pdev, &res, 1); 1267 err = platform_device_add_resources(pdev, &res, 1);
1263 if (err) { 1268 if (err) {
1264 printk(KERN_ERR DRVNAME ": Device resource addition failed " 1269 printk(KERN_ERR DRVNAME ": Device resource addition failed "
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 5bc57275cae8..9982b45fbb14 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -35,6 +35,7 @@
35#include <linux/hwmon-vid.h> 35#include <linux/hwmon-vid.h>
36#include <linux/err.h> 36#include <linux/err.h>
37#include <linux/mutex.h> 37#include <linux/mutex.h>
38#include <linux/acpi.h>
38#include <asm/io.h> 39#include <asm/io.h>
39 40
40static int force_addr; 41static int force_addr;
@@ -894,6 +895,10 @@ static int __devinit vt8231_device_add(unsigned short address)
894 }; 895 };
895 int err; 896 int err;
896 897
898 err = acpi_check_resource_conflict(&res);
899 if (err)
900 goto exit;
901
897 pdev = platform_device_alloc("vt8231", address); 902 pdev = platform_device_alloc("vt8231", address);
898 if (!pdev) { 903 if (!pdev) {
899 err = -ENOMEM; 904 err = -ENOMEM;
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 075164dd65a7..cb808d015361 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -48,6 +48,7 @@
48#include <linux/hwmon-vid.h> 48#include <linux/hwmon-vid.h>
49#include <linux/err.h> 49#include <linux/err.h>
50#include <linux/mutex.h> 50#include <linux/mutex.h>
51#include <linux/acpi.h>
51#include <asm/io.h> 52#include <asm/io.h>
52#include "lm75.h" 53#include "lm75.h"
53 54
@@ -502,7 +503,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
502 } 503 }
503 504
504 for (i = 0; i < 4; i++) { 505 for (i = 0; i < 4; i++) {
505 /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ 506 /* pwmcfg, tolerance mapped for i=0, i=1 to same reg */
506 if (i != 1) { 507 if (i != 1) {
507 pwmcfg = w83627ehf_read_value(data, 508 pwmcfg = w83627ehf_read_value(data,
508 W83627EHF_REG_PWM_ENABLE[i]); 509 W83627EHF_REG_PWM_ENABLE[i]);
@@ -1544,6 +1545,11 @@ static int __init sensors_w83627ehf_init(void)
1544 res.start = address + IOREGION_OFFSET; 1545 res.start = address + IOREGION_OFFSET;
1545 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; 1546 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1546 res.flags = IORESOURCE_IO; 1547 res.flags = IORESOURCE_IO;
1548
1549 err = acpi_check_resource_conflict(&res);
1550 if (err)
1551 goto exit;
1552
1547 err = platform_device_add_resources(pdev, &res, 1); 1553 err = platform_device_add_resources(pdev, &res, 1);
1548 if (err) { 1554 if (err) {
1549 printk(KERN_ERR DRVNAME ": Device resource addition failed " 1555 printk(KERN_ERR DRVNAME ": Device resource addition failed "
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index b30e5796cb26..389150ba30d3 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -50,6 +50,7 @@
50#include <linux/err.h> 50#include <linux/err.h>
51#include <linux/mutex.h> 51#include <linux/mutex.h>
52#include <linux/ioport.h> 52#include <linux/ioport.h>
53#include <linux/acpi.h>
53#include <asm/io.h> 54#include <asm/io.h>
54#include "lm75.h" 55#include "lm75.h"
55 56
@@ -1793,6 +1794,10 @@ static int __init w83627hf_device_add(unsigned short address,
1793 }; 1794 };
1794 int err; 1795 int err;
1795 1796
1797 err = acpi_check_resource_conflict(&res);
1798 if (err)
1799 goto exit;
1800
1796 pdev = platform_device_alloc(DRVNAME, address); 1801 pdev = platform_device_alloc(DRVNAME, address);
1797 if (!pdev) { 1802 if (!pdev) {
1798 err = -ENOMEM; 1803 err = -ENOMEM;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index fc12bd412e3a..dbfb30c588d8 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -58,7 +58,10 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
58 0x2e, 0x2f, I2C_CLIENT_END }; 58 0x2e, 0x2f, I2C_CLIENT_END };
59/* Insmod parameters */ 59/* Insmod parameters */
60I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f); 60I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f);
61I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " 61
62static unsigned short force_subclients[4];
63module_param_array(force_subclients, short, NULL, 0);
64MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
62 "{bus, clientaddr, subclientaddr1, subclientaddr2}"); 65 "{bus, clientaddr, subclientaddr1, subclientaddr2}");
63 66
64static int reset; 67static int reset;
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 5768def8a4f2..97851c5ba3a3 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -53,7 +53,10 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
53 53
54/* Insmod parameters */ 54/* Insmod parameters */
55I2C_CLIENT_INSMOD_1(w83791d); 55I2C_CLIENT_INSMOD_1(w83791d);
56I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " 56
57static unsigned short force_subclients[4];
58module_param_array(force_subclients, short, NULL, 0);
59MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
57 "{bus, clientaddr, subclientaddr1, subclientaddr2}"); 60 "{bus, clientaddr, subclientaddr1, subclientaddr2}");
58 61
59static int reset; 62static int reset;
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index cf94c5b0c879..2be16194ddf3 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -51,7 +51,10 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
51 51
52/* Insmod parameters */ 52/* Insmod parameters */
53I2C_CLIENT_INSMOD_1(w83792d); 53I2C_CLIENT_INSMOD_1(w83792d);
54I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " 54
55static unsigned short force_subclients[4];
56module_param_array(force_subclients, short, NULL, 0);
57MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
55 "{bus, clientaddr, subclientaddr1, subclientaddr2}"); 58 "{bus, clientaddr, subclientaddr1, subclientaddr2}");
56 59
57static int init; 60static int init;
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 0a739f1c69be..47dd398f7258 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -42,7 +42,10 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
42 42
43/* Insmod parameters */ 43/* Insmod parameters */
44I2C_CLIENT_INSMOD_1(w83793); 44I2C_CLIENT_INSMOD_1(w83793);
45I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " 45
46static unsigned short force_subclients[4];
47module_param_array(force_subclients, short, NULL, 0);
48MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
46 "{bus, clientaddr, subclientaddr1, subclientaddr2}"); 49 "{bus, clientaddr, subclientaddr1, subclientaddr2}");
47 50
48static int reset; 51static int reset;