diff options
author | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
commit | ed03f430cdc8c802652467e9097606fedc2c7abc (patch) | |
tree | 30941ec1e6f93e99358fefe18175e5dd800a4379 /drivers/hwmon | |
parent | ed349a8a0a780ed27e2a765f16cee54d9b63bfee (diff) | |
parent | 6f957eaf79356a32e838f5f262ee9a60544b1d5b (diff) |
Pull pnpacpi into acpica branch
Diffstat (limited to 'drivers/hwmon')
38 files changed, 1106 insertions, 223 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index db358cfa7cbf..c58295914365 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -350,6 +350,18 @@ config SENSORS_VIA686A | |||
350 | This driver can also be built as a module. If so, the module | 350 | This driver can also be built as a module. If so, the module |
351 | will be called via686a. | 351 | will be called via686a. |
352 | 352 | ||
353 | config SENSORS_VT8231 | ||
354 | tristate "VT8231" | ||
355 | depends on HWMON && I2C && PCI && EXPERIMENTAL | ||
356 | select HWMON_VID | ||
357 | select I2C_ISA | ||
358 | help | ||
359 | If you say yes here then you get support for the integrated sensors | ||
360 | in the VIA VT8231 device. | ||
361 | |||
362 | This driver can also be built as a module. If so, the module | ||
363 | will be called vt8231. | ||
364 | |||
353 | config SENSORS_W83781D | 365 | config SENSORS_W83781D |
354 | tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" | 366 | tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" |
355 | depends on HWMON && I2C | 367 | depends on HWMON && I2C |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index f7d6a2f61ee7..06d4a1d14105 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o | |||
40 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | 40 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o |
41 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | 41 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o |
42 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o | 42 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o |
43 | obj-$(CONFIG_SENSORS_VT8231) += vt8231.o | ||
43 | obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o | 44 | obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o |
44 | obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o | 45 | obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o |
45 | 46 | ||
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 8102876c7c3f..665612729cb9 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
@@ -126,10 +126,10 @@ static int read_only; | |||
126 | 126 | ||
127 | /* This is the driver that will be inserted */ | 127 | /* This is the driver that will be inserted */ |
128 | static struct i2c_driver adm1021_driver = { | 128 | static struct i2c_driver adm1021_driver = { |
129 | .owner = THIS_MODULE, | 129 | .driver = { |
130 | .name = "adm1021", | 130 | .name = "adm1021", |
131 | }, | ||
131 | .id = I2C_DRIVERID_ADM1021, | 132 | .id = I2C_DRIVERID_ADM1021, |
132 | .flags = I2C_DF_NOTIFY, | ||
133 | .attach_adapter = adm1021_attach_adapter, | 133 | .attach_adapter = adm1021_attach_adapter, |
134 | .detach_client = adm1021_detach_client, | 134 | .detach_client = adm1021_detach_client, |
135 | }; | 135 | }; |
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 3ec12421694f..9331c56d2ba6 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c | |||
@@ -118,10 +118,10 @@ static struct adm1025_data *adm1025_update_device(struct device *dev); | |||
118 | */ | 118 | */ |
119 | 119 | ||
120 | static struct i2c_driver adm1025_driver = { | 120 | static struct i2c_driver adm1025_driver = { |
121 | .owner = THIS_MODULE, | 121 | .driver = { |
122 | .name = "adm1025", | 122 | .name = "adm1025", |
123 | }, | ||
123 | .id = I2C_DRIVERID_ADM1025, | 124 | .id = I2C_DRIVERID_ADM1025, |
124 | .flags = I2C_DF_NOTIFY, | ||
125 | .attach_adapter = adm1025_attach_adapter, | 125 | .attach_adapter = adm1025_attach_adapter, |
126 | .detach_client = adm1025_detach_client, | 126 | .detach_client = adm1025_detach_client, |
127 | }; | 127 | }; |
@@ -287,8 +287,6 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char | |||
287 | struct adm1025_data *data = adm1025_update_device(dev); | 287 | struct adm1025_data *data = adm1025_update_device(dev); |
288 | return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); | 288 | return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); |
289 | } | 289 | } |
290 | /* in1_ref is deprecated in favour of cpu0_vid, remove after 2005-11-11 */ | ||
291 | static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL); | ||
292 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | 290 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); |
293 | 291 | ||
294 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 292 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -444,8 +442,6 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) | |||
444 | device_create_file(&new_client->dev, &dev_attr_temp1_max); | 442 | device_create_file(&new_client->dev, &dev_attr_temp1_max); |
445 | device_create_file(&new_client->dev, &dev_attr_temp2_max); | 443 | device_create_file(&new_client->dev, &dev_attr_temp2_max); |
446 | device_create_file(&new_client->dev, &dev_attr_alarms); | 444 | device_create_file(&new_client->dev, &dev_attr_alarms); |
447 | /* in1_ref is deprecated, remove after 2005-11-11 */ | ||
448 | device_create_file(&new_client->dev, &dev_attr_in1_ref); | ||
449 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); | 445 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); |
450 | device_create_file(&new_client->dev, &dev_attr_vrm); | 446 | device_create_file(&new_client->dev, &dev_attr_vrm); |
451 | 447 | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index e0f56549d1d8..fefe6e74fd02 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -308,9 +308,9 @@ static void adm1026_init_client(struct i2c_client *client); | |||
308 | 308 | ||
309 | 309 | ||
310 | static struct i2c_driver adm1026_driver = { | 310 | static struct i2c_driver adm1026_driver = { |
311 | .owner = THIS_MODULE, | 311 | .driver = { |
312 | .name = "adm1026", | 312 | .name = "adm1026", |
313 | .flags = I2C_DF_NOTIFY, | 313 | }, |
314 | .attach_adapter = adm1026_attach_adapter, | 314 | .attach_adapter = adm1026_attach_adapter, |
315 | .detach_client = adm1026_detach_client, | 315 | .detach_client = adm1026_detach_client, |
316 | }; | 316 | }; |
@@ -1227,8 +1227,6 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, c | |||
1227 | struct adm1026_data *data = adm1026_update_device(dev); | 1227 | struct adm1026_data *data = adm1026_update_device(dev); |
1228 | return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); | 1228 | return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); |
1229 | } | 1229 | } |
1230 | /* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */ | ||
1231 | static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL); | ||
1232 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 1230 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
1233 | 1231 | ||
1234 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 1232 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -1673,8 +1671,6 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1673 | device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable); | 1671 | device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable); |
1674 | device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable); | 1672 | device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable); |
1675 | device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable); | 1673 | device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable); |
1676 | /* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */ | ||
1677 | device_create_file(&new_client->dev, &dev_attr_vid); | ||
1678 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); | 1674 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); |
1679 | device_create_file(&new_client->dev, &dev_attr_vrm); | 1675 | device_create_file(&new_client->dev, &dev_attr_vrm); |
1680 | device_create_file(&new_client->dev, &dev_attr_alarms); | 1676 | device_create_file(&new_client->dev, &dev_attr_alarms); |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 7c545d5eee45..d06397966081 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -105,9 +105,9 @@ static struct adm1031_data *adm1031_update_device(struct device *dev); | |||
105 | 105 | ||
106 | /* This is the driver that will be inserted */ | 106 | /* This is the driver that will be inserted */ |
107 | static struct i2c_driver adm1031_driver = { | 107 | static struct i2c_driver adm1031_driver = { |
108 | .owner = THIS_MODULE, | 108 | .driver = { |
109 | .name = "adm1031", | 109 | .name = "adm1031", |
110 | .flags = I2C_DF_NOTIFY, | 110 | }, |
111 | .attach_adapter = adm1031_attach_adapter, | 111 | .attach_adapter = adm1031_attach_adapter, |
112 | .detach_client = adm1031_detach_client, | 112 | .detach_client = adm1031_detach_client, |
113 | }; | 113 | }; |
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 11dc95f8a17e..5ddc22fea4a3 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -137,10 +137,10 @@ static struct adm9240_data *adm9240_update_device(struct device *dev); | |||
137 | 137 | ||
138 | /* driver data */ | 138 | /* driver data */ |
139 | static struct i2c_driver adm9240_driver = { | 139 | static struct i2c_driver adm9240_driver = { |
140 | .owner = THIS_MODULE, | 140 | .driver = { |
141 | .name = "adm9240", | 141 | .name = "adm9240", |
142 | }, | ||
142 | .id = I2C_DRIVERID_ADM9240, | 143 | .id = I2C_DRIVERID_ADM9240, |
143 | .flags = I2C_DF_NOTIFY, | ||
144 | .attach_adapter = adm9240_attach_adapter, | 144 | .attach_adapter = adm9240_attach_adapter, |
145 | .detach_client = adm9240_detach_client, | 145 | .detach_client = adm9240_detach_client, |
146 | }; | 146 | }; |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 52c469722a65..ae9de63cf2e0 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -217,10 +217,10 @@ static struct asb100_data *asb100_update_device(struct device *dev); | |||
217 | static void asb100_init_client(struct i2c_client *client); | 217 | static void asb100_init_client(struct i2c_client *client); |
218 | 218 | ||
219 | static struct i2c_driver asb100_driver = { | 219 | static struct i2c_driver asb100_driver = { |
220 | .owner = THIS_MODULE, | 220 | .driver = { |
221 | .name = "asb100", | 221 | .name = "asb100", |
222 | }, | ||
222 | .id = I2C_DRIVERID_ASB100, | 223 | .id = I2C_DRIVERID_ASB100, |
223 | .flags = I2C_DF_NOTIFY, | ||
224 | .attach_adapter = asb100_attach_adapter, | 224 | .attach_adapter = asb100_attach_adapter, |
225 | .detach_client = asb100_detach_client, | 225 | .detach_client = asb100_detach_client, |
226 | }; | 226 | }; |
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 53324f56404e..b0c490073c8e 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -50,9 +50,9 @@ static struct atxp1_data * atxp1_update_device(struct device *dev); | |||
50 | static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); | 50 | static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); |
51 | 51 | ||
52 | static struct i2c_driver atxp1_driver = { | 52 | static struct i2c_driver atxp1_driver = { |
53 | .owner = THIS_MODULE, | 53 | .driver = { |
54 | .name = "atxp1", | 54 | .name = "atxp1", |
55 | .flags = I2C_DF_NOTIFY, | 55 | }, |
56 | .attach_adapter = atxp1_attach_adapter, | 56 | .attach_adapter = atxp1_attach_adapter, |
57 | .detach_client = atxp1_detach_client, | 57 | .detach_client = atxp1_detach_client, |
58 | }; | 58 | }; |
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 34f71b7c7f37..203f9c7abb20 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
@@ -89,10 +89,10 @@ static struct ds1621_data *ds1621_update_client(struct device *dev); | |||
89 | 89 | ||
90 | /* This is the driver that will be inserted */ | 90 | /* This is the driver that will be inserted */ |
91 | static struct i2c_driver ds1621_driver = { | 91 | static struct i2c_driver ds1621_driver = { |
92 | .owner = THIS_MODULE, | 92 | .driver = { |
93 | .name = "ds1621", | 93 | .name = "ds1621", |
94 | }, | ||
94 | .id = I2C_DRIVERID_DS1621, | 95 | .id = I2C_DRIVERID_DS1621, |
95 | .flags = I2C_DF_NOTIFY, | ||
96 | .attach_adapter = ds1621_attach_adapter, | 96 | .attach_adapter = ds1621_attach_adapter, |
97 | .detach_client = ds1621_detach_client, | 97 | .detach_client = ds1621_detach_client, |
98 | }; | 98 | }; |
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index a02e1c34c757..25409181d1eb 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c | |||
@@ -118,10 +118,10 @@ static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value); | |||
118 | */ | 118 | */ |
119 | 119 | ||
120 | static struct i2c_driver fscher_driver = { | 120 | static struct i2c_driver fscher_driver = { |
121 | .owner = THIS_MODULE, | 121 | .driver = { |
122 | .name = "fscher", | 122 | .name = "fscher", |
123 | }, | ||
123 | .id = I2C_DRIVERID_FSCHER, | 124 | .id = I2C_DRIVERID_FSCHER, |
124 | .flags = I2C_DF_NOTIFY, | ||
125 | .attach_adapter = fscher_attach_adapter, | 125 | .attach_adapter = fscher_attach_adapter, |
126 | .detach_client = fscher_detach_client, | 126 | .detach_client = fscher_detach_client, |
127 | }; | 127 | }; |
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 64e4edc64f8d..6d0146b57020 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c | |||
@@ -100,10 +100,10 @@ static void reset_fan_alarm(struct i2c_client *client, int nr); | |||
100 | * Driver data (common to all clients) | 100 | * Driver data (common to all clients) |
101 | */ | 101 | */ |
102 | static struct i2c_driver fscpos_driver = { | 102 | static struct i2c_driver fscpos_driver = { |
103 | .owner = THIS_MODULE, | 103 | .driver = { |
104 | .name = "fscpos", | 104 | .name = "fscpos", |
105 | }, | ||
105 | .id = I2C_DRIVERID_FSCPOS, | 106 | .id = I2C_DRIVERID_FSCPOS, |
106 | .flags = I2C_DF_NOTIFY, | ||
107 | .attach_adapter = fscpos_attach_adapter, | 107 | .attach_adapter = fscpos_attach_adapter, |
108 | .detach_client = fscpos_detach_client, | 108 | .detach_client = fscpos_detach_client, |
109 | }; | 109 | }; |
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 2f178dbe3d87..9e685e3a3bc9 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -151,10 +151,10 @@ static struct gl518_data *gl518_update_device(struct device *dev); | |||
151 | 151 | ||
152 | /* This is the driver that will be inserted */ | 152 | /* This is the driver that will be inserted */ |
153 | static struct i2c_driver gl518_driver = { | 153 | static struct i2c_driver gl518_driver = { |
154 | .owner = THIS_MODULE, | 154 | .driver = { |
155 | .name = "gl518sm", | 155 | .name = "gl518sm", |
156 | }, | ||
156 | .id = I2C_DRIVERID_GL518, | 157 | .id = I2C_DRIVERID_GL518, |
157 | .flags = I2C_DF_NOTIFY, | ||
158 | .attach_adapter = gl518_attach_adapter, | 158 | .attach_adapter = gl518_attach_adapter, |
159 | .detach_client = gl518_detach_client, | 159 | .detach_client = gl518_detach_client, |
160 | }; | 160 | }; |
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index c39ba1239426..baee60e44b52 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -109,10 +109,10 @@ static struct gl520_data *gl520_update_device(struct device *dev); | |||
109 | 109 | ||
110 | /* Driver data */ | 110 | /* Driver data */ |
111 | static struct i2c_driver gl520_driver = { | 111 | static struct i2c_driver gl520_driver = { |
112 | .owner = THIS_MODULE, | 112 | .driver = { |
113 | .name = "gl520sm", | 113 | .name = "gl520sm", |
114 | }, | ||
114 | .id = I2C_DRIVERID_GL520, | 115 | .id = I2C_DRIVERID_GL520, |
115 | .flags = I2C_DF_NOTIFY, | ||
116 | .attach_adapter = gl520_attach_adapter, | 116 | .attach_adapter = gl520_attach_adapter, |
117 | .detach_client = gl520_detach_client, | 117 | .detach_client = gl520_detach_client, |
118 | }; | 118 | }; |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 312769ad4dab..e497274916ce 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -49,20 +49,22 @@ | |||
49 | . . . . | 49 | . . . . |
50 | 11110 = 0.800 V | 50 | 11110 = 0.800 V |
51 | 11111 = 0.000 V (off) | 51 | 11111 = 0.000 V (off) |
52 | |||
53 | The 17 specification is in fact Intel Mobile Voltage Positioning - | ||
54 | (IMVP-II). You can find more information in the datasheet of Max1718 | ||
55 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 | ||
56 | |||
52 | */ | 57 | */ |
53 | 58 | ||
54 | /* vrm is the VRM/VRD document version multiplied by 10. | 59 | /* vrm is the VRM/VRD document version multiplied by 10. |
55 | val is the 4-, 5- or 6-bit VID code. | 60 | val is the 4-, 5- or 6-bit VID code. |
56 | Returned value is in mV to avoid floating point in the kernel. */ | 61 | Returned value is in mV to avoid floating point in the kernel. */ |
57 | int vid_from_reg(int val, int vrm) | 62 | int vid_from_reg(int val, u8 vrm) |
58 | { | 63 | { |
59 | int vid; | 64 | int vid; |
60 | 65 | ||
61 | switch(vrm) { | 66 | switch(vrm) { |
62 | 67 | ||
63 | case 0: | ||
64 | return 0; | ||
65 | |||
66 | case 100: /* VRD 10.0 */ | 68 | case 100: /* VRD 10.0 */ |
67 | if((val & 0x1f) == 0x1f) | 69 | if((val & 0x1f) == 0x1f) |
68 | return 0; | 70 | return 0; |
@@ -91,10 +93,16 @@ int vid_from_reg(int val, int vrm) | |||
91 | case 84: /* VRM 8.4 */ | 93 | case 84: /* VRM 8.4 */ |
92 | val &= 0x0f; | 94 | val &= 0x0f; |
93 | /* fall through */ | 95 | /* fall through */ |
94 | default: /* VRM 8.2 */ | 96 | case 82: /* VRM 8.2 */ |
95 | return(val == 0x1f ? 0 : | 97 | return(val == 0x1f ? 0 : |
96 | val & 0x10 ? 5100 - (val) * 100 : | 98 | val & 0x10 ? 5100 - (val) * 100 : |
97 | 2050 - (val) * 50); | 99 | 2050 - (val) * 50); |
100 | case 17: /* Intel IMVP-II */ | ||
101 | return(val & 0x10 ? 975 - (val & 0xF) * 25 : | ||
102 | 1750 - val * 50); | ||
103 | default: /* report 0 for unknown */ | ||
104 | printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); | ||
105 | return 0; | ||
98 | } | 106 | } |
99 | } | 107 | } |
100 | 108 | ||
@@ -108,30 +116,36 @@ struct vrm_model { | |||
108 | u8 vendor; | 116 | u8 vendor; |
109 | u8 eff_family; | 117 | u8 eff_family; |
110 | u8 eff_model; | 118 | u8 eff_model; |
111 | int vrm_type; | 119 | u8 eff_stepping; |
120 | u8 vrm_type; | ||
112 | }; | 121 | }; |
113 | 122 | ||
114 | #define ANY 0xFF | 123 | #define ANY 0xFF |
115 | 124 | ||
116 | #ifdef CONFIG_X86 | 125 | #ifdef CONFIG_X86 |
117 | 126 | ||
127 | /* the stepping parameter is highest acceptable stepping for current line */ | ||
128 | |||
118 | static struct vrm_model vrm_models[] = { | 129 | static struct vrm_model vrm_models[] = { |
119 | {X86_VENDOR_AMD, 0x6, ANY, 90}, /* Athlon Duron etc */ | 130 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ |
120 | {X86_VENDOR_AMD, 0xF, ANY, 24}, /* Athlon 64, Opteron */ | 131 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */ |
121 | {X86_VENDOR_INTEL, 0x6, 0x9, 85}, /* 0.13um too */ | 132 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 85}, /* 0.13um too */ |
122 | {X86_VENDOR_INTEL, 0x6, 0xB, 85}, /* Tualatin */ | 133 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ |
123 | {X86_VENDOR_INTEL, 0x6, ANY, 82}, /* any P6 */ | 134 | {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ |
124 | {X86_VENDOR_INTEL, 0x7, ANY, 0}, /* Itanium */ | 135 | {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */ |
125 | {X86_VENDOR_INTEL, 0xF, 0x0, 90}, /* P4 */ | 136 | {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ |
126 | {X86_VENDOR_INTEL, 0xF, 0x1, 90}, /* P4 Willamette */ | 137 | {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ |
127 | {X86_VENDOR_INTEL, 0xF, 0x2, 90}, /* P4 Northwood */ | 138 | {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ |
128 | {X86_VENDOR_INTEL, 0xF, 0x3, 100}, /* P4 Prescott */ | 139 | {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ |
129 | {X86_VENDOR_INTEL, 0xF, 0x4, 100}, /* P4 Prescott */ | 140 | {X86_VENDOR_INTEL, 0x10, ANY, ANY, 0}, /* Itanium 2 */ |
130 | {X86_VENDOR_INTEL, 0x10,ANY, 0}, /* Itanium 2 */ | 141 | {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ |
131 | {X86_VENDOR_UNKNOWN, ANY, ANY, 0} /* stop here */ | 142 | {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ |
143 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */ | ||
144 | {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M */ | ||
145 | {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ | ||
132 | }; | 146 | }; |
133 | 147 | ||
134 | static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) | 148 | static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) |
135 | { | 149 | { |
136 | int i = 0; | 150 | int i = 0; |
137 | 151 | ||
@@ -139,7 +153,8 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) | |||
139 | if (vrm_models[i].vendor==vendor) | 153 | if (vrm_models[i].vendor==vendor) |
140 | if ((vrm_models[i].eff_family==eff_family) | 154 | if ((vrm_models[i].eff_family==eff_family) |
141 | && ((vrm_models[i].eff_model==eff_model) || | 155 | && ((vrm_models[i].eff_model==eff_model) || |
142 | (vrm_models[i].eff_model==ANY))) | 156 | (vrm_models[i].eff_model==ANY)) && |
157 | (eff_stepping <= vrm_models[i].eff_stepping)) | ||
143 | return vrm_models[i].vrm_type; | 158 | return vrm_models[i].vrm_type; |
144 | i++; | 159 | i++; |
145 | } | 160 | } |
@@ -147,12 +162,11 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) | |||
147 | return 0; | 162 | return 0; |
148 | } | 163 | } |
149 | 164 | ||
150 | int vid_which_vrm(void) | 165 | u8 vid_which_vrm(void) |
151 | { | 166 | { |
152 | struct cpuinfo_x86 *c = cpu_data; | 167 | struct cpuinfo_x86 *c = cpu_data; |
153 | u32 eax; | 168 | u32 eax; |
154 | u8 eff_family, eff_model; | 169 | u8 eff_family, eff_model, eff_stepping, vrm_ret; |
155 | int vrm_ret; | ||
156 | 170 | ||
157 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ | 171 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ |
158 | return 0; /* doesn't have VID and/or CPUID */ | 172 | return 0; /* doesn't have VID and/or CPUID */ |
@@ -160,20 +174,21 @@ int vid_which_vrm(void) | |||
160 | eax = cpuid_eax(1); | 174 | eax = cpuid_eax(1); |
161 | eff_family = ((eax & 0x00000F00)>>8); | 175 | eff_family = ((eax & 0x00000F00)>>8); |
162 | eff_model = ((eax & 0x000000F0)>>4); | 176 | eff_model = ((eax & 0x000000F0)>>4); |
177 | eff_stepping = eax & 0xF; | ||
163 | if (eff_family == 0xF) { /* use extended model & family */ | 178 | if (eff_family == 0xF) { /* use extended model & family */ |
164 | eff_family += ((eax & 0x00F00000)>>20); | 179 | eff_family += ((eax & 0x00F00000)>>20); |
165 | eff_model += ((eax & 0x000F0000)>>16)<<4; | 180 | eff_model += ((eax & 0x000F0000)>>16)<<4; |
166 | } | 181 | } |
167 | vrm_ret = find_vrm(eff_family,eff_model,c->x86_vendor); | 182 | vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); |
168 | if (vrm_ret == 0) | 183 | if (vrm_ret == 0) |
169 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your " | 184 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your " |
170 | "x86 CPU\n"); | 185 | "x86 CPU\n"); |
171 | return vrm_ret; | 186 | return vrm_ret; |
172 | } | 187 | } |
173 | 188 | ||
174 | /* and now something completely different for the non-x86 world */ | 189 | /* and now for something completely different for the non-x86 world */ |
175 | #else | 190 | #else |
176 | int vid_which_vrm(void) | 191 | u8 vid_which_vrm(void) |
177 | { | 192 | { |
178 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n"); | 193 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n"); |
179 | return 0; | 194 | return 0; |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index a61f5d00f10a..0da7c9c508c3 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -213,7 +213,7 @@ struct it87_data { | |||
213 | u8 sensor; /* Register value */ | 213 | u8 sensor; /* Register value */ |
214 | u8 fan_div[3]; /* Register encoding, shifted right */ | 214 | u8 fan_div[3]; /* Register encoding, shifted right */ |
215 | u8 vid; /* Register encoding, combined */ | 215 | u8 vid; /* Register encoding, combined */ |
216 | int vrm; | 216 | u8 vrm; |
217 | u32 alarms; /* Register encoding, combined */ | 217 | u32 alarms; /* Register encoding, combined */ |
218 | u8 fan_main_ctrl; /* Register value */ | 218 | u8 fan_main_ctrl; /* Register value */ |
219 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ | 219 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ |
@@ -234,17 +234,18 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data); | |||
234 | 234 | ||
235 | 235 | ||
236 | static struct i2c_driver it87_driver = { | 236 | static struct i2c_driver it87_driver = { |
237 | .owner = THIS_MODULE, | 237 | .driver = { |
238 | .name = "it87", | 238 | .name = "it87", |
239 | }, | ||
239 | .id = I2C_DRIVERID_IT87, | 240 | .id = I2C_DRIVERID_IT87, |
240 | .flags = I2C_DF_NOTIFY, | ||
241 | .attach_adapter = it87_attach_adapter, | 241 | .attach_adapter = it87_attach_adapter, |
242 | .detach_client = it87_detach_client, | 242 | .detach_client = it87_detach_client, |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct i2c_driver it87_isa_driver = { | 245 | static struct i2c_driver it87_isa_driver = { |
246 | .owner = THIS_MODULE, | 246 | .driver = { |
247 | .name = "it87-isa", | 247 | .name = "it87-isa", |
248 | }, | ||
248 | .attach_adapter = it87_isa_attach_adapter, | 249 | .attach_adapter = it87_isa_attach_adapter, |
249 | .detach_client = it87_detach_client, | 250 | .detach_client = it87_detach_client, |
250 | }; | 251 | }; |
@@ -668,7 +669,7 @@ static ssize_t | |||
668 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 669 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
669 | { | 670 | { |
670 | struct it87_data *data = it87_update_device(dev); | 671 | struct it87_data *data = it87_update_device(dev); |
671 | return sprintf(buf, "%ld\n", (long) data->vrm); | 672 | return sprintf(buf, "%u\n", data->vrm); |
672 | } | 673 | } |
673 | static ssize_t | 674 | static ssize_t |
674 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 675 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -761,7 +762,8 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
761 | 762 | ||
762 | /* Reserve the ISA region */ | 763 | /* Reserve the ISA region */ |
763 | if (is_isa) | 764 | if (is_isa) |
764 | if (!request_region(address, IT87_EXTENT, it87_isa_driver.name)) | 765 | if (!request_region(address, IT87_EXTENT, |
766 | it87_isa_driver.driver.name)) | ||
765 | goto ERROR0; | 767 | goto ERROR0; |
766 | 768 | ||
767 | /* For now, we presume we have a valid client. We create the | 769 | /* For now, we presume we have a valid client. We create the |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 954ec2497249..6b1aa7ef552e 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -139,9 +139,9 @@ static void lm63_init_client(struct i2c_client *client); | |||
139 | */ | 139 | */ |
140 | 140 | ||
141 | static struct i2c_driver lm63_driver = { | 141 | static struct i2c_driver lm63_driver = { |
142 | .owner = THIS_MODULE, | 142 | .driver = { |
143 | .name = "lm63", | 143 | .name = "lm63", |
144 | .flags = I2C_DF_NOTIFY, | 144 | }, |
145 | .attach_adapter = lm63_attach_adapter, | 145 | .attach_adapter = lm63_attach_adapter, |
146 | .detach_client = lm63_detach_client, | 146 | .detach_client = lm63_detach_client, |
147 | }; | 147 | }; |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d70f4c8fc1e6..74ca2c8c61c3 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -66,10 +66,10 @@ static struct lm75_data *lm75_update_device(struct device *dev); | |||
66 | 66 | ||
67 | /* This is the driver that will be inserted */ | 67 | /* This is the driver that will be inserted */ |
68 | static struct i2c_driver lm75_driver = { | 68 | static struct i2c_driver lm75_driver = { |
69 | .owner = THIS_MODULE, | 69 | .driver = { |
70 | .name = "lm75", | 70 | .name = "lm75", |
71 | }, | ||
71 | .id = I2C_DRIVERID_LM75, | 72 | .id = I2C_DRIVERID_LM75, |
72 | .flags = I2C_DF_NOTIFY, | ||
73 | .attach_adapter = lm75_attach_adapter, | 73 | .attach_adapter = lm75_attach_adapter, |
74 | .detach_client = lm75_detach_client, | 74 | .detach_client = lm75_detach_client, |
75 | }; | 75 | }; |
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 9380fda7dcd1..a2f420d01fb7 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -74,9 +74,9 @@ static struct lm77_data *lm77_update_device(struct device *dev); | |||
74 | 74 | ||
75 | /* This is the driver that will be inserted */ | 75 | /* This is the driver that will be inserted */ |
76 | static struct i2c_driver lm77_driver = { | 76 | static struct i2c_driver lm77_driver = { |
77 | .owner = THIS_MODULE, | 77 | .driver = { |
78 | .name = "lm77", | 78 | .name = "lm77", |
79 | .flags = I2C_DF_NOTIFY, | 79 | }, |
80 | .attach_adapter = lm77_attach_adapter, | 80 | .attach_adapter = lm77_attach_adapter, |
81 | .detach_client = lm77_detach_client, | 81 | .detach_client = lm77_detach_client, |
82 | }; | 82 | }; |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 78cdd506439f..e404001e20da 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -164,17 +164,18 @@ static void lm78_init_client(struct i2c_client *client); | |||
164 | 164 | ||
165 | 165 | ||
166 | static struct i2c_driver lm78_driver = { | 166 | static struct i2c_driver lm78_driver = { |
167 | .owner = THIS_MODULE, | 167 | .driver = { |
168 | .name = "lm78", | 168 | .name = "lm78", |
169 | }, | ||
169 | .id = I2C_DRIVERID_LM78, | 170 | .id = I2C_DRIVERID_LM78, |
170 | .flags = I2C_DF_NOTIFY, | ||
171 | .attach_adapter = lm78_attach_adapter, | 171 | .attach_adapter = lm78_attach_adapter, |
172 | .detach_client = lm78_detach_client, | 172 | .detach_client = lm78_detach_client, |
173 | }; | 173 | }; |
174 | 174 | ||
175 | static struct i2c_driver lm78_isa_driver = { | 175 | static struct i2c_driver lm78_isa_driver = { |
176 | .owner = THIS_MODULE, | 176 | .driver = { |
177 | .name = "lm78-isa", | 177 | .name = "lm78-isa", |
178 | }, | ||
178 | .attach_adapter = lm78_isa_attach_adapter, | 179 | .attach_adapter = lm78_isa_attach_adapter, |
179 | .detach_client = lm78_detach_client, | 180 | .detach_client = lm78_detach_client, |
180 | }; | 181 | }; |
@@ -497,7 +498,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
497 | /* Reserve the ISA region */ | 498 | /* Reserve the ISA region */ |
498 | if (is_isa) | 499 | if (is_isa) |
499 | if (!request_region(address, LM78_EXTENT, | 500 | if (!request_region(address, LM78_EXTENT, |
500 | lm78_isa_driver.name)) { | 501 | lm78_isa_driver.driver.name)) { |
501 | err = -EBUSY; | 502 | err = -EBUSY; |
502 | goto ERROR0; | 503 | goto ERROR0; |
503 | } | 504 | } |
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index c359fdea211e..c9a7cdea7bd7 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c | |||
@@ -143,10 +143,10 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); | |||
143 | */ | 143 | */ |
144 | 144 | ||
145 | static struct i2c_driver lm80_driver = { | 145 | static struct i2c_driver lm80_driver = { |
146 | .owner = THIS_MODULE, | 146 | .driver = { |
147 | .name = "lm80", | 147 | .name = "lm80", |
148 | }, | ||
148 | .id = I2C_DRIVERID_LM80, | 149 | .id = I2C_DRIVERID_LM80, |
149 | .flags = I2C_DF_NOTIFY, | ||
150 | .attach_adapter = lm80_attach_adapter, | 150 | .attach_adapter = lm80_attach_adapter, |
151 | .detach_client = lm80_detach_client, | 151 | .detach_client = lm80_detach_client, |
152 | }; | 152 | }; |
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 9a70611a9f69..26dfa9e216c2 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
@@ -124,10 +124,10 @@ static struct lm83_data *lm83_update_device(struct device *dev); | |||
124 | */ | 124 | */ |
125 | 125 | ||
126 | static struct i2c_driver lm83_driver = { | 126 | static struct i2c_driver lm83_driver = { |
127 | .owner = THIS_MODULE, | 127 | .driver = { |
128 | .name = "lm83", | 128 | .name = "lm83", |
129 | }, | ||
129 | .id = I2C_DRIVERID_LM83, | 130 | .id = I2C_DRIVERID_LM83, |
130 | .flags = I2C_DF_NOTIFY, | ||
131 | .attach_adapter = lm83_attach_adapter, | 131 | .attach_adapter = lm83_attach_adapter, |
132 | .detach_client = lm83_detach_client, | 132 | .detach_client = lm83_detach_client, |
133 | }; | 133 | }; |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index d1070ed2bee6..7389a0127547 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -380,10 +380,10 @@ static void lm85_init_client(struct i2c_client *client); | |||
380 | 380 | ||
381 | 381 | ||
382 | static struct i2c_driver lm85_driver = { | 382 | static struct i2c_driver lm85_driver = { |
383 | .owner = THIS_MODULE, | 383 | .driver = { |
384 | .name = "lm85", | 384 | .name = "lm85", |
385 | }, | ||
385 | .id = I2C_DRIVERID_LM85, | 386 | .id = I2C_DRIVERID_LM85, |
386 | .flags = I2C_DF_NOTIFY, | ||
387 | .attach_adapter = lm85_attach_adapter, | 387 | .attach_adapter = lm85_attach_adapter, |
388 | .detach_client = lm85_detach_client, | 388 | .detach_client = lm85_detach_client, |
389 | }; | 389 | }; |
@@ -443,7 +443,17 @@ show_fan_offset(4); | |||
443 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | 443 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) |
444 | { | 444 | { |
445 | struct lm85_data *data = lm85_update_device(dev); | 445 | struct lm85_data *data = lm85_update_device(dev); |
446 | return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); | 446 | int vid; |
447 | |||
448 | if (data->type == adt7463 && (data->vid & 0x80)) { | ||
449 | /* 6-pin VID (VRM 10) */ | ||
450 | vid = vid_from_reg(data->vid & 0x3f, data->vrm); | ||
451 | } else { | ||
452 | /* 5-pin VID (VRM 9) */ | ||
453 | vid = vid_from_reg(data->vid & 0x1f, data->vrm); | ||
454 | } | ||
455 | |||
456 | return sprintf(buf, "%d\n", vid); | ||
447 | } | 457 | } |
448 | 458 | ||
449 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 459 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
@@ -1176,17 +1186,14 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1176 | device_create_file(&new_client->dev, &dev_attr_in1_input); | 1186 | device_create_file(&new_client->dev, &dev_attr_in1_input); |
1177 | device_create_file(&new_client->dev, &dev_attr_in2_input); | 1187 | device_create_file(&new_client->dev, &dev_attr_in2_input); |
1178 | device_create_file(&new_client->dev, &dev_attr_in3_input); | 1188 | device_create_file(&new_client->dev, &dev_attr_in3_input); |
1179 | device_create_file(&new_client->dev, &dev_attr_in4_input); | ||
1180 | device_create_file(&new_client->dev, &dev_attr_in0_min); | 1189 | device_create_file(&new_client->dev, &dev_attr_in0_min); |
1181 | device_create_file(&new_client->dev, &dev_attr_in1_min); | 1190 | device_create_file(&new_client->dev, &dev_attr_in1_min); |
1182 | device_create_file(&new_client->dev, &dev_attr_in2_min); | 1191 | device_create_file(&new_client->dev, &dev_attr_in2_min); |
1183 | device_create_file(&new_client->dev, &dev_attr_in3_min); | 1192 | device_create_file(&new_client->dev, &dev_attr_in3_min); |
1184 | device_create_file(&new_client->dev, &dev_attr_in4_min); | ||
1185 | device_create_file(&new_client->dev, &dev_attr_in0_max); | 1193 | device_create_file(&new_client->dev, &dev_attr_in0_max); |
1186 | device_create_file(&new_client->dev, &dev_attr_in1_max); | 1194 | device_create_file(&new_client->dev, &dev_attr_in1_max); |
1187 | device_create_file(&new_client->dev, &dev_attr_in2_max); | 1195 | device_create_file(&new_client->dev, &dev_attr_in2_max); |
1188 | device_create_file(&new_client->dev, &dev_attr_in3_max); | 1196 | device_create_file(&new_client->dev, &dev_attr_in3_max); |
1189 | device_create_file(&new_client->dev, &dev_attr_in4_max); | ||
1190 | device_create_file(&new_client->dev, &dev_attr_temp1_input); | 1197 | device_create_file(&new_client->dev, &dev_attr_temp1_input); |
1191 | device_create_file(&new_client->dev, &dev_attr_temp2_input); | 1198 | device_create_file(&new_client->dev, &dev_attr_temp2_input); |
1192 | device_create_file(&new_client->dev, &dev_attr_temp3_input); | 1199 | device_create_file(&new_client->dev, &dev_attr_temp3_input); |
@@ -1224,6 +1231,15 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1224 | device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit); | 1231 | device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit); |
1225 | device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit); | 1232 | device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit); |
1226 | 1233 | ||
1234 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used | ||
1235 | as a sixth digital VID input rather than an analog input. */ | ||
1236 | data->vid = lm85_read_value(new_client, LM85_REG_VID); | ||
1237 | if (!(kind == adt7463 && (data->vid & 0x80))) { | ||
1238 | device_create_file(&new_client->dev, &dev_attr_in4_input); | ||
1239 | device_create_file(&new_client->dev, &dev_attr_in4_min); | ||
1240 | device_create_file(&new_client->dev, &dev_attr_in4_max); | ||
1241 | } | ||
1242 | |||
1227 | return 0; | 1243 | return 0; |
1228 | 1244 | ||
1229 | /* Error out and cleanup code */ | 1245 | /* Error out and cleanup code */ |
@@ -1382,11 +1398,18 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1382 | irrelevant. So it is left in 4*/ | 1398 | irrelevant. So it is left in 4*/ |
1383 | data->adc_scale = (data->type == emc6d102 ) ? 16 : 4; | 1399 | data->adc_scale = (data->type == emc6d102 ) ? 16 : 4; |
1384 | 1400 | ||
1385 | for (i = 0; i <= 4; ++i) { | 1401 | data->vid = lm85_read_value(client, LM85_REG_VID); |
1402 | |||
1403 | for (i = 0; i <= 3; ++i) { | ||
1386 | data->in[i] = | 1404 | data->in[i] = |
1387 | lm85_read_value(client, LM85_REG_IN(i)); | 1405 | lm85_read_value(client, LM85_REG_IN(i)); |
1388 | } | 1406 | } |
1389 | 1407 | ||
1408 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | ||
1409 | data->in[4] = lm85_read_value(client, | ||
1410 | LM85_REG_IN(4)); | ||
1411 | } | ||
1412 | |||
1390 | for (i = 0; i <= 3; ++i) { | 1413 | for (i = 0; i <= 3; ++i) { |
1391 | data->fan[i] = | 1414 | data->fan[i] = |
1392 | lm85_read_value(client, LM85_REG_FAN(i)); | 1415 | lm85_read_value(client, LM85_REG_FAN(i)); |
@@ -1450,13 +1473,20 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1450 | /* Things that don't change often */ | 1473 | /* Things that don't change often */ |
1451 | dev_dbg(&client->dev, "Reading config values\n"); | 1474 | dev_dbg(&client->dev, "Reading config values\n"); |
1452 | 1475 | ||
1453 | for (i = 0; i <= 4; ++i) { | 1476 | for (i = 0; i <= 3; ++i) { |
1454 | data->in_min[i] = | 1477 | data->in_min[i] = |
1455 | lm85_read_value(client, LM85_REG_IN_MIN(i)); | 1478 | lm85_read_value(client, LM85_REG_IN_MIN(i)); |
1456 | data->in_max[i] = | 1479 | data->in_max[i] = |
1457 | lm85_read_value(client, LM85_REG_IN_MAX(i)); | 1480 | lm85_read_value(client, LM85_REG_IN_MAX(i)); |
1458 | } | 1481 | } |
1459 | 1482 | ||
1483 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | ||
1484 | data->in_min[4] = lm85_read_value(client, | ||
1485 | LM85_REG_IN_MIN(4)); | ||
1486 | data->in_max[4] = lm85_read_value(client, | ||
1487 | LM85_REG_IN_MAX(4)); | ||
1488 | } | ||
1489 | |||
1460 | if ( data->type == emc6d100 ) { | 1490 | if ( data->type == emc6d100 ) { |
1461 | for (i = 5; i <= 7; ++i) { | 1491 | for (i = 5; i <= 7; ++i) { |
1462 | data->in_min[i] = | 1492 | data->in_min[i] = |
@@ -1478,8 +1508,6 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1478 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); | 1508 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); |
1479 | } | 1509 | } |
1480 | 1510 | ||
1481 | data->vid = lm85_read_value(client, LM85_REG_VID); | ||
1482 | |||
1483 | for (i = 0; i <= 2; ++i) { | 1511 | for (i = 0; i <= 2; ++i) { |
1484 | int val ; | 1512 | int val ; |
1485 | data->autofan[i].config = | 1513 | data->autofan[i].config = |
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index eeec18177861..6ba34c302d8d 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c | |||
@@ -161,10 +161,10 @@ static struct lm87_data *lm87_update_device(struct device *dev); | |||
161 | */ | 161 | */ |
162 | 162 | ||
163 | static struct i2c_driver lm87_driver = { | 163 | static struct i2c_driver lm87_driver = { |
164 | .owner = THIS_MODULE, | 164 | .driver = { |
165 | .name = "lm87", | 165 | .name = "lm87", |
166 | }, | ||
166 | .id = I2C_DRIVERID_LM87, | 167 | .id = I2C_DRIVERID_LM87, |
167 | .flags = I2C_DF_NOTIFY, | ||
168 | .attach_adapter = lm87_attach_adapter, | 168 | .attach_adapter = lm87_attach_adapter, |
169 | .detach_client = lm87_detach_client, | 169 | .detach_client = lm87_detach_client, |
170 | }; | 170 | }; |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 83cf2e1b09f5..5679464447cc 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -186,10 +186,10 @@ static struct lm90_data *lm90_update_device(struct device *dev); | |||
186 | */ | 186 | */ |
187 | 187 | ||
188 | static struct i2c_driver lm90_driver = { | 188 | static struct i2c_driver lm90_driver = { |
189 | .owner = THIS_MODULE, | 189 | .driver = { |
190 | .name = "lm90", | 190 | .name = "lm90", |
191 | }, | ||
191 | .id = I2C_DRIVERID_LM90, | 192 | .id = I2C_DRIVERID_LM90, |
192 | .flags = I2C_DF_NOTIFY, | ||
193 | .attach_adapter = lm90_attach_adapter, | 193 | .attach_adapter = lm90_attach_adapter, |
194 | .detach_client = lm90_detach_client, | 194 | .detach_client = lm90_detach_client, |
195 | }; | 195 | }; |
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 7a4b3701ed1a..b0c4cb730a7e 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
@@ -410,10 +410,10 @@ static int lm92_detach_client(struct i2c_client *client) | |||
410 | */ | 410 | */ |
411 | 411 | ||
412 | static struct i2c_driver lm92_driver = { | 412 | static struct i2c_driver lm92_driver = { |
413 | .owner = THIS_MODULE, | 413 | .driver = { |
414 | .name = "lm92", | 414 | .name = "lm92", |
415 | }, | ||
415 | .id = I2C_DRIVERID_LM92, | 416 | .id = I2C_DRIVERID_LM92, |
416 | .flags = I2C_DF_NOTIFY, | ||
417 | .attach_adapter = lm92_attach_adapter, | 417 | .attach_adapter = lm92_attach_adapter, |
418 | .detach_client = lm92_detach_client, | 418 | .detach_client = lm92_detach_client, |
419 | }; | 419 | }; |
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 69e7e125683b..3abe330b22ce 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -90,9 +90,9 @@ static struct max1619_data *max1619_update_device(struct device *dev); | |||
90 | */ | 90 | */ |
91 | 91 | ||
92 | static struct i2c_driver max1619_driver = { | 92 | static struct i2c_driver max1619_driver = { |
93 | .owner = THIS_MODULE, | 93 | .driver = { |
94 | .name = "max1619", | 94 | .name = "max1619", |
95 | .flags = I2C_DF_NOTIFY, | 95 | }, |
96 | .attach_adapter = max1619_attach_adapter, | 96 | .attach_adapter = max1619_attach_adapter, |
97 | .detach_client = max1619_detach_client, | 97 | .detach_client = max1619_detach_client, |
98 | }; | 98 | }; |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 17f745a23d04..f161e88e3bb6 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -236,8 +236,9 @@ static struct pc87360_data *pc87360_update_device(struct device *dev); | |||
236 | */ | 236 | */ |
237 | 237 | ||
238 | static struct i2c_driver pc87360_driver = { | 238 | static struct i2c_driver pc87360_driver = { |
239 | .owner = THIS_MODULE, | 239 | .driver = { |
240 | .name = "pc87360", | 240 | .name = "pc87360", |
241 | }, | ||
241 | .attach_adapter = pc87360_detect, | 242 | .attach_adapter = pc87360_detect, |
242 | .detach_client = pc87360_detach_client, | 243 | .detach_client = pc87360_detach_client, |
243 | }; | 244 | }; |
@@ -798,7 +799,7 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
798 | for (i = 0; i < 3; i++) { | 799 | for (i = 0; i < 3; i++) { |
799 | if (((data->address[i] = extra_isa[i])) | 800 | if (((data->address[i] = extra_isa[i])) |
800 | && !request_region(extra_isa[i], PC87360_EXTENT, | 801 | && !request_region(extra_isa[i], PC87360_EXTENT, |
801 | pc87360_driver.name)) { | 802 | pc87360_driver.driver.name)) { |
802 | dev_err(&new_client->dev, "Region 0x%x-0x%x already " | 803 | dev_err(&new_client->dev, "Region 0x%x-0x%x already " |
803 | "in use!\n", extra_isa[i], | 804 | "in use!\n", extra_isa[i], |
804 | extra_isa[i]+PC87360_EXTENT-1); | 805 | extra_isa[i]+PC87360_EXTENT-1); |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 9c6cadec1087..8be5189d9bd9 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -198,8 +198,9 @@ static struct sis5595_data *sis5595_update_device(struct device *dev); | |||
198 | static void sis5595_init_client(struct i2c_client *client); | 198 | static void sis5595_init_client(struct i2c_client *client); |
199 | 199 | ||
200 | static struct i2c_driver sis5595_driver = { | 200 | static struct i2c_driver sis5595_driver = { |
201 | .owner = THIS_MODULE, | 201 | .driver = { |
202 | .name = "sis5595", | 202 | .name = "sis5595", |
203 | }, | ||
203 | .attach_adapter = sis5595_detect, | 204 | .attach_adapter = sis5595_detect, |
204 | .detach_client = sis5595_detach_client, | 205 | .detach_client = sis5595_detach_client, |
205 | }; | 206 | }; |
@@ -484,7 +485,8 @@ static int sis5595_detect(struct i2c_adapter *adapter) | |||
484 | if (force_addr) | 485 | if (force_addr) |
485 | address = force_addr & ~(SIS5595_EXTENT - 1); | 486 | address = force_addr & ~(SIS5595_EXTENT - 1); |
486 | /* Reserve the ISA region */ | 487 | /* Reserve the ISA region */ |
487 | if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) { | 488 | if (!request_region(address, SIS5595_EXTENT, |
489 | sis5595_driver.driver.name)) { | ||
488 | err = -EBUSY; | 490 | err = -EBUSY; |
489 | goto exit; | 491 | goto exit; |
490 | } | 492 | } |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 2a3e21b5b6b4..8663bbbe97f5 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -226,8 +226,9 @@ static int smsc47b397_detach_client(struct i2c_client *client) | |||
226 | static int smsc47b397_detect(struct i2c_adapter *adapter); | 226 | static int smsc47b397_detect(struct i2c_adapter *adapter); |
227 | 227 | ||
228 | static struct i2c_driver smsc47b397_driver = { | 228 | static struct i2c_driver smsc47b397_driver = { |
229 | .owner = THIS_MODULE, | 229 | .driver = { |
230 | .name = "smsc47b397", | 230 | .name = "smsc47b397", |
231 | }, | ||
231 | .attach_adapter = smsc47b397_detect, | 232 | .attach_adapter = smsc47b397_detect, |
232 | .detach_client = smsc47b397_detach_client, | 233 | .detach_client = smsc47b397_detach_client, |
233 | }; | 234 | }; |
@@ -238,7 +239,8 @@ static int smsc47b397_detect(struct i2c_adapter *adapter) | |||
238 | struct smsc47b397_data *data; | 239 | struct smsc47b397_data *data; |
239 | int err = 0; | 240 | int err = 0; |
240 | 241 | ||
241 | if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) { | 242 | if (!request_region(address, SMSC_EXTENT, |
243 | smsc47b397_driver.driver.name)) { | ||
242 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", | 244 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", |
243 | address); | 245 | address); |
244 | return -EBUSY; | 246 | return -EBUSY; |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 5905c1af88f2..d1e3ec0fe4df 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -126,8 +126,9 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, | |||
126 | 126 | ||
127 | 127 | ||
128 | static struct i2c_driver smsc47m1_driver = { | 128 | static struct i2c_driver smsc47m1_driver = { |
129 | .owner = THIS_MODULE, | 129 | .driver = { |
130 | .name = "smsc47m1", | 130 | .name = "smsc47m1", |
131 | }, | ||
131 | .attach_adapter = smsc47m1_detect, | 132 | .attach_adapter = smsc47m1_detect, |
132 | .detach_client = smsc47m1_detach_client, | 133 | .detach_client = smsc47m1_detach_client, |
133 | }; | 134 | }; |
@@ -394,7 +395,7 @@ static int smsc47m1_detect(struct i2c_adapter *adapter) | |||
394 | int err = 0; | 395 | int err = 0; |
395 | int fan1, fan2, pwm1, pwm2; | 396 | int fan1, fan2, pwm1, pwm2; |
396 | 397 | ||
397 | if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { | 398 | if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) { |
398 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); | 399 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); |
399 | return -EBUSY; | 400 | return -EBUSY; |
400 | } | 401 | } |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 6f696f897176..cb01848729b5 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -572,8 +572,9 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | |||
572 | /* The driver. I choose to use type i2c_driver, as at is identical to both | 572 | /* The driver. I choose to use type i2c_driver, as at is identical to both |
573 | smbus_driver and isa_driver, and clients could be of either kind */ | 573 | smbus_driver and isa_driver, and clients could be of either kind */ |
574 | static struct i2c_driver via686a_driver = { | 574 | static struct i2c_driver via686a_driver = { |
575 | .owner = THIS_MODULE, | 575 | .driver = { |
576 | .name = "via686a", | 576 | .name = "via686a", |
577 | }, | ||
577 | .attach_adapter = via686a_detect, | 578 | .attach_adapter = via686a_detect, |
578 | .detach_client = via686a_detach_client, | 579 | .detach_client = via686a_detach_client, |
579 | }; | 580 | }; |
@@ -615,7 +616,8 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
615 | } | 616 | } |
616 | 617 | ||
617 | /* Reserve the ISA region */ | 618 | /* Reserve the ISA region */ |
618 | if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) { | 619 | if (!request_region(address, VIA686A_EXTENT, |
620 | via686a_driver.driver.name)) { | ||
619 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 621 | dev_err(&adapter->dev, "region 0x%x already in use!\n", |
620 | address); | 622 | address); |
621 | return -ENODEV; | 623 | return -ENODEV; |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c new file mode 100644 index 000000000000..d00a726d0239 --- /dev/null +++ b/drivers/hwmon/vt8231.c | |||
@@ -0,0 +1,862 @@ | |||
1 | /* | ||
2 | vt8231.c - Part of lm_sensors, Linux kernel modules | ||
3 | for hardware monitoring | ||
4 | |||
5 | Copyright (c) 2005 Roger Lucas <roger@planbit.co.uk> | ||
6 | Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | ||
7 | Aaron M. Marsh <amarsh@sdf.lonestar.org> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | /* Supports VIA VT8231 South Bridge embedded sensors | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/pci.h> | ||
31 | #include <linux/jiffies.h> | ||
32 | #include <linux/i2c.h> | ||
33 | #include <linux/i2c-isa.h> | ||
34 | #include <linux/hwmon.h> | ||
35 | #include <linux/hwmon-sysfs.h> | ||
36 | #include <linux/hwmon-vid.h> | ||
37 | #include <linux/err.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | static int force_addr; | ||
41 | module_param(force_addr, int, 0); | ||
42 | MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); | ||
43 | |||
44 | /* Device address | ||
45 | Note that we can't determine the ISA address until we have initialized | ||
46 | our module */ | ||
47 | static unsigned short isa_address; | ||
48 | |||
49 | #define VT8231_EXTENT 0x80 | ||
50 | #define VT8231_BASE_REG 0x70 | ||
51 | #define VT8231_ENABLE_REG 0x74 | ||
52 | |||
53 | /* The VT8231 registers | ||
54 | |||
55 | The reset value for the input channel configuration is used (Reg 0x4A=0x07) | ||
56 | which sets the selected inputs marked with '*' below if multiple options are | ||
57 | possible: | ||
58 | |||
59 | Voltage Mode Temperature Mode | ||
60 | Sensor Linux Id Linux Id VIA Id | ||
61 | -------- -------- -------- ------ | ||
62 | CPU Diode N/A temp1 0 | ||
63 | UIC1 in0 temp2 * 1 | ||
64 | UIC2 in1 * temp3 2 | ||
65 | UIC3 in2 * temp4 3 | ||
66 | UIC4 in3 * temp5 4 | ||
67 | UIC5 in4 * temp6 5 | ||
68 | 3.3V in5 N/A | ||
69 | |||
70 | Note that the BIOS may set the configuration register to a different value | ||
71 | to match the motherboard configuration. | ||
72 | */ | ||
73 | |||
74 | /* fans numbered 0-1 */ | ||
75 | #define VT8231_REG_FAN_MIN(nr) (0x3b + (nr)) | ||
76 | #define VT8231_REG_FAN(nr) (0x29 + (nr)) | ||
77 | |||
78 | /* Voltage inputs numbered 0-5 */ | ||
79 | |||
80 | static const u8 regvolt[] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 }; | ||
81 | static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 }; | ||
82 | static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 }; | ||
83 | |||
84 | /* Temperatures are numbered 1-6 according to the Linux kernel specification. | ||
85 | ** | ||
86 | ** In the VIA datasheet, however, the temperatures are numbered from zero. | ||
87 | ** Since it is important that this driver can easily be compared to the VIA | ||
88 | ** datasheet, we will use the VIA numbering within this driver and map the | ||
89 | ** kernel sysfs device name to the VIA number in the sysfs callback. | ||
90 | */ | ||
91 | |||
92 | #define VT8231_REG_TEMP_LOW01 0x49 | ||
93 | #define VT8231_REG_TEMP_LOW25 0x4d | ||
94 | |||
95 | static const u8 regtemp[] = { 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25 }; | ||
96 | static const u8 regtempmax[] = { 0x39, 0x3d, 0x2b, 0x2d, 0x2f, 0x31 }; | ||
97 | static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 }; | ||
98 | |||
99 | #define TEMP_FROM_REG(reg) (((253 * 4 - (reg)) * 550 + 105) / 210) | ||
100 | #define TEMP_MAXMIN_FROM_REG(reg) (((253 - (reg)) * 2200 + 105) / 210) | ||
101 | #define TEMP_MAXMIN_TO_REG(val) (253 - ((val) * 210 + 1100) / 2200) | ||
102 | |||
103 | #define VT8231_REG_CONFIG 0x40 | ||
104 | #define VT8231_REG_ALARM1 0x41 | ||
105 | #define VT8231_REG_ALARM2 0x42 | ||
106 | #define VT8231_REG_FANDIV 0x47 | ||
107 | #define VT8231_REG_UCH_CONFIG 0x4a | ||
108 | #define VT8231_REG_TEMP1_CONFIG 0x4b | ||
109 | #define VT8231_REG_TEMP2_CONFIG 0x4c | ||
110 | |||
111 | /* temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux | ||
112 | ** numbering | ||
113 | */ | ||
114 | #define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \ | ||
115 | ((ch_config) >> ((i)+1)) & 0x01) | ||
116 | /* voltages 0-5 */ | ||
117 | #define ISVOLT(i, ch_config) ((i) == 5 ? 1 : \ | ||
118 | !(((ch_config) >> ((i)+2)) & 0x01)) | ||
119 | |||
120 | #define DIV_FROM_REG(val) (1 << (val)) | ||
121 | |||
122 | /* NB The values returned here are NOT temperatures. The calibration curves | ||
123 | ** for the thermistor curves are board-specific and must go in the | ||
124 | ** sensors.conf file. Temperature sensors are actually ten bits, but the | ||
125 | ** VIA datasheet only considers the 8 MSBs obtained from the regtemp[] | ||
126 | ** register. The temperature value returned should have a magnitude of 3, | ||
127 | ** so we use the VIA scaling as the "true" scaling and use the remaining 2 | ||
128 | ** LSBs as fractional precision. | ||
129 | ** | ||
130 | ** All the on-chip hardware temperature comparisons for the alarms are only | ||
131 | ** 8-bits wide, and compare against the 8 MSBs of the temperature. The bits | ||
132 | ** in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are | ||
133 | ** ignored. | ||
134 | */ | ||
135 | |||
136 | /******** FAN RPM CONVERSIONS ******** | ||
137 | ** This chip saturates back at 0, not at 255 like many the other chips. | ||
138 | ** So, 0 means 0 RPM | ||
139 | */ | ||
140 | static inline u8 FAN_TO_REG(long rpm, int div) | ||
141 | { | ||
142 | if (rpm == 0) | ||
143 | return 0; | ||
144 | return SENSORS_LIMIT(1310720 / (rpm * div), 1, 255); | ||
145 | } | ||
146 | |||
147 | #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div))) | ||
148 | |||
149 | struct vt8231_data { | ||
150 | struct i2c_client client; | ||
151 | struct semaphore update_lock; | ||
152 | struct class_device *class_dev; | ||
153 | char valid; /* !=0 if following fields are valid */ | ||
154 | unsigned long last_updated; /* In jiffies */ | ||
155 | |||
156 | u8 in[6]; /* Register value */ | ||
157 | u8 in_max[6]; /* Register value */ | ||
158 | u8 in_min[6]; /* Register value */ | ||
159 | u16 temp[6]; /* Register value 10 bit, right aligned */ | ||
160 | u8 temp_max[6]; /* Register value */ | ||
161 | u8 temp_min[6]; /* Register value */ | ||
162 | u8 fan[2]; /* Register value */ | ||
163 | u8 fan_min[2]; /* Register value */ | ||
164 | u8 fan_div[2]; /* Register encoding, shifted right */ | ||
165 | u16 alarms; /* Register encoding */ | ||
166 | u8 uch_config; | ||
167 | }; | ||
168 | |||
169 | static struct pci_dev *s_bridge; | ||
170 | static int vt8231_detect(struct i2c_adapter *adapter); | ||
171 | static int vt8231_detach_client(struct i2c_client *client); | ||
172 | static struct vt8231_data *vt8231_update_device(struct device *dev); | ||
173 | static void vt8231_init_client(struct i2c_client *client); | ||
174 | |||
175 | static inline int vt8231_read_value(struct i2c_client *client, u8 reg) | ||
176 | { | ||
177 | return inb_p(client->addr + reg); | ||
178 | } | ||
179 | |||
180 | static inline void vt8231_write_value(struct i2c_client *client, u8 reg, | ||
181 | u8 value) | ||
182 | { | ||
183 | outb_p(value, client->addr + reg); | ||
184 | } | ||
185 | |||
186 | /* following are the sysfs callback functions */ | ||
187 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
188 | char *buf) | ||
189 | { | ||
190 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
191 | int nr = sensor_attr->index; | ||
192 | struct vt8231_data *data = vt8231_update_device(dev); | ||
193 | |||
194 | return sprintf(buf, "%d\n", ((data->in[nr] - 3) * 10000) / 958); | ||
195 | } | ||
196 | |||
197 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
198 | char *buf) | ||
199 | { | ||
200 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
201 | int nr = sensor_attr->index; | ||
202 | struct vt8231_data *data = vt8231_update_device(dev); | ||
203 | |||
204 | return sprintf(buf, "%d\n", ((data->in_min[nr] - 3) * 10000) / 958); | ||
205 | } | ||
206 | |||
207 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | ||
208 | char *buf) | ||
209 | { | ||
210 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
211 | int nr = sensor_attr->index; | ||
212 | struct vt8231_data *data = vt8231_update_device(dev); | ||
213 | |||
214 | return sprintf(buf, "%d\n", (((data->in_max[nr] - 3) * 10000) / 958)); | ||
215 | } | ||
216 | |||
217 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | ||
218 | const char *buf, size_t count) | ||
219 | { | ||
220 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
221 | int nr = sensor_attr->index; | ||
222 | struct i2c_client *client = to_i2c_client(dev); | ||
223 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
224 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
225 | |||
226 | down(&data->update_lock); | ||
227 | data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | ||
228 | vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]); | ||
229 | up(&data->update_lock); | ||
230 | return count; | ||
231 | } | ||
232 | |||
233 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | ||
234 | const char *buf, size_t count) | ||
235 | { | ||
236 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
237 | int nr = sensor_attr->index; | ||
238 | struct i2c_client *client = to_i2c_client(dev); | ||
239 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
240 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
241 | |||
242 | down(&data->update_lock); | ||
243 | data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | ||
244 | vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]); | ||
245 | up(&data->update_lock); | ||
246 | return count; | ||
247 | } | ||
248 | |||
249 | /* Special case for input 5 as this has 3.3V scaling built into the chip */ | ||
250 | static ssize_t show_in5(struct device *dev, struct device_attribute *attr, | ||
251 | char *buf) | ||
252 | { | ||
253 | struct vt8231_data *data = vt8231_update_device(dev); | ||
254 | |||
255 | return sprintf(buf, "%d\n", | ||
256 | (((data->in[5] - 3) * 10000 * 54) / (958 * 34))); | ||
257 | } | ||
258 | |||
259 | static ssize_t show_in5_min(struct device *dev, struct device_attribute *attr, | ||
260 | char *buf) | ||
261 | { | ||
262 | struct vt8231_data *data = vt8231_update_device(dev); | ||
263 | |||
264 | return sprintf(buf, "%d\n", | ||
265 | (((data->in_min[5] - 3) * 10000 * 54) / (958 * 34))); | ||
266 | } | ||
267 | |||
268 | static ssize_t show_in5_max(struct device *dev, struct device_attribute *attr, | ||
269 | char *buf) | ||
270 | { | ||
271 | struct vt8231_data *data = vt8231_update_device(dev); | ||
272 | |||
273 | return sprintf(buf, "%d\n", | ||
274 | (((data->in_max[5] - 3) * 10000 * 54) / (958 * 34))); | ||
275 | } | ||
276 | |||
277 | static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, | ||
278 | const char *buf, size_t count) | ||
279 | { | ||
280 | struct i2c_client *client = to_i2c_client(dev); | ||
281 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
282 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
283 | |||
284 | down(&data->update_lock); | ||
285 | data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | ||
286 | 0, 255); | ||
287 | vt8231_write_value(client, regvoltmin[5], data->in_min[5]); | ||
288 | up(&data->update_lock); | ||
289 | return count; | ||
290 | } | ||
291 | |||
292 | static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, | ||
293 | const char *buf, size_t count) | ||
294 | { | ||
295 | struct i2c_client *client = to_i2c_client(dev); | ||
296 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
297 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
298 | |||
299 | down(&data->update_lock); | ||
300 | data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | ||
301 | 0, 255); | ||
302 | vt8231_write_value(client, regvoltmax[5], data->in_max[5]); | ||
303 | up(&data->update_lock); | ||
304 | return count; | ||
305 | } | ||
306 | |||
307 | #define define_voltage_sysfs(offset) \ | ||
308 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | ||
309 | show_in, NULL, offset); \ | ||
310 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
311 | show_in_min, set_in_min, offset); \ | ||
312 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
313 | show_in_max, set_in_max, offset) | ||
314 | |||
315 | define_voltage_sysfs(0); | ||
316 | define_voltage_sysfs(1); | ||
317 | define_voltage_sysfs(2); | ||
318 | define_voltage_sysfs(3); | ||
319 | define_voltage_sysfs(4); | ||
320 | |||
321 | static DEVICE_ATTR(in5_input, S_IRUGO, show_in5, NULL); | ||
322 | static DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR, show_in5_min, set_in5_min); | ||
323 | static DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR, show_in5_max, set_in5_max); | ||
324 | |||
325 | /* Temperatures */ | ||
326 | static ssize_t show_temp0(struct device *dev, struct device_attribute *attr, | ||
327 | char *buf) | ||
328 | { | ||
329 | struct vt8231_data *data = vt8231_update_device(dev); | ||
330 | return sprintf(buf, "%d\n", data->temp[0] * 250); | ||
331 | } | ||
332 | |||
333 | static ssize_t show_temp0_max(struct device *dev, struct device_attribute *attr, | ||
334 | char *buf) | ||
335 | { | ||
336 | struct vt8231_data *data = vt8231_update_device(dev); | ||
337 | return sprintf(buf, "%d\n", data->temp_max[0] * 1000); | ||
338 | } | ||
339 | |||
340 | static ssize_t show_temp0_min(struct device *dev, struct device_attribute *attr, | ||
341 | char *buf) | ||
342 | { | ||
343 | struct vt8231_data *data = vt8231_update_device(dev); | ||
344 | return sprintf(buf, "%d\n", data->temp_min[0] * 1000); | ||
345 | } | ||
346 | |||
347 | static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, | ||
348 | const char *buf, size_t count) | ||
349 | { | ||
350 | struct i2c_client *client = to_i2c_client(dev); | ||
351 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
352 | int val = simple_strtol(buf, NULL, 10); | ||
353 | |||
354 | down(&data->update_lock); | ||
355 | data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | ||
356 | vt8231_write_value(client, regtempmax[0], data->temp_max[0]); | ||
357 | up(&data->update_lock); | ||
358 | return count; | ||
359 | } | ||
360 | static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, | ||
361 | const char *buf, size_t count) | ||
362 | { | ||
363 | struct i2c_client *client = to_i2c_client(dev); | ||
364 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
365 | int val = simple_strtol(buf, NULL, 10); | ||
366 | |||
367 | down(&data->update_lock); | ||
368 | data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | ||
369 | vt8231_write_value(client, regtempmin[0], data->temp_min[0]); | ||
370 | up(&data->update_lock); | ||
371 | return count; | ||
372 | } | ||
373 | |||
374 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
375 | char *buf) | ||
376 | { | ||
377 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
378 | int nr = sensor_attr->index; | ||
379 | struct vt8231_data *data = vt8231_update_device(dev); | ||
380 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); | ||
381 | } | ||
382 | |||
383 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
384 | char *buf) | ||
385 | { | ||
386 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
387 | int nr = sensor_attr->index; | ||
388 | struct vt8231_data *data = vt8231_update_device(dev); | ||
389 | return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_max[nr])); | ||
390 | } | ||
391 | |||
392 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | ||
393 | char *buf) | ||
394 | { | ||
395 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
396 | int nr = sensor_attr->index; | ||
397 | struct vt8231_data *data = vt8231_update_device(dev); | ||
398 | return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_min[nr])); | ||
399 | } | ||
400 | |||
401 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | ||
402 | const char *buf, size_t count) | ||
403 | { | ||
404 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
405 | int nr = sensor_attr->index; | ||
406 | struct i2c_client *client = to_i2c_client(dev); | ||
407 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
408 | int val = simple_strtol(buf, NULL, 10); | ||
409 | |||
410 | down(&data->update_lock); | ||
411 | data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | ||
412 | vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]); | ||
413 | up(&data->update_lock); | ||
414 | return count; | ||
415 | } | ||
416 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | ||
417 | const char *buf, size_t count) | ||
418 | { | ||
419 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
420 | int nr = sensor_attr->index; | ||
421 | struct i2c_client *client = to_i2c_client(dev); | ||
422 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
423 | int val = simple_strtol(buf, NULL, 10); | ||
424 | |||
425 | down(&data->update_lock); | ||
426 | data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | ||
427 | vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]); | ||
428 | up(&data->update_lock); | ||
429 | return count; | ||
430 | } | ||
431 | |||
432 | /* Note that these map the Linux temperature sensor numbering (1-6) to the VIA | ||
433 | ** temperature sensor numbering (0-5) | ||
434 | */ | ||
435 | #define define_temperature_sysfs(offset) \ | ||
436 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
437 | show_temp, NULL, offset - 1); \ | ||
438 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
439 | show_temp_max, set_temp_max, offset - 1); \ | ||
440 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | ||
441 | show_temp_min, set_temp_min, offset - 1) | ||
442 | |||
443 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL); | ||
444 | static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max); | ||
445 | static DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); | ||
446 | |||
447 | define_temperature_sysfs(2); | ||
448 | define_temperature_sysfs(3); | ||
449 | define_temperature_sysfs(4); | ||
450 | define_temperature_sysfs(5); | ||
451 | define_temperature_sysfs(6); | ||
452 | |||
453 | #define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ | ||
454 | &sensor_dev_attr_temp##id##_min.dev_attr, \ | ||
455 | &sensor_dev_attr_temp##id##_max.dev_attr } | ||
456 | #define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ | ||
457 | &sensor_dev_attr_in##id##_min.dev_attr, \ | ||
458 | &sensor_dev_attr_in##id##_max.dev_attr } | ||
459 | |||
460 | struct str_device_attr_table { | ||
461 | struct device_attribute *input; | ||
462 | struct device_attribute *min; | ||
463 | struct device_attribute *max; | ||
464 | }; | ||
465 | |||
466 | static struct str_device_attr_table cfg_info_temp[] = { | ||
467 | { &dev_attr_temp1_input, &dev_attr_temp1_min, &dev_attr_temp1_max }, | ||
468 | CFG_INFO_TEMP(2), | ||
469 | CFG_INFO_TEMP(3), | ||
470 | CFG_INFO_TEMP(4), | ||
471 | CFG_INFO_TEMP(5), | ||
472 | CFG_INFO_TEMP(6) | ||
473 | }; | ||
474 | |||
475 | static struct str_device_attr_table cfg_info_volt[] = { | ||
476 | CFG_INFO_VOLT(0), | ||
477 | CFG_INFO_VOLT(1), | ||
478 | CFG_INFO_VOLT(2), | ||
479 | CFG_INFO_VOLT(3), | ||
480 | CFG_INFO_VOLT(4), | ||
481 | { &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max } | ||
482 | }; | ||
483 | |||
484 | /* Fans */ | ||
485 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | ||
486 | char *buf) | ||
487 | { | ||
488 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
489 | int nr = sensor_attr->index; | ||
490 | struct vt8231_data *data = vt8231_update_device(dev); | ||
491 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | ||
492 | DIV_FROM_REG(data->fan_div[nr]))); | ||
493 | } | ||
494 | |||
495 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | ||
496 | char *buf) | ||
497 | { | ||
498 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
499 | int nr = sensor_attr->index; | ||
500 | struct vt8231_data *data = vt8231_update_device(dev); | ||
501 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], | ||
502 | DIV_FROM_REG(data->fan_div[nr]))); | ||
503 | } | ||
504 | |||
505 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, | ||
506 | char *buf) | ||
507 | { | ||
508 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
509 | int nr = sensor_attr->index; | ||
510 | struct vt8231_data *data = vt8231_update_device(dev); | ||
511 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); | ||
512 | } | ||
513 | |||
514 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | ||
515 | const char *buf, size_t count) | ||
516 | { | ||
517 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
518 | int nr = sensor_attr->index; | ||
519 | struct i2c_client *client = to_i2c_client(dev); | ||
520 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
521 | int val = simple_strtoul(buf, NULL, 10); | ||
522 | |||
523 | down(&data->update_lock); | ||
524 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | ||
525 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | ||
526 | up(&data->update_lock); | ||
527 | return count; | ||
528 | } | ||
529 | |||
530 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | ||
531 | const char *buf, size_t count) | ||
532 | { | ||
533 | struct i2c_client *client = to_i2c_client(dev); | ||
534 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
535 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
536 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
537 | int nr = sensor_attr->index; | ||
538 | int old = vt8231_read_value(client, VT8231_REG_FANDIV); | ||
539 | long min = FAN_FROM_REG(data->fan_min[nr], | ||
540 | DIV_FROM_REG(data->fan_div[nr])); | ||
541 | |||
542 | down(&data->update_lock); | ||
543 | switch (val) { | ||
544 | case 1: data->fan_div[nr] = 0; break; | ||
545 | case 2: data->fan_div[nr] = 1; break; | ||
546 | case 4: data->fan_div[nr] = 2; break; | ||
547 | case 8: data->fan_div[nr] = 3; break; | ||
548 | default: | ||
549 | dev_err(&client->dev, "fan_div value %ld not supported." | ||
550 | "Choose one of 1, 2, 4 or 8!\n", val); | ||
551 | up(&data->update_lock); | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | |||
555 | /* Correct the fan minimum speed */ | ||
556 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | ||
557 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | ||
558 | |||
559 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | ||
560 | vt8231_write_value(client, VT8231_REG_FANDIV, old); | ||
561 | up(&data->update_lock); | ||
562 | return count; | ||
563 | } | ||
564 | |||
565 | |||
566 | #define define_fan_sysfs(offset) \ | ||
567 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
568 | show_fan, NULL, offset - 1); \ | ||
569 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | ||
570 | show_fan_div, set_fan_div, offset - 1); \ | ||
571 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
572 | show_fan_min, set_fan_min, offset - 1) | ||
573 | |||
574 | define_fan_sysfs(1); | ||
575 | define_fan_sysfs(2); | ||
576 | |||
577 | /* Alarms */ | ||
578 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | ||
579 | char *buf) | ||
580 | { | ||
581 | struct vt8231_data *data = vt8231_update_device(dev); | ||
582 | return sprintf(buf, "%d\n", data->alarms); | ||
583 | } | ||
584 | |||
585 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
586 | |||
587 | static struct i2c_driver vt8231_driver = { | ||
588 | .driver = { | ||
589 | .name = "vt8231", | ||
590 | }, | ||
591 | .attach_adapter = vt8231_detect, | ||
592 | .detach_client = vt8231_detach_client, | ||
593 | }; | ||
594 | |||
595 | static struct pci_device_id vt8231_pci_ids[] = { | ||
596 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, | ||
597 | { 0, } | ||
598 | }; | ||
599 | |||
600 | MODULE_DEVICE_TABLE(pci, vt8231_pci_ids); | ||
601 | |||
602 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, | ||
603 | const struct pci_device_id *id); | ||
604 | |||
605 | static struct pci_driver vt8231_pci_driver = { | ||
606 | .name = "vt8231", | ||
607 | .id_table = vt8231_pci_ids, | ||
608 | .probe = vt8231_pci_probe, | ||
609 | }; | ||
610 | |||
611 | int vt8231_detect(struct i2c_adapter *adapter) | ||
612 | { | ||
613 | struct i2c_client *client; | ||
614 | struct vt8231_data *data; | ||
615 | int err = 0, i; | ||
616 | u16 val; | ||
617 | |||
618 | /* 8231 requires multiple of 256 */ | ||
619 | if (force_addr) { | ||
620 | isa_address = force_addr & 0xFF00; | ||
621 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
622 | isa_address); | ||
623 | if (PCIBIOS_SUCCESSFUL != pci_write_config_word(s_bridge, | ||
624 | VT8231_BASE_REG, isa_address)) | ||
625 | return -ENODEV; | ||
626 | } | ||
627 | |||
628 | if (PCIBIOS_SUCCESSFUL != | ||
629 | pci_read_config_word(s_bridge, VT8231_ENABLE_REG, &val)) | ||
630 | return -ENODEV; | ||
631 | |||
632 | if (!(val & 0x0001)) { | ||
633 | dev_warn(&adapter->dev, "enabling sensors\n"); | ||
634 | if (PCIBIOS_SUCCESSFUL != | ||
635 | pci_write_config_word(s_bridge, VT8231_ENABLE_REG, | ||
636 | val | 0x0001)) | ||
637 | return -ENODEV; | ||
638 | } | ||
639 | |||
640 | /* Reserve the ISA region */ | ||
641 | if (!request_region(isa_address, VT8231_EXTENT, | ||
642 | vt8231_pci_driver.name)) { | ||
643 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | ||
644 | isa_address); | ||
645 | return -ENODEV; | ||
646 | } | ||
647 | |||
648 | if (!(data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL))) { | ||
649 | err = -ENOMEM; | ||
650 | goto exit_release; | ||
651 | } | ||
652 | |||
653 | client = &data->client; | ||
654 | i2c_set_clientdata(client, data); | ||
655 | client->addr = isa_address; | ||
656 | client->adapter = adapter; | ||
657 | client->driver = &vt8231_driver; | ||
658 | client->dev.parent = &adapter->dev; | ||
659 | |||
660 | /* Fill in the remaining client fields and put into the global list */ | ||
661 | strlcpy(client->name, "vt8231", I2C_NAME_SIZE); | ||
662 | |||
663 | init_MUTEX(&data->update_lock); | ||
664 | |||
665 | /* Tell the I2C layer a new client has arrived */ | ||
666 | if ((err = i2c_attach_client(client))) | ||
667 | goto exit_free; | ||
668 | |||
669 | vt8231_init_client(client); | ||
670 | |||
671 | /* Register sysfs hooks */ | ||
672 | data->class_dev = hwmon_device_register(&client->dev); | ||
673 | if (IS_ERR(data->class_dev)) { | ||
674 | err = PTR_ERR(data->class_dev); | ||
675 | goto exit_detach; | ||
676 | } | ||
677 | |||
678 | /* Must update device information to find out the config field */ | ||
679 | data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); | ||
680 | |||
681 | for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) { | ||
682 | if (ISTEMP(i, data->uch_config)) { | ||
683 | device_create_file(&client->dev, | ||
684 | cfg_info_temp[i].input); | ||
685 | device_create_file(&client->dev, cfg_info_temp[i].max); | ||
686 | device_create_file(&client->dev, cfg_info_temp[i].min); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) { | ||
691 | if (ISVOLT(i, data->uch_config)) { | ||
692 | device_create_file(&client->dev, | ||
693 | cfg_info_volt[i].input); | ||
694 | device_create_file(&client->dev, cfg_info_volt[i].max); | ||
695 | device_create_file(&client->dev, cfg_info_volt[i].min); | ||
696 | } | ||
697 | } | ||
698 | |||
699 | device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr); | ||
700 | device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr); | ||
701 | device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr); | ||
702 | device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr); | ||
703 | device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr); | ||
704 | device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr); | ||
705 | |||
706 | device_create_file(&client->dev, &dev_attr_alarms); | ||
707 | return 0; | ||
708 | |||
709 | exit_detach: | ||
710 | i2c_detach_client(client); | ||
711 | exit_free: | ||
712 | kfree(data); | ||
713 | exit_release: | ||
714 | release_region(isa_address, VT8231_EXTENT); | ||
715 | return err; | ||
716 | } | ||
717 | |||
718 | static int vt8231_detach_client(struct i2c_client *client) | ||
719 | { | ||
720 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
721 | int err; | ||
722 | |||
723 | hwmon_device_unregister(data->class_dev); | ||
724 | |||
725 | if ((err = i2c_detach_client(client))) { | ||
726 | return err; | ||
727 | } | ||
728 | |||
729 | release_region(client->addr, VT8231_EXTENT); | ||
730 | kfree(data); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static void vt8231_init_client(struct i2c_client *client) | ||
736 | { | ||
737 | vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0); | ||
738 | vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0); | ||
739 | } | ||
740 | |||
741 | static struct vt8231_data *vt8231_update_device(struct device *dev) | ||
742 | { | ||
743 | struct i2c_client *client = to_i2c_client(dev); | ||
744 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
745 | int i; | ||
746 | u16 low; | ||
747 | |||
748 | down(&data->update_lock); | ||
749 | |||
750 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
751 | || !data->valid) { | ||
752 | for (i = 0; i < 6; i++) { | ||
753 | if (ISVOLT(i, data->uch_config)) { | ||
754 | data->in[i] = vt8231_read_value(client, | ||
755 | regvolt[i]); | ||
756 | data->in_min[i] = vt8231_read_value(client, | ||
757 | regvoltmin[i]); | ||
758 | data->in_max[i] = vt8231_read_value(client, | ||
759 | regvoltmax[i]); | ||
760 | } | ||
761 | } | ||
762 | for (i = 0; i < 2; i++) { | ||
763 | data->fan[i] = vt8231_read_value(client, | ||
764 | VT8231_REG_FAN(i)); | ||
765 | data->fan_min[i] = vt8231_read_value(client, | ||
766 | VT8231_REG_FAN_MIN(i)); | ||
767 | } | ||
768 | |||
769 | low = vt8231_read_value(client, VT8231_REG_TEMP_LOW01); | ||
770 | low = (low >> 6) | ((low & 0x30) >> 2) | ||
771 | | (vt8231_read_value(client, VT8231_REG_TEMP_LOW25) << 4); | ||
772 | for (i = 0; i < 6; i++) { | ||
773 | if (ISTEMP(i, data->uch_config)) { | ||
774 | data->temp[i] = (vt8231_read_value(client, | ||
775 | regtemp[i]) << 2) | ||
776 | | ((low >> (2 * i)) & 0x03); | ||
777 | data->temp_max[i] = vt8231_read_value(client, | ||
778 | regtempmax[i]); | ||
779 | data->temp_min[i] = vt8231_read_value(client, | ||
780 | regtempmin[i]); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | i = vt8231_read_value(client, VT8231_REG_FANDIV); | ||
785 | data->fan_div[0] = (i >> 4) & 0x03; | ||
786 | data->fan_div[1] = i >> 6; | ||
787 | data->alarms = vt8231_read_value(client, VT8231_REG_ALARM1) | | ||
788 | (vt8231_read_value(client, VT8231_REG_ALARM2) << 8); | ||
789 | |||
790 | /* Set alarm flags correctly */ | ||
791 | if (!data->fan[0] && data->fan_min[0]) { | ||
792 | data->alarms |= 0x40; | ||
793 | } else if (data->fan[0] && !data->fan_min[0]) { | ||
794 | data->alarms &= ~0x40; | ||
795 | } | ||
796 | |||
797 | if (!data->fan[1] && data->fan_min[1]) { | ||
798 | data->alarms |= 0x80; | ||
799 | } else if (data->fan[1] && !data->fan_min[1]) { | ||
800 | data->alarms &= ~0x80; | ||
801 | } | ||
802 | |||
803 | data->last_updated = jiffies; | ||
804 | data->valid = 1; | ||
805 | } | ||
806 | |||
807 | up(&data->update_lock); | ||
808 | |||
809 | return data; | ||
810 | } | ||
811 | |||
812 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, | ||
813 | const struct pci_device_id *id) | ||
814 | { | ||
815 | u16 val; | ||
816 | |||
817 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG, | ||
818 | &val)) | ||
819 | return -ENODEV; | ||
820 | |||
821 | isa_address = val & ~(VT8231_EXTENT - 1); | ||
822 | if (isa_address == 0 && force_addr == 0) { | ||
823 | dev_err(&dev->dev, "base address not set -\ | ||
824 | upgrade BIOS or use force_addr=0xaddr\n"); | ||
825 | return -ENODEV; | ||
826 | } | ||
827 | |||
828 | s_bridge = pci_dev_get(dev); | ||
829 | |||
830 | if (i2c_isa_add_driver(&vt8231_driver)) { | ||
831 | pci_dev_put(s_bridge); | ||
832 | s_bridge = NULL; | ||
833 | } | ||
834 | |||
835 | /* Always return failure here. This is to allow other drivers to bind | ||
836 | * to this pci device. We don't really want to have control over the | ||
837 | * pci device, we only wanted to read as few register values from it. | ||
838 | */ | ||
839 | return -ENODEV; | ||
840 | } | ||
841 | |||
842 | static int __init sm_vt8231_init(void) | ||
843 | { | ||
844 | return pci_module_init(&vt8231_pci_driver); | ||
845 | } | ||
846 | |||
847 | static void __exit sm_vt8231_exit(void) | ||
848 | { | ||
849 | pci_unregister_driver(&vt8231_pci_driver); | ||
850 | if (s_bridge != NULL) { | ||
851 | i2c_isa_del_driver(&vt8231_driver); | ||
852 | pci_dev_put(s_bridge); | ||
853 | s_bridge = NULL; | ||
854 | } | ||
855 | } | ||
856 | |||
857 | MODULE_AUTHOR("Roger Lucas <roger@planbit.co.uk>"); | ||
858 | MODULE_DESCRIPTION("VT8231 sensors"); | ||
859 | MODULE_LICENSE("GPL"); | ||
860 | |||
861 | module_init(sm_vt8231_init); | ||
862 | module_exit(sm_vt8231_exit); | ||
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index eee22a57e929..12d79f5e4900 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -676,7 +676,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
676 | int i, err = 0; | 676 | int i, err = 0; |
677 | 677 | ||
678 | if (!request_region(address + REGION_OFFSET, REGION_LENGTH, | 678 | if (!request_region(address + REGION_OFFSET, REGION_LENGTH, |
679 | w83627ehf_driver.name)) { | 679 | w83627ehf_driver.driver.name)) { |
680 | err = -EBUSY; | 680 | err = -EBUSY; |
681 | goto exit; | 681 | goto exit; |
682 | } | 682 | } |
@@ -785,8 +785,9 @@ static int w83627ehf_detach_client(struct i2c_client *client) | |||
785 | } | 785 | } |
786 | 786 | ||
787 | static struct i2c_driver w83627ehf_driver = { | 787 | static struct i2c_driver w83627ehf_driver = { |
788 | .owner = THIS_MODULE, | 788 | .driver = { |
789 | .name = "w83627ehf", | 789 | .name = "w83627ehf", |
790 | }, | ||
790 | .attach_adapter = w83627ehf_detect, | 791 | .attach_adapter = w83627ehf_detect, |
791 | .detach_client = w83627ehf_detach_client, | 792 | .detach_client = w83627ehf_detach_client, |
792 | }; | 793 | }; |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index bbb3dcde146b..7ea441d4da63 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -332,8 +332,9 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev); | |||
332 | static void w83627hf_init_client(struct i2c_client *client); | 332 | static void w83627hf_init_client(struct i2c_client *client); |
333 | 333 | ||
334 | static struct i2c_driver w83627hf_driver = { | 334 | static struct i2c_driver w83627hf_driver = { |
335 | .owner = THIS_MODULE, | 335 | .driver = { |
336 | .name = "w83627hf", | 336 | .name = "w83627hf", |
337 | }, | ||
337 | .attach_adapter = w83627hf_detect, | 338 | .attach_adapter = w83627hf_detect, |
338 | .detach_client = w83627hf_detach_client, | 339 | .detach_client = w83627hf_detach_client, |
339 | }; | 340 | }; |
@@ -1009,7 +1010,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1009 | address = force_addr & WINB_ALIGNMENT; | 1010 | address = force_addr & WINB_ALIGNMENT; |
1010 | 1011 | ||
1011 | if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, | 1012 | if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, |
1012 | w83627hf_driver.name)) { | 1013 | w83627hf_driver.driver.name)) { |
1013 | err = -EBUSY; | 1014 | err = -EBUSY; |
1014 | goto ERROR0; | 1015 | goto ERROR0; |
1015 | } | 1016 | } |
@@ -1122,11 +1123,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1122 | if (kind != w83697hf) | 1123 | if (kind != w83697hf) |
1123 | device_create_file_temp(new_client, 3); | 1124 | device_create_file_temp(new_client, 3); |
1124 | 1125 | ||
1125 | if (kind != w83697hf) | 1126 | if (kind != w83697hf && data->vid != 0xff) { |
1126 | device_create_file_vid(new_client); | 1127 | device_create_file_vid(new_client); |
1127 | |||
1128 | if (kind != w83697hf) | ||
1129 | device_create_file_vrm(new_client); | 1128 | device_create_file_vrm(new_client); |
1129 | } | ||
1130 | 1130 | ||
1131 | device_create_file_fan_div(new_client, 1); | 1131 | device_create_file_fan_div(new_client, 1); |
1132 | device_create_file_fan_div(new_client, 2); | 1132 | device_create_file_fan_div(new_client, 2); |
@@ -1232,7 +1232,7 @@ static int w83627thf_read_gpio5(struct i2c_client *client) | |||
1232 | 1232 | ||
1233 | /* Make sure the pins are configured for input | 1233 | /* Make sure the pins are configured for input |
1234 | There must be at least five (VRM 9), and possibly 6 (VRM 10) */ | 1234 | There must be at least five (VRM 9), and possibly 6 (VRM 10) */ |
1235 | sel = superio_inb(W83627THF_GPIO5_IOSR); | 1235 | sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f; |
1236 | if ((sel & 0x1f) != 0x1f) { | 1236 | if ((sel & 0x1f) != 0x1f) { |
1237 | dev_dbg(&client->dev, "GPIO5 not configured for VID " | 1237 | dev_dbg(&client->dev, "GPIO5 not configured for VID " |
1238 | "function\n"); | 1238 | "function\n"); |
@@ -1323,19 +1323,18 @@ static void w83627hf_init_client(struct i2c_client *client) | |||
1323 | int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); | 1323 | int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); |
1324 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); | 1324 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); |
1325 | } else if (w83627thf == data->type) { | 1325 | } else if (w83627thf == data->type) { |
1326 | data->vid = w83627thf_read_gpio5(client) & 0x3f; | 1326 | data->vid = w83627thf_read_gpio5(client); |
1327 | } | 1327 | } |
1328 | 1328 | ||
1329 | /* Read VRM & OVT Config only once */ | 1329 | /* Read VRM & OVT Config only once */ |
1330 | if (w83627thf == data->type || w83637hf == data->type) { | 1330 | if (w83627thf == data->type || w83637hf == data->type) { |
1331 | data->vrm_ovt = | 1331 | data->vrm_ovt = |
1332 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); | 1332 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); |
1333 | data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82; | ||
1334 | } else { | ||
1335 | /* Convert VID to voltage based on default VRM */ | ||
1336 | data->vrm = vid_which_vrm(); | ||
1337 | } | 1333 | } |
1338 | 1334 | ||
1335 | /* Convert VID to voltage based on VRM */ | ||
1336 | data->vrm = vid_which_vrm(); | ||
1337 | |||
1339 | tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); | 1338 | tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); |
1340 | for (i = 1; i <= 3; i++) { | 1339 | for (i = 1; i <= 3; i++) { |
1341 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1340 | if (!(tmp & BIT_SCFG1[i - 1])) { |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index ffdb3a03e2b5..557114872f3c 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -269,17 +269,18 @@ static struct w83781d_data *w83781d_update_device(struct device *dev); | |||
269 | static void w83781d_init_client(struct i2c_client *client); | 269 | static void w83781d_init_client(struct i2c_client *client); |
270 | 270 | ||
271 | static struct i2c_driver w83781d_driver = { | 271 | static struct i2c_driver w83781d_driver = { |
272 | .owner = THIS_MODULE, | 272 | .driver = { |
273 | .name = "w83781d", | 273 | .name = "w83781d", |
274 | }, | ||
274 | .id = I2C_DRIVERID_W83781D, | 275 | .id = I2C_DRIVERID_W83781D, |
275 | .flags = I2C_DF_NOTIFY, | ||
276 | .attach_adapter = w83781d_attach_adapter, | 276 | .attach_adapter = w83781d_attach_adapter, |
277 | .detach_client = w83781d_detach_client, | 277 | .detach_client = w83781d_detach_client, |
278 | }; | 278 | }; |
279 | 279 | ||
280 | static struct i2c_driver w83781d_isa_driver = { | 280 | static struct i2c_driver w83781d_isa_driver = { |
281 | .owner = THIS_MODULE, | 281 | .driver = { |
282 | .name = "w83781d-isa", | 282 | .name = "w83781d-isa", |
283 | }, | ||
283 | .attach_adapter = w83781d_isa_attach_adapter, | 284 | .attach_adapter = w83781d_isa_attach_adapter, |
284 | .detach_client = w83781d_detach_client, | 285 | .detach_client = w83781d_detach_client, |
285 | }; | 286 | }; |
@@ -1012,7 +1013,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1012 | 1013 | ||
1013 | if (is_isa) | 1014 | if (is_isa) |
1014 | if (!request_region(address, W83781D_EXTENT, | 1015 | if (!request_region(address, W83781D_EXTENT, |
1015 | w83781d_isa_driver.name)) { | 1016 | w83781d_isa_driver.driver.name)) { |
1016 | dev_dbg(&adapter->dev, "Request of region " | 1017 | dev_dbg(&adapter->dev, "Request of region " |
1017 | "0x%x-0x%x for w83781d failed\n", address, | 1018 | "0x%x-0x%x for w83781d failed\n", address, |
1018 | address + W83781D_EXTENT - 1); | 1019 | address + W83781D_EXTENT - 1); |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 1ba072630361..b176bf0c4c7b 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -269,7 +269,6 @@ DIV_TO_REG(long val) | |||
269 | struct w83792d_data { | 269 | struct w83792d_data { |
270 | struct i2c_client client; | 270 | struct i2c_client client; |
271 | struct class_device *class_dev; | 271 | struct class_device *class_dev; |
272 | struct semaphore lock; | ||
273 | enum chips type; | 272 | enum chips type; |
274 | 273 | ||
275 | struct semaphore update_lock; | 274 | struct semaphore update_lock; |
@@ -282,7 +281,7 @@ struct w83792d_data { | |||
282 | u8 in[9]; /* Register value */ | 281 | u8 in[9]; /* Register value */ |
283 | u8 in_max[9]; /* Register value */ | 282 | u8 in_max[9]; /* Register value */ |
284 | u8 in_min[9]; /* Register value */ | 283 | u8 in_min[9]; /* Register value */ |
285 | u8 low_bits[2]; /* Additional resolution to voltage in0-6 */ | 284 | u16 low_bits; /* Additional resolution to voltage in6-0 */ |
286 | u8 fan[7]; /* Register value */ | 285 | u8 fan[7]; /* Register value */ |
287 | u8 fan_min[7]; /* Register value */ | 286 | u8 fan_min[7]; /* Register value */ |
288 | u8 temp1[3]; /* current, over, thyst */ | 287 | u8 temp1[3]; /* current, over, thyst */ |
@@ -317,45 +316,17 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev); | |||
317 | static void w83792d_init_client(struct i2c_client *client); | 316 | static void w83792d_init_client(struct i2c_client *client); |
318 | 317 | ||
319 | static struct i2c_driver w83792d_driver = { | 318 | static struct i2c_driver w83792d_driver = { |
320 | .owner = THIS_MODULE, | 319 | .driver = { |
321 | .name = "w83792d", | 320 | .name = "w83792d", |
322 | .flags = I2C_DF_NOTIFY, | 321 | }, |
323 | .attach_adapter = w83792d_attach_adapter, | 322 | .attach_adapter = w83792d_attach_adapter, |
324 | .detach_client = w83792d_detach_client, | 323 | .detach_client = w83792d_detach_client, |
325 | }; | 324 | }; |
326 | 325 | ||
327 | static long in_count_from_reg(int nr, struct w83792d_data *data) | 326 | static inline long in_count_from_reg(int nr, struct w83792d_data *data) |
328 | { | 327 | { |
329 | u16 vol_count = data->in[nr]; | 328 | /* in7 and in8 do not have low bits, but the formula still works */ |
330 | u16 low_bits = 0; | 329 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); |
331 | vol_count = (vol_count << 2); | ||
332 | switch (nr) | ||
333 | { | ||
334 | case 0: /* vin0 */ | ||
335 | low_bits = (data->low_bits[0]) & 0x03; | ||
336 | break; | ||
337 | case 1: /* vin1 */ | ||
338 | low_bits = ((data->low_bits[0]) & 0x0c) >> 2; | ||
339 | break; | ||
340 | case 2: /* vin2 */ | ||
341 | low_bits = ((data->low_bits[0]) & 0x30) >> 4; | ||
342 | break; | ||
343 | case 3: /* vin3 */ | ||
344 | low_bits = ((data->low_bits[0]) & 0xc0) >> 6; | ||
345 | break; | ||
346 | case 4: /* vin4 */ | ||
347 | low_bits = (data->low_bits[1]) & 0x03; | ||
348 | break; | ||
349 | case 5: /* vin5 */ | ||
350 | low_bits = ((data->low_bits[1]) & 0x0c) >> 2; | ||
351 | break; | ||
352 | case 6: /* vin6 */ | ||
353 | low_bits = ((data->low_bits[1]) & 0x30) >> 4; | ||
354 | default: | ||
355 | break; | ||
356 | } | ||
357 | vol_count = vol_count | low_bits; | ||
358 | return vol_count; | ||
359 | } | 330 | } |
360 | 331 | ||
361 | /* following are the sysfs callback functions */ | 332 | /* following are the sysfs callback functions */ |
@@ -1192,7 +1163,6 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1192 | new_client = &data->client; | 1163 | new_client = &data->client; |
1193 | i2c_set_clientdata(new_client, data); | 1164 | i2c_set_clientdata(new_client, data); |
1194 | new_client->addr = address; | 1165 | new_client->addr = address; |
1195 | init_MUTEX(&data->lock); | ||
1196 | new_client->adapter = adapter; | 1166 | new_client->adapter = adapter; |
1197 | new_client->driver = &w83792d_driver; | 1167 | new_client->driver = &w83792d_driver; |
1198 | new_client->flags = 0; | 1168 | new_client->flags = 0; |
@@ -1243,7 +1213,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1243 | goto ERROR1; | 1213 | goto ERROR1; |
1244 | } | 1214 | } |
1245 | val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID); | 1215 | val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID); |
1246 | if (val1 == 0x7a && address >= 0x2c) { | 1216 | if (val1 == 0x7a) { |
1247 | kind = w83792d; | 1217 | kind = w83792d; |
1248 | } else { | 1218 | } else { |
1249 | if (kind == 0) | 1219 | if (kind == 0) |
@@ -1416,26 +1386,17 @@ w83792d_detach_client(struct i2c_client *client) | |||
1416 | return 0; | 1386 | return 0; |
1417 | } | 1387 | } |
1418 | 1388 | ||
1419 | /* The SMBus locks itself, usually, but nothing may access the Winbond between | 1389 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, |
1420 | bank switches. ISA access must always be locked explicitly! | 1390 | but the driver only accesses registers in bank 0, so we don't have |
1421 | We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks, | 1391 | to switch banks and lock access between switches. */ |
1422 | would slow down the W83792D access and should not be necessary. | 1392 | static int w83792d_read_value(struct i2c_client *client, u8 reg) |
1423 | There are some ugly typecasts here, but the good news is - they should | ||
1424 | nowhere else be necessary! */ | ||
1425 | static int | ||
1426 | w83792d_read_value(struct i2c_client *client, u8 reg) | ||
1427 | { | 1393 | { |
1428 | int res=0; | 1394 | return i2c_smbus_read_byte_data(client, reg); |
1429 | res = i2c_smbus_read_byte_data(client, reg); | ||
1430 | |||
1431 | return res; | ||
1432 | } | 1395 | } |
1433 | 1396 | ||
1434 | static int | 1397 | static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) |
1435 | w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
1436 | { | 1398 | { |
1437 | i2c_smbus_write_byte_data(client, reg, value); | 1399 | return i2c_smbus_write_byte_data(client, reg, value); |
1438 | return 0; | ||
1439 | } | 1400 | } |
1440 | 1401 | ||
1441 | static void | 1402 | static void |
@@ -1492,10 +1453,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) | |||
1492 | data->in_min[i] = w83792d_read_value(client, | 1453 | data->in_min[i] = w83792d_read_value(client, |
1493 | W83792D_REG_IN_MIN[i]); | 1454 | W83792D_REG_IN_MIN[i]); |
1494 | } | 1455 | } |
1495 | data->low_bits[0] = w83792d_read_value(client, | 1456 | data->low_bits = w83792d_read_value(client, |
1496 | W83792D_REG_LOW_BITS1); | 1457 | W83792D_REG_LOW_BITS1) + |
1497 | data->low_bits[1] = w83792d_read_value(client, | 1458 | (w83792d_read_value(client, |
1498 | W83792D_REG_LOW_BITS2); | 1459 | W83792D_REG_LOW_BITS2) << 8); |
1499 | for (i = 0; i < 7; i++) { | 1460 | for (i = 0; i < 7; i++) { |
1500 | /* Update the Fan measured value and limits */ | 1461 | /* Update the Fan measured value and limits */ |
1501 | data->fan[i] = w83792d_read_value(client, | 1462 | data->fan[i] = w83792d_read_value(client, |
@@ -1506,7 +1467,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) | |||
1506 | pwm_array_tmp[i] = w83792d_read_value(client, | 1467 | pwm_array_tmp[i] = w83792d_read_value(client, |
1507 | W83792D_REG_PWM[i]); | 1468 | W83792D_REG_PWM[i]); |
1508 | data->pwm[i] = pwm_array_tmp[i] & 0x0f; | 1469 | data->pwm[i] = pwm_array_tmp[i] & 0x0f; |
1509 | data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01; | 1470 | data->pwm_mode[i] = pwm_array_tmp[i] >> 7; |
1510 | } | 1471 | } |
1511 | 1472 | ||
1512 | reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); | 1473 | reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); |
@@ -1607,8 +1568,8 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev) | |||
1607 | dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]); | 1568 | dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]); |
1608 | dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]); | 1569 | dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]); |
1609 | } | 1570 | } |
1610 | dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]); | 1571 | dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff); |
1611 | dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]); | 1572 | dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8); |
1612 | dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n"); | 1573 | dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n"); |
1613 | for (i=0; i<7; i++) { | 1574 | for (i=0; i<7; i++) { |
1614 | dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); | 1575 | dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); |
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index f495b6378668..f66c0cfdeda7 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c | |||
@@ -92,10 +92,10 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); | |||
92 | */ | 92 | */ |
93 | 93 | ||
94 | static struct i2c_driver w83l785ts_driver = { | 94 | static struct i2c_driver w83l785ts_driver = { |
95 | .owner = THIS_MODULE, | 95 | .driver = { |
96 | .name = "w83l785ts", | 96 | .name = "w83l785ts", |
97 | }, | ||
97 | .id = I2C_DRIVERID_W83L785TS, | 98 | .id = I2C_DRIVERID_W83L785TS, |
98 | .flags = I2C_DF_NOTIFY, | ||
99 | .attach_adapter = w83l785ts_attach_adapter, | 99 | .attach_adapter = w83l785ts_attach_adapter, |
100 | .detach_client = w83l785ts_detach_client, | 100 | .detach_client = w83l785ts_detach_client, |
101 | }; | 101 | }; |