aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/adm10314
-rw-r--r--Documentation/hwmon/thmc5074
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/abituguru3.c5
-rw-r--r--drivers/hwmon/ams/ams-core.c1
-rw-r--r--drivers/hwmon/applesmc.c14
-rw-r--r--drivers/hwmon/dme1737.c2
-rw-r--r--drivers/hwmon/fscher.c4
-rw-r--r--drivers/hwmon/it87.c2
-rw-r--r--drivers/hwmon/lm78.c2
-rw-r--r--drivers/hwmon/lm90.c2
-rw-r--r--drivers/hwmon/lm93.c2
-rw-r--r--drivers/hwmon/pc87360.c2
-rw-r--r--drivers/hwmon/sis5595.c2
-rw-r--r--drivers/hwmon/smsc47m1.c2
-rw-r--r--drivers/hwmon/thmc50.c440
-rw-r--r--drivers/hwmon/via686a.c2
-rw-r--r--drivers/hwmon/vt8231.c4
-rw-r--r--drivers/hwmon/w83627hf.c2
20 files changed, 554 insertions, 23 deletions
diff --git a/Documentation/hwmon/adm1031 b/Documentation/hwmon/adm1031
index 130a38382b98..be92a77da1d5 100644
--- a/Documentation/hwmon/adm1031
+++ b/Documentation/hwmon/adm1031
@@ -6,13 +6,13 @@ Supported chips:
6 Prefix: 'adm1030' 6 Prefix: 'adm1030'
7 Addresses scanned: I2C 0x2c to 0x2e 7 Addresses scanned: I2C 0x2c to 0x2e
8 Datasheet: Publicly available at the Analog Devices website 8 Datasheet: Publicly available at the Analog Devices website
9 http://products.analog.com/products/info.asp?product=ADM1030 9 http://www.analog.com/en/prod/0%2C2877%2CADM1030%2C00.html
10 10
11 * Analog Devices ADM1031 11 * Analog Devices ADM1031
12 Prefix: 'adm1031' 12 Prefix: 'adm1031'
13 Addresses scanned: I2C 0x2c to 0x2e 13 Addresses scanned: I2C 0x2c to 0x2e
14 Datasheet: Publicly available at the Analog Devices website 14 Datasheet: Publicly available at the Analog Devices website
15 http://products.analog.com/products/info.asp?product=ADM1031 15 http://www.analog.com/en/prod/0%2C2877%2CADM1031%2C00.html
16 16
17Authors: 17Authors:
18 Alexandre d'Alton <alex@alexdalton.org> 18 Alexandre d'Alton <alex@alexdalton.org>
diff --git a/Documentation/hwmon/thmc50 b/Documentation/hwmon/thmc50
new file mode 100644
index 000000000000..9639ca93d559
--- /dev/null
+++ b/Documentation/hwmon/thmc50
@@ -0,0 +1,74 @@
1Kernel driver thmc50
2=====================
3
4Supported chips:
5 * Analog Devices ADM1022
6 Prefix: 'adm1022'
7 Addresses scanned: I2C 0x2c - 0x2e
8 Datasheet: http://www.analog.com/en/prod/0,2877,ADM1022,00.html
9 * Texas Instruments THMC50
10 Prefix: 'thmc50'
11 Addresses scanned: I2C 0x2c - 0x2e
12 Datasheet: http://focus.ti.com/docs/prod/folders/print/thmc50.html
13
14Author: Krzysztof Helt <krzysztof.h1@wp.pl>
15
16This driver was derived from the 2.4 kernel thmc50.c source file.
17
18Credits:
19 thmc50.c (2.4 kernel):
20 Frodo Looijaard <frodol@dds.nl>
21 Philip Edelbrock <phil@netroedge.com>
22
23Module Parameters
24-----------------
25
26* adm1022_temp3: short array
27 List of adapter,address pairs to force chips into ADM1022 mode with
28 second remote temperature. This does not work for original THMC50 chips.
29
30Description
31-----------
32
33The THMC50 implements: an internal temperature sensor, support for an
34external diode-type temperature sensor (compatible w/ the diode sensor inside
35many processors), and a controllable fan/analog_out DAC. For the temperature
36sensors, limits can be set through the appropriate Overtemperature Shutdown
37register and Hysteresis register. Each value can be set and read to half-degree
38accuracy. An alarm is issued (usually to a connected LM78) when the
39temperature gets higher then the Overtemperature Shutdown value; it stays on
40until the temperature falls below the Hysteresis value. All temperatures are in
41degrees Celsius, and are guaranteed within a range of -55 to +125 degrees.
42
43The THMC50 only updates its values each 1.5 seconds; reading it more often
44will do no harm, but will return 'old' values.
45
46The THMC50 is usually used in combination with LM78-like chips, to measure
47the temperature of the processor(s).
48
49The ADM1022 works the same as THMC50 but it is faster (5 Hz instead of
501 Hz for THMC50). It can be also put in a new mode to handle additional
51remote temperature sensor. The driver use the mode set by BIOS by default.
52
53In case the BIOS is broken and the mode is set incorrectly, you can force
54the mode with additional remote temperature with adm1022_temp3 parameter.
55A typical symptom of wrong setting is a fan forced to full speed.
56
57Driver Features
58---------------
59
60The driver provides up to three temperatures:
61
62temp1 -- internal
63temp2 -- remote
64temp3 -- 2nd remote only for ADM1022
65
66pwm1 -- fan speed (0 = stop, 255 = full)
67pwm1_mode -- always 0 (DC mode)
68
69The value of 0 for pwm1 also forces FAN_OFF signal from the chip,
70so it stops fans even if the value 0 into the ANALOG_OUT register does not.
71
72The driver was tested on Compaq AP550 with two ADM1022 chips (one works
73in the temp3 mode), five temperature readings and two fans.
74
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index dbdca6f10e46..192953b29b28 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -520,6 +520,16 @@ config SENSORS_SMSC47B397
520 This driver can also be built as a module. If so, the module 520 This driver can also be built as a module. If so, the module
521 will be called smsc47b397. 521 will be called smsc47b397.
522 522
523config SENSORS_THMC50
524 tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
525 depends on I2C && EXPERIMENTAL
526 help
527 If you say yes here you get support for Texas Instruments THMC50
528 sensor chips and clones: the Analog Devices ADM1022.
529
530 This driver can also be built as a module. If so, the module
531 will be called thmc50.
532
523config SENSORS_VIA686A 533config SENSORS_VIA686A
524 tristate "VIA686A" 534 tristate "VIA686A"
525 depends on PCI 535 depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 59f81fae40a0..d04f90031ebf 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
56obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o 56obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
57obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o 57obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
58obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o 58obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
59obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
59obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 60obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
60obj-$(CONFIG_SENSORS_VT1211) += vt1211.o 61obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
61obj-$(CONFIG_SENSORS_VT8231) += vt8231.o 62obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index a003d104ca45..cdd8b6dea16d 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -691,8 +691,9 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
691 691
692/* Sensor settings are stored 1 byte per offset with the bytes 692/* Sensor settings are stored 1 byte per offset with the bytes
693 placed add consecutive offsets. */ 693 placed add consecutive offsets. */
694int abituguru3_read_increment_offset(struct abituguru3_data *data, u8 bank, 694static int abituguru3_read_increment_offset(struct abituguru3_data *data,
695 u8 offset, u8 count, u8 *buf, int offset_count) 695 u8 bank, u8 offset, u8 count,
696 u8 *buf, int offset_count)
696{ 697{
697 int i, x; 698 int i, x;
698 699
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
index 6db973739725..a112a03e8f29 100644
--- a/drivers/hwmon/ams/ams-core.c
+++ b/drivers/hwmon/ams/ams-core.c
@@ -23,7 +23,6 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/module.h>
27#include <asm/pmac_pfunc.h> 26#include <asm/pmac_pfunc.h>
28#include <asm/of_platform.h> 27#include <asm/of_platform.h>
29 28
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index fd1281f42209..941729a131f5 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -79,11 +79,15 @@
79 79
80/* 80/*
81 * Temperature sensors keys (sp78 - 2 bytes). 81 * Temperature sensors keys (sp78 - 2 bytes).
82 * First set for Macbook(Pro), second for Macmini.
83 */ 82 */
84static const char* temperature_sensors_sets[][13] = { 83static const char* temperature_sensors_sets[][13] = {
84/* Set 0: Macbook Pro */
85 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", 85 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
86 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, 86 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
87/* Set 1: Macbook set */
88 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
89 "Th1H", "Ts0P", NULL },
90/* Set 2: Macmini set */
87 { "TC0D", "TC0P", NULL } 91 { "TC0D", "TC0P", NULL }
88}; 92};
89 93
@@ -1150,10 +1154,10 @@ static void applesmc_release_accelerometer(void)
1150static __initdata struct dmi_match_data applesmc_dmi_data[] = { 1154static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1151/* MacBook Pro: accelerometer, backlight and temperature set 0 */ 1155/* MacBook Pro: accelerometer, backlight and temperature set 0 */
1152 { .accelerometer = 1, .light = 1, .temperature_set = 0 }, 1156 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1153/* MacBook: accelerometer and temperature set 0 */ 1157/* MacBook: accelerometer and temperature set 1 */
1154 { .accelerometer = 1, .light = 0, .temperature_set = 0 }, 1158 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1155/* MacBook: temperature set 1 */ 1159/* MacMini: temperature set 2 */
1156 { .accelerometer = 0, .light = 0, .temperature_set = 1 } 1160 { .accelerometer = 0, .light = 0, .temperature_set = 2 },
1157}; 1161};
1158 1162
1159/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". 1163/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index be3aaa5d0b91..e9cbc727664d 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -750,7 +750,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
750 res = (data->alarms >> DME1737_BIT_ALARM_TEMP[ix]) & 0x01; 750 res = (data->alarms >> DME1737_BIT_ALARM_TEMP[ix]) & 0x01;
751 break; 751 break;
752 case SYS_TEMP_FAULT: 752 case SYS_TEMP_FAULT:
753 res = (data->temp[ix] == 0x0800); 753 res = (((u16)data->temp[ix] & 0xff00) == 0x8000);
754 break; 754 break;
755 default: 755 default:
756 res = 0; 756 res = 0;
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
index 19717752cfca..b34b546c68b8 100644
--- a/drivers/hwmon/fscher.c
+++ b/drivers/hwmon/fscher.c
@@ -441,6 +441,8 @@ static struct fscher_data *fscher_update_device(struct device *dev)
441 data->watchdog[2] = fscher_read_value(client, FSCHER_REG_WDOG_CONTROL); 441 data->watchdog[2] = fscher_read_value(client, FSCHER_REG_WDOG_CONTROL);
442 442
443 data->global_event = fscher_read_value(client, FSCHER_REG_EVENT_STATE); 443 data->global_event = fscher_read_value(client, FSCHER_REG_EVENT_STATE);
444 data->global_control = fscher_read_value(client,
445 FSCHER_REG_CONTROL);
444 446
445 data->last_updated = jiffies; 447 data->last_updated = jiffies;
446 data->valid = 1; 448 data->valid = 1;
@@ -599,7 +601,7 @@ static ssize_t set_control(struct i2c_client *client, struct fscher_data *data,
599 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01; 601 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01;
600 602
601 mutex_lock(&data->update_lock); 603 mutex_lock(&data->update_lock);
602 data->global_control &= ~v; 604 data->global_control = v;
603 fscher_write_value(client, reg, v); 605 fscher_write_value(client, reg, v);
604 mutex_unlock(&data->update_lock); 606 mutex_unlock(&data->update_lock);
605 return count; 607 return count;
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index eff6036e15c0..d75dba9b810b 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -252,7 +252,7 @@ struct it87_data {
252 252
253 253
254static int it87_probe(struct platform_device *pdev); 254static int it87_probe(struct platform_device *pdev);
255static int it87_remove(struct platform_device *pdev); 255static int __devexit it87_remove(struct platform_device *pdev);
256 256
257static int it87_read_value(struct it87_data *data, u8 reg); 257static int it87_read_value(struct it87_data *data, u8 reg);
258static void it87_write_value(struct it87_data *data, u8 reg, u8 value); 258static void it87_write_value(struct it87_data *data, u8 reg, u8 value);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 9fb572f03ba5..565c4e679b8d 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -864,7 +864,7 @@ static int __init lm78_isa_found(unsigned short address)
864 /* Determine the chip type */ 864 /* Determine the chip type */
865 outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET); 865 outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET);
866 val = inb_p(address + LM78_DATA_REG_OFFSET); 866 val = inb_p(address + LM78_DATA_REG_OFFSET);
867 if (val == 0x00 /* LM78 */ 867 if (val == 0x00 || val == 0x20 /* LM78 */
868 || val == 0x40 /* LM78-J */ 868 || val == 0x40 /* LM78-J */
869 || (val & 0xfe) == 0xc0) /* LM79 */ 869 || (val & 0xfe) == 0xc0) /* LM79 */
870 found = 1; 870 found = 1;
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 48833fff4920..af541d67245d 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -585,7 +585,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
585 * those of the man_id register. 585 * those of the man_id register.
586 */ 586 */
587 if (chip_id == man_id 587 if (chip_id == man_id
588 && (address == 0x4F || address == 0x4D) 588 && (address == 0x4C || address == 0x4D)
589 && (reg_config1 & 0x1F) == (man_id & 0x0F) 589 && (reg_config1 & 0x1F) == (man_id & 0x0F)
590 && reg_convrate <= 0x09) { 590 && reg_convrate <= 0x09) {
591 kind = max6657; 591 kind = max6657;
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index 23edf4fe4221..d84f8bf6f284 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -234,7 +234,7 @@ struct lm93_data {
234 struct { 234 struct {
235 u8 min; 235 u8 min;
236 u8 max; 236 u8 max;
237 } temp_lim[3]; 237 } temp_lim[4];
238 238
239 /* vin1 - vin16: low and high limits */ 239 /* vin1 - vin16: low and high limits */
240 struct { 240 struct {
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index cb72526c346a..f57c75d59a5b 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -220,7 +220,7 @@ struct pc87360_data {
220 */ 220 */
221 221
222static int pc87360_probe(struct platform_device *pdev); 222static int pc87360_probe(struct platform_device *pdev);
223static int pc87360_remove(struct platform_device *pdev); 223static int __devexit pc87360_remove(struct platform_device *pdev);
224 224
225static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, 225static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
226 u8 reg); 226 u8 reg);
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 83321b28cf0e..92956eb3f3c1 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -187,7 +187,7 @@ struct sis5595_data {
187static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ 187static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */
188 188
189static int sis5595_probe(struct platform_device *pdev); 189static int sis5595_probe(struct platform_device *pdev);
190static int sis5595_remove(struct platform_device *pdev); 190static int __devexit sis5595_remove(struct platform_device *pdev);
191 191
192static int sis5595_read_value(struct sis5595_data *data, u8 reg); 192static int sis5595_read_value(struct sis5595_data *data, u8 reg);
193static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value); 193static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 1de2f2be8708..338ee4f54614 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -134,7 +134,7 @@ struct smsc47m1_sio_data {
134 134
135 135
136static int smsc47m1_probe(struct platform_device *pdev); 136static int smsc47m1_probe(struct platform_device *pdev);
137static int smsc47m1_remove(struct platform_device *pdev); 137static int __devexit smsc47m1_remove(struct platform_device *pdev);
138static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 138static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
139 int init); 139 int init);
140 140
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
new file mode 100644
index 000000000000..9395b52d9b99
--- /dev/null
+++ b/drivers/hwmon/thmc50.c
@@ -0,0 +1,440 @@
1/*
2 thmc50.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
5 Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and
6 Philip Edelbrock <phil@netroedge.com>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/i2c.h>
27#include <linux/hwmon.h>
28#include <linux/hwmon-sysfs.h>
29#include <linux/err.h>
30#include <linux/mutex.h>
31
32MODULE_LICENSE("GPL");
33
34/* Addresses to scan */
35static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
36
37/* Insmod parameters */
38I2C_CLIENT_INSMOD_2(thmc50, adm1022);
39I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
40 "to enable 3rd temperature (ADM1022 only)");
41
42/* Many THMC50 constants specified below */
43
44/* The THMC50 registers */
45#define THMC50_REG_CONF 0x40
46#define THMC50_REG_COMPANY_ID 0x3E
47#define THMC50_REG_DIE_CODE 0x3F
48#define THMC50_REG_ANALOG_OUT 0x19
49
50const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
51const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
52const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
53
54#define THMC50_REG_CONF_nFANOFF 0x20
55
56/* Each client has this additional data */
57struct thmc50_data {
58 struct i2c_client client;
59 struct class_device *class_dev;
60
61 struct mutex update_lock;
62 enum chips type;
63 unsigned long last_updated; /* In jiffies */
64 char has_temp3; /* !=0 if it is ADM1022 in temp3 mode */
65 char valid; /* !=0 if following fields are valid */
66
67 /* Register values */
68 s8 temp_input[3];
69 s8 temp_max[3];
70 s8 temp_min[3];
71 u8 analog_out;
72};
73
74static int thmc50_attach_adapter(struct i2c_adapter *adapter);
75static int thmc50_detach_client(struct i2c_client *client);
76static void thmc50_init_client(struct i2c_client *client);
77static struct thmc50_data *thmc50_update_device(struct device *dev);
78
79static struct i2c_driver thmc50_driver = {
80 .driver = {
81 .name = "thmc50",
82 },
83 .attach_adapter = thmc50_attach_adapter,
84 .detach_client = thmc50_detach_client,
85};
86
87static ssize_t show_analog_out(struct device *dev,
88 struct device_attribute *attr, char *buf)
89{
90 struct thmc50_data *data = thmc50_update_device(dev);
91 return sprintf(buf, "%d\n", data->analog_out);
92}
93
94static ssize_t set_analog_out(struct device *dev,
95 struct device_attribute *attr,
96 const char *buf, size_t count)
97{
98 struct i2c_client *client = to_i2c_client(dev);
99 struct thmc50_data *data = i2c_get_clientdata(client);
100 int tmp = simple_strtoul(buf, NULL, 10);
101 int config;
102
103 mutex_lock(&data->update_lock);
104 data->analog_out = SENSORS_LIMIT(tmp, 0, 255);
105 i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,
106 data->analog_out);
107
108 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
109 if (data->analog_out == 0)
110 config &= ~THMC50_REG_CONF_nFANOFF;
111 else
112 config |= THMC50_REG_CONF_nFANOFF;
113 i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
114
115 mutex_unlock(&data->update_lock);
116 return count;
117}
118
119/* There is only one PWM mode = DC */
120static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr,
121 char *buf)
122{
123 return sprintf(buf, "0\n");
124}
125
126/* Temperatures */
127static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
128 char *buf)
129{
130 int nr = to_sensor_dev_attr(attr)->index;
131 struct thmc50_data *data = thmc50_update_device(dev);
132 return sprintf(buf, "%d\n", data->temp_input[nr] * 1000);
133}
134
135static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
136 char *buf)
137{
138 int nr = to_sensor_dev_attr(attr)->index;
139 struct thmc50_data *data = thmc50_update_device(dev);
140 return sprintf(buf, "%d\n", data->temp_min[nr] * 1000);
141}
142
143static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
144 const char *buf, size_t count)
145{
146 int nr = to_sensor_dev_attr(attr)->index;
147 struct i2c_client *client = to_i2c_client(dev);
148 struct thmc50_data *data = i2c_get_clientdata(client);
149 int val = simple_strtol(buf, NULL, 10);
150
151 mutex_lock(&data->update_lock);
152 data->temp_min[nr] = SENSORS_LIMIT(val / 1000, -128, 127);
153 i2c_smbus_write_byte_data(client, THMC50_REG_TEMP_MIN[nr],
154 data->temp_min[nr]);
155 mutex_unlock(&data->update_lock);
156 return count;
157}
158
159static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
160 char *buf)
161{
162 int nr = to_sensor_dev_attr(attr)->index;
163 struct thmc50_data *data = thmc50_update_device(dev);
164 return sprintf(buf, "%d\n", data->temp_max[nr] * 1000);
165}
166
167static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
168 const char *buf, size_t count)
169{
170 int nr = to_sensor_dev_attr(attr)->index;
171 struct i2c_client *client = to_i2c_client(dev);
172 struct thmc50_data *data = i2c_get_clientdata(client);
173 int val = simple_strtol(buf, NULL, 10);
174
175 mutex_lock(&data->update_lock);
176 data->temp_max[nr] = SENSORS_LIMIT(val / 1000, -128, 127);
177 i2c_smbus_write_byte_data(client, THMC50_REG_TEMP_MAX[nr],
178 data->temp_max[nr]);
179 mutex_unlock(&data->update_lock);
180 return count;
181}
182
183#define temp_reg(offset) \
184static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \
185 NULL, offset - 1); \
186static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
187 show_temp_min, set_temp_min, offset - 1); \
188static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
189 show_temp_max, set_temp_max, offset - 1);
190
191temp_reg(1);
192temp_reg(2);
193temp_reg(3);
194
195static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out,
196 set_analog_out, 0);
197static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
198
199static struct attribute *thmc50_attributes[] = {
200 &sensor_dev_attr_temp1_max.dev_attr.attr,
201 &sensor_dev_attr_temp1_min.dev_attr.attr,
202 &sensor_dev_attr_temp1_input.dev_attr.attr,
203 &sensor_dev_attr_temp2_max.dev_attr.attr,
204 &sensor_dev_attr_temp2_min.dev_attr.attr,
205 &sensor_dev_attr_temp2_input.dev_attr.attr,
206 &sensor_dev_attr_pwm1.dev_attr.attr,
207 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
208 NULL
209};
210
211static const struct attribute_group thmc50_group = {
212 .attrs = thmc50_attributes,
213};
214
215/* for ADM1022 3rd temperature mode */
216static struct attribute *adm1022_attributes[] = {
217 &sensor_dev_attr_temp3_max.dev_attr.attr,
218 &sensor_dev_attr_temp3_min.dev_attr.attr,
219 &sensor_dev_attr_temp3_input.dev_attr.attr,
220 NULL
221};
222
223static const struct attribute_group adm1022_group = {
224 .attrs = adm1022_attributes,
225};
226
227static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
228{
229 unsigned company;
230 unsigned revision;
231 unsigned config;
232 struct i2c_client *client;
233 struct thmc50_data *data;
234 struct device *dev;
235 int err = 0;
236 const char *type_name = "";
237
238 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
239 pr_debug("thmc50: detect failed, "
240 "smbus byte data not supported!\n");
241 goto exit;
242 }
243
244 /* OK. For now, we presume we have a valid client. We now create the
245 client structure, even though we cannot fill it completely yet.
246 But it allows us to access thmc50 registers. */
247 if (!(data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL))) {
248 pr_debug("thmc50: detect failed, kzalloc failed!\n");
249 err = -ENOMEM;
250 goto exit;
251 }
252
253 client = &data->client;
254 i2c_set_clientdata(client, data);
255 client->addr = address;
256 client->adapter = adapter;
257 client->driver = &thmc50_driver;
258 dev = &client->dev;
259
260 pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",
261 client->addr, i2c_adapter_id(client->adapter));
262
263 /* Now, we do the remaining detection. */
264 company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID);
265 revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE);
266 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
267
268 if (kind == 0)
269 kind = thmc50;
270 else if (kind < 0) {
271 err = -ENODEV;
272 if (revision >= 0xc0 && ((config & 0x10) == 0)) {
273 if (company == 0x49) {
274 kind = thmc50;
275 err = 0;
276 } else if (company == 0x41) {
277 kind = adm1022;
278 err = 0;
279 }
280 }
281 }
282 if (err == -ENODEV) {
283 pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
284 goto exit_free;
285 }
286 pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
287 type_name, (revision >> 4) - 0xc, revision & 0xf);
288 data->type = kind;
289
290 if (kind == thmc50)
291 type_name = "thmc50";
292 else if (kind == adm1022) {
293 int id = i2c_adapter_id(client->adapter);
294 int i;
295
296 type_name = "adm1022";
297 data->has_temp3 = (config >> 7) & 1; /* config MSB */
298 for (i = 0; i + 1 < adm1022_temp3_num; i += 2)
299 if (adm1022_temp3[i] == id &&
300 adm1022_temp3[i + 1] == address) {
301 /* enable 2nd remote temp */
302 data->has_temp3 = 1;
303 break;
304 }
305 }
306
307 /* Fill in the remaining client fields & put it into the global list */
308 strlcpy(client->name, type_name, I2C_NAME_SIZE);
309 mutex_init(&data->update_lock);
310
311 /* Tell the I2C layer a new client has arrived */
312 if ((err = i2c_attach_client(client)))
313 goto exit_free;
314
315 thmc50_init_client(client);
316
317 /* Register sysfs hooks */
318 if ((err = sysfs_create_group(&client->dev.kobj, &thmc50_group)))
319 goto exit_detach;
320
321 /* Register ADM1022 sysfs hooks */
322 if (data->type == adm1022)
323 if ((err = sysfs_create_group(&client->dev.kobj,
324 &adm1022_group)))
325 goto exit_remove_sysfs_thmc50;
326
327 /* Register a new directory entry with module sensors */
328 data->class_dev = hwmon_device_register(&client->dev);
329 if (IS_ERR(data->class_dev)) {
330 err = PTR_ERR(data->class_dev);
331 goto exit_remove_sysfs;
332 }
333
334 return 0;
335
336exit_remove_sysfs:
337 if (data->type == adm1022)
338 sysfs_remove_group(&client->dev.kobj, &adm1022_group);
339exit_remove_sysfs_thmc50:
340 sysfs_remove_group(&client->dev.kobj, &thmc50_group);
341exit_detach:
342 i2c_detach_client(client);
343exit_free:
344 kfree(data);
345exit:
346 return err;
347}
348
349static int thmc50_attach_adapter(struct i2c_adapter *adapter)
350{
351 if (!(adapter->class & I2C_CLASS_HWMON))
352 return 0;
353 return i2c_probe(adapter, &addr_data, thmc50_detect);
354}
355
356static int thmc50_detach_client(struct i2c_client *client)
357{
358 struct thmc50_data *data = i2c_get_clientdata(client);
359 int err;
360
361 hwmon_device_unregister(data->class_dev);
362 sysfs_remove_group(&client->dev.kobj, &thmc50_group);
363 if (data->type == adm1022)
364 sysfs_remove_group(&client->dev.kobj, &adm1022_group);
365
366 if ((err = i2c_detach_client(client)))
367 return err;
368
369 kfree(data);
370
371 return 0;
372}
373
374static void thmc50_init_client(struct i2c_client *client)
375{
376 struct thmc50_data *data = i2c_get_clientdata(client);
377 int config;
378
379 data->analog_out = i2c_smbus_read_byte_data(client,
380 THMC50_REG_ANALOG_OUT);
381 /* set up to at least 1 */
382 if (data->analog_out == 0) {
383 data->analog_out = 1;
384 i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,
385 data->analog_out);
386 }
387 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
388 config |= 0x1; /* start the chip if it is in standby mode */
389 if (data->has_temp3)
390 config |= 0x80; /* enable 2nd remote temp */
391 i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
392}
393
394static struct thmc50_data *thmc50_update_device(struct device *dev)
395{
396 struct i2c_client *client = to_i2c_client(dev);
397 struct thmc50_data *data = i2c_get_clientdata(client);
398 int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
399
400 mutex_lock(&data->update_lock);
401
402 if (time_after(jiffies, data->last_updated + timeout)
403 || !data->valid) {
404
405 int temps = data->has_temp3 ? 3 : 2;
406 int i;
407 for (i = 0; i < temps; i++) {
408 data->temp_input[i] = i2c_smbus_read_byte_data(client,
409 THMC50_REG_TEMP[i]);
410 data->temp_max[i] = i2c_smbus_read_byte_data(client,
411 THMC50_REG_TEMP_MAX[i]);
412 data->temp_min[i] = i2c_smbus_read_byte_data(client,
413 THMC50_REG_TEMP_MIN[i]);
414 }
415 data->analog_out =
416 i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
417 data->last_updated = jiffies;
418 data->valid = 1;
419 }
420
421 mutex_unlock(&data->update_lock);
422
423 return data;
424}
425
426static int __init sm_thmc50_init(void)
427{
428 return i2c_add_driver(&thmc50_driver);
429}
430
431static void __exit sm_thmc50_exit(void)
432{
433 i2c_del_driver(&thmc50_driver);
434}
435
436MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
437MODULE_DESCRIPTION("THMC50 driver");
438
439module_init(sm_thmc50_init);
440module_exit(sm_thmc50_exit);
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 24a6851491d0..696c8a2e5374 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -314,7 +314,7 @@ struct via686a_data {
314static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ 314static struct pci_dev *s_bridge; /* pointer to the (only) via686a */
315 315
316static int via686a_probe(struct platform_device *pdev); 316static int via686a_probe(struct platform_device *pdev);
317static int via686a_remove(struct platform_device *pdev); 317static int __devexit via686a_remove(struct platform_device *pdev);
318 318
319static inline int via686a_read_value(struct via686a_data *data, u8 reg) 319static inline int via686a_read_value(struct via686a_data *data, u8 reg)
320{ 320{
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index c604972f0186..3e63eaf19041 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -167,7 +167,7 @@ struct vt8231_data {
167 167
168static struct pci_dev *s_bridge; 168static struct pci_dev *s_bridge;
169static int vt8231_probe(struct platform_device *pdev); 169static int vt8231_probe(struct platform_device *pdev);
170static int vt8231_remove(struct platform_device *pdev); 170static int __devexit vt8231_remove(struct platform_device *pdev);
171static struct vt8231_data *vt8231_update_device(struct device *dev); 171static struct vt8231_data *vt8231_update_device(struct device *dev);
172static void vt8231_init_device(struct vt8231_data *data); 172static void vt8231_init_device(struct vt8231_data *data);
173 173
@@ -751,7 +751,7 @@ exit_release:
751 return err; 751 return err;
752} 752}
753 753
754static int vt8231_remove(struct platform_device *pdev) 754static int __devexit vt8231_remove(struct platform_device *pdev)
755{ 755{
756 struct vt8231_data *data = platform_get_drvdata(pdev); 756 struct vt8231_data *data = platform_get_drvdata(pdev);
757 int i; 757 int i;
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 1ce78179b005..7a4a15f4bf8b 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -387,7 +387,7 @@ struct w83627hf_sio_data {
387 387
388 388
389static int w83627hf_probe(struct platform_device *pdev); 389static int w83627hf_probe(struct platform_device *pdev);
390static int w83627hf_remove(struct platform_device *pdev); 390static int __devexit w83627hf_remove(struct platform_device *pdev);
391 391
392static int w83627hf_read_value(struct w83627hf_data *data, u16 reg); 392static int w83627hf_read_value(struct w83627hf_data *data, u16 reg);
393static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value); 393static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value);