]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/hwmon/lm78.c
ixgbe: invalidate FCoE DDP context when no error status is available
[net-next-2.6.git] / drivers / hwmon / lm78.c
CommitLineData
1da177e4
LT
1/*
2 lm78.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
c40769fe 5 Copyright (c) 2007 Jean Delvare <khali@linux-fr.org>
1da177e4
LT
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
1da177e4
LT
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/jiffies.h>
26#include <linux/i2c.h>
c40769fe
JD
27#include <linux/platform_device.h>
28#include <linux/ioport.h>
943b0830 29#include <linux/hwmon.h>
19f673ed 30#include <linux/hwmon-vid.h>
247dde4c 31#include <linux/hwmon-sysfs.h>
943b0830 32#include <linux/err.h>
9a61bf63 33#include <linux/mutex.h>
6055fae8 34#include <linux/io.h>
1da177e4 35
c40769fe
JD
36/* ISA device, if found */
37static struct platform_device *pdev;
38
1da177e4 39/* Addresses to scan */
25e9c86d
MH
40static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
41 0x2e, 0x2f, I2C_CLIENT_END };
2d8672c5 42static unsigned short isa_address = 0x290;
1da177e4 43
e5e9f44c 44enum chips { lm78, lm79 };
1da177e4
LT
45
46/* Many LM78 constants specified below */
47
48/* Length of ISA address segment */
49#define LM78_EXTENT 8
50
51/* Where are the ISA address/data registers relative to the base address */
52#define LM78_ADDR_REG_OFFSET 5
53#define LM78_DATA_REG_OFFSET 6
54
55/* The LM78 registers */
56#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
57#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
58#define LM78_REG_IN(nr) (0x20 + (nr))
59
60#define LM78_REG_FAN_MIN(nr) (0x3b + (nr))
61#define LM78_REG_FAN(nr) (0x28 + (nr))
62
63#define LM78_REG_TEMP 0x27
64#define LM78_REG_TEMP_OVER 0x39
65#define LM78_REG_TEMP_HYST 0x3a
66
67#define LM78_REG_ALARM1 0x41
68#define LM78_REG_ALARM2 0x42
69
70#define LM78_REG_VID_FANDIV 0x47
71
72#define LM78_REG_CONFIG 0x40
73#define LM78_REG_CHIPID 0x49
74#define LM78_REG_I2C_ADDR 0x48
75
76
77/* Conversions. Rounding and limit checking is only done on the TO_REG
78 variants. */
79
80/* IN: mV, (0V to 4.08V)
81 REG: 16mV/bit */
82static inline u8 IN_TO_REG(unsigned long val)
83{
84 unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
85 return (nval + 8) / 16;
86}
87#define IN_FROM_REG(val) ((val) * 16)
88
89static inline u8 FAN_TO_REG(long rpm, int div)
90{
91 if (rpm <= 0)
92 return 255;
93 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
94}
95
96static inline int FAN_FROM_REG(u8 val, int div)
97{
98 return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
99}
100
101/* TEMP: mC (-128C to +127C)
102 REG: 1C/bit, two's complement */
103static inline s8 TEMP_TO_REG(int val)
104{
105 int nval = SENSORS_LIMIT(val, -128000, 127000) ;
106 return nval<0 ? (nval-500)/1000 : (nval+500)/1000;
107}
108
109static inline int TEMP_FROM_REG(s8 val)
110{
111 return val * 1000;
112}
113
1da177e4
LT
114#define DIV_FROM_REG(val) (1 << (val))
115
1da177e4 116struct lm78_data {
0c6e9731 117 struct i2c_client *client;
1beeffe4 118 struct device *hwmon_dev;
9a61bf63 119 struct mutex lock;
1da177e4
LT
120 enum chips type;
121
6e1b5029
JD
122 /* For ISA device only */
123 const char *name;
124 int isa_addr;
125
9a61bf63 126 struct mutex update_lock;
1da177e4
LT
127 char valid; /* !=0 if following fields are valid */
128 unsigned long last_updated; /* In jiffies */
129
130 u8 in[7]; /* Register value */
131 u8 in_max[7]; /* Register value */
132 u8 in_min[7]; /* Register value */
133 u8 fan[3]; /* Register value */
134 u8 fan_min[3]; /* Register value */
135 s8 temp; /* Register value */
136 s8 temp_over; /* Register value */
137 s8 temp_hyst; /* Register value */
138 u8 fan_div[3]; /* Register encoding, shifted right */
139 u8 vid; /* Register encoding, combined */
140 u16 alarms; /* Register encoding, combined */
141};
142
143
310ec792 144static int lm78_i2c_detect(struct i2c_client *client,
0c6e9731
JD
145 struct i2c_board_info *info);
146static int lm78_i2c_probe(struct i2c_client *client,
147 const struct i2c_device_id *id);
148static int lm78_i2c_remove(struct i2c_client *client);
1da177e4 149
c40769fe
JD
150static int __devinit lm78_isa_probe(struct platform_device *pdev);
151static int __devexit lm78_isa_remove(struct platform_device *pdev);
152
c59cc301
JD
153static int lm78_read_value(struct lm78_data *data, u8 reg);
154static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
1da177e4 155static struct lm78_data *lm78_update_device(struct device *dev);
c59cc301 156static void lm78_init_device(struct lm78_data *data);
1da177e4
LT
157
158
0c6e9731
JD
159static const struct i2c_device_id lm78_i2c_id[] = {
160 { "lm78", lm78 },
161 { "lm79", lm79 },
162 { }
163};
164MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
165
1da177e4 166static struct i2c_driver lm78_driver = {
0c6e9731 167 .class = I2C_CLASS_HWMON,
cdaf7934 168 .driver = {
cdaf7934
LR
169 .name = "lm78",
170 },
0c6e9731
JD
171 .probe = lm78_i2c_probe,
172 .remove = lm78_i2c_remove,
173 .id_table = lm78_i2c_id,
174 .detect = lm78_i2c_detect,
c3813d6a 175 .address_list = normal_i2c,
1da177e4
LT
176};
177
c40769fe 178static struct platform_driver lm78_isa_driver = {
cdaf7934 179 .driver = {
87218842 180 .owner = THIS_MODULE,
c40769fe 181 .name = "lm78",
cdaf7934 182 },
c40769fe 183 .probe = lm78_isa_probe,
39d8bbed 184 .remove = __devexit_p(lm78_isa_remove),
fde09509
JD
185};
186
187
1da177e4 188/* 7 Voltages */
247dde4c
JD
189static ssize_t show_in(struct device *dev, struct device_attribute *da,
190 char *buf)
1da177e4 191{
247dde4c 192 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1da177e4 193 struct lm78_data *data = lm78_update_device(dev);
247dde4c 194 return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index]));
1da177e4
LT
195}
196
247dde4c
JD
197static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
198 char *buf)
1da177e4 199{
247dde4c 200 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1da177e4 201 struct lm78_data *data = lm78_update_device(dev);
247dde4c 202 return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index]));
1da177e4
LT
203}
204
247dde4c
JD
205static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
206 char *buf)
1da177e4 207{
247dde4c 208 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1da177e4 209 struct lm78_data *data = lm78_update_device(dev);
247dde4c 210 return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index]));
1da177e4
LT
211}
212
247dde4c
JD
213static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
214 const char *buf, size_t count)
1da177e4 215{
247dde4c 216 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
c40769fe 217 struct lm78_data *data = dev_get_drvdata(dev);
1da177e4 218 unsigned long val = simple_strtoul(buf, NULL, 10);
247dde4c 219 int nr = attr->index;
1da177e4 220
9a61bf63 221 mutex_lock(&data->update_lock);
1da177e4 222 data->in_min[nr] = IN_TO_REG(val);
c59cc301 223 lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]);
9a61bf63 224 mutex_unlock(&data->update_lock);
1da177e4
LT
225 return count;
226}
227
247dde4c
JD
228static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
229 const char *buf, size_t count)
1da177e4 230{
247dde4c 231 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
c40769fe 232 struct lm78_data *data = dev_get_drvdata(dev);
1da177e4 233 unsigned long val = simple_strtoul(buf, NULL, 10);
247dde4c 234 int nr = attr->index;
1da177e4 235
9a61bf63 236 mutex_lock(&data->update_lock);
1da177e4 237 data->in_max[nr] = IN_TO_REG(val);
c59cc301 238 lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]);
9a61bf63 239 mutex_unlock(&data->update_lock);
1da177e4
LT
240 return count;
241}
242
243#define show_in_offset(offset) \
247dde4c
JD
244static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
245 show_in, NULL, offset); \
246static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
247 show_in_min, set_in_min, offset); \
248static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
249 show_in_max, set_in_max, offset);
1da177e4
LT
250
251show_in_offset(0);
252show_in_offset(1);
253show_in_offset(2);
254show_in_offset(3);
255show_in_offset(4);
256show_in_offset(5);
257show_in_offset(6);
258
259/* Temperature */
247dde4c
JD
260static ssize_t show_temp(struct device *dev, struct device_attribute *da,
261 char *buf)
1da177e4
LT
262{
263 struct lm78_data *data = lm78_update_device(dev);
264 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
265}
266
247dde4c
JD
267static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
268 char *buf)
1da177e4
LT
269{
270 struct lm78_data *data = lm78_update_device(dev);
271 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
272}
273
247dde4c
JD
274static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
275 const char *buf, size_t count)
1da177e4 276{
c40769fe 277 struct lm78_data *data = dev_get_drvdata(dev);
1da177e4
LT
278 long val = simple_strtol(buf, NULL, 10);
279
9a61bf63 280 mutex_lock(&data->update_lock);
1da177e4 281 data->temp_over = TEMP_TO_REG(val);
c59cc301 282 lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over);
9a61bf63 283 mutex_unlock(&data->update_lock);
1da177e4
LT
284 return count;
285}
286
247dde4c
JD
287static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
288 char *buf)
1da177e4
LT
289{
290 struct lm78_data *data = lm78_update_device(dev);
291 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
292}
293
247dde4c
JD
294static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
295 const char *buf, size_t count)
1da177e4 296{
c40769fe 297 struct lm78_data *data = dev_get_drvdata(dev);
1da177e4
LT
298 long val = simple_strtol(buf, NULL, 10);
299
9a61bf63 300 mutex_lock(&data->update_lock);
1da177e4 301 data->temp_hyst = TEMP_TO_REG(val);
c59cc301 302 lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst);
9a61bf63 303 mutex_unlock(&data->update_lock);
1da177e4
LT
304 return count;
305}
306
307static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
308static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
309 show_temp_over, set_temp_over);
310static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
311 show_temp_hyst, set_temp_hyst);
312
313/* 3 Fans */
247dde4c
JD
314static ssize_t show_fan(struct device *dev, struct device_attribute *da,
315 char *buf)
1da177e4 316{
247dde4c 317 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1da177e4 318 struct lm78_data *data = lm78_update_device(dev);
247dde4c 319 int nr = attr->index;
1da177e4
LT
320 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
321 DIV_FROM_REG(data->fan_div[nr])) );
322}
323
247dde4c
JD
324static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
325 char *buf)
1da177e4 326{
247dde4c 327 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1da177e4 328 struct lm78_data *data = lm78_update_device(dev);
247dde4c 329 int nr = attr->index;
1da177e4
LT
330 return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
331 DIV_FROM_REG(data->fan_div[nr])) );
332}
333
247dde4c
JD
334static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
335 const char *buf, size_t count)
1da177e4 336{
247dde4c 337 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
c40769fe 338 struct lm78_data *data = dev_get_drvdata(dev);
247dde4c 339 int nr = attr->index;
1da177e4
LT
340 unsigned long val = simple_strtoul(buf, NULL, 10);
341
9a61bf63 342 mutex_lock(&data->update_lock);
1da177e4 343 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
c59cc301 344 lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
9a61bf63 345 mutex_unlock(&data->update_lock);
1da177e4
LT
346 return count;
347}
348
247dde4c
JD
349static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
350 char *buf)
1da177e4 351{
247dde4c 352 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1da177e4 353 struct lm78_data *data = lm78_update_device(dev);
247dde4c 354 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
1da177e4
LT
355}
356
357/* Note: we save and restore the fan minimum here, because its value is
358 determined in part by the fan divisor. This follows the principle of
d6e05edc 359 least surprise; the user doesn't expect the fan minimum to change just
1da177e4 360 because the divisor changed. */
247dde4c
JD
361static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
362 const char *buf, size_t count)
1da177e4 363{
247dde4c 364 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
c40769fe 365 struct lm78_data *data = dev_get_drvdata(dev);
247dde4c 366 int nr = attr->index;
1da177e4
LT
367 unsigned long val = simple_strtoul(buf, NULL, 10);
368 unsigned long min;
369 u8 reg;
370
9a61bf63 371 mutex_lock(&data->update_lock);
1da177e4
LT
372 min = FAN_FROM_REG(data->fan_min[nr],
373 DIV_FROM_REG(data->fan_div[nr]));
374
375 switch (val) {
376 case 1: data->fan_div[nr] = 0; break;
377 case 2: data->fan_div[nr] = 1; break;
378 case 4: data->fan_div[nr] = 2; break;
379 case 8: data->fan_div[nr] = 3; break;
380 default:
c40769fe 381 dev_err(dev, "fan_div value %ld not "
1da177e4 382 "supported. Choose one of 1, 2, 4 or 8!\n", val);
9a61bf63 383 mutex_unlock(&data->update_lock);
1da177e4
LT
384 return -EINVAL;
385 }
386
c59cc301 387 reg = lm78_read_value(data, LM78_REG_VID_FANDIV);
1da177e4
LT
388 switch (nr) {
389 case 0:
390 reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
391 break;
392 case 1:
393 reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
394 break;
395 }
c59cc301 396 lm78_write_value(data, LM78_REG_VID_FANDIV, reg);
1da177e4
LT
397
398 data->fan_min[nr] =
399 FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
c59cc301 400 lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
9a61bf63 401 mutex_unlock(&data->update_lock);
1da177e4
LT
402
403 return count;
404}
405
247dde4c
JD
406#define show_fan_offset(offset) \
407static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
408 show_fan, NULL, offset - 1); \
409static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
410 show_fan_min, set_fan_min, offset - 1);
1da177e4
LT
411
412show_fan_offset(1);
413show_fan_offset(2);
414show_fan_offset(3);
415
416/* Fan 3 divisor is locked in H/W */
247dde4c
JD
417static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
418 show_fan_div, set_fan_div, 0);
419static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
420 show_fan_div, set_fan_div, 1);
421static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2);
1da177e4
LT
422
423/* VID */
247dde4c
JD
424static ssize_t show_vid(struct device *dev, struct device_attribute *da,
425 char *buf)
1da177e4
LT
426{
427 struct lm78_data *data = lm78_update_device(dev);
d0d3cd69 428 return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82));
1da177e4
LT
429}
430static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
431
432/* Alarms */
247dde4c
JD
433static ssize_t show_alarms(struct device *dev, struct device_attribute *da,
434 char *buf)
1da177e4
LT
435{
436 struct lm78_data *data = lm78_update_device(dev);
437 return sprintf(buf, "%u\n", data->alarms);
438}
439static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
440
428a7039
JD
441static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
442 char *buf)
443{
444 struct lm78_data *data = lm78_update_device(dev);
445 int nr = to_sensor_dev_attr(da)->index;
446 return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
447}
448static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
449static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
450static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
451static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
452static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
453static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9);
454static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10);
455static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
456static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
457static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
458static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
459
c1685f61 460static struct attribute *lm78_attributes[] = {
247dde4c
JD
461 &sensor_dev_attr_in0_input.dev_attr.attr,
462 &sensor_dev_attr_in0_min.dev_attr.attr,
463 &sensor_dev_attr_in0_max.dev_attr.attr,
428a7039 464 &sensor_dev_attr_in0_alarm.dev_attr.attr,
247dde4c
JD
465 &sensor_dev_attr_in1_input.dev_attr.attr,
466 &sensor_dev_attr_in1_min.dev_attr.attr,
467 &sensor_dev_attr_in1_max.dev_attr.attr,
428a7039 468 &sensor_dev_attr_in1_alarm.dev_attr.attr,
247dde4c
JD
469 &sensor_dev_attr_in2_input.dev_attr.attr,
470 &sensor_dev_attr_in2_min.dev_attr.attr,
471 &sensor_dev_attr_in2_max.dev_attr.attr,
428a7039 472 &sensor_dev_attr_in2_alarm.dev_attr.attr,
247dde4c
JD
473 &sensor_dev_attr_in3_input.dev_attr.attr,
474 &sensor_dev_attr_in3_min.dev_attr.attr,
475 &sensor_dev_attr_in3_max.dev_attr.attr,
428a7039 476 &sensor_dev_attr_in3_alarm.dev_attr.attr,
247dde4c
JD
477 &sensor_dev_attr_in4_input.dev_attr.attr,
478 &sensor_dev_attr_in4_min.dev_attr.attr,
479 &sensor_dev_attr_in4_max.dev_attr.attr,
428a7039 480 &sensor_dev_attr_in4_alarm.dev_attr.attr,
247dde4c
JD
481 &sensor_dev_attr_in5_input.dev_attr.attr,
482 &sensor_dev_attr_in5_min.dev_attr.attr,
483 &sensor_dev_attr_in5_max.dev_attr.attr,
428a7039 484 &sensor_dev_attr_in5_alarm.dev_attr.attr,
247dde4c
JD
485 &sensor_dev_attr_in6_input.dev_attr.attr,
486 &sensor_dev_attr_in6_min.dev_attr.attr,
487 &sensor_dev_attr_in6_max.dev_attr.attr,
428a7039 488 &sensor_dev_attr_in6_alarm.dev_attr.attr,
c1685f61
MH
489 &dev_attr_temp1_input.attr,
490 &dev_attr_temp1_max.attr,
491 &dev_attr_temp1_max_hyst.attr,
428a7039 492 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
247dde4c
JD
493 &sensor_dev_attr_fan1_input.dev_attr.attr,
494 &sensor_dev_attr_fan1_min.dev_attr.attr,
495 &sensor_dev_attr_fan1_div.dev_attr.attr,
428a7039 496 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
247dde4c
JD
497 &sensor_dev_attr_fan2_input.dev_attr.attr,
498 &sensor_dev_attr_fan2_min.dev_attr.attr,
499 &sensor_dev_attr_fan2_div.dev_attr.attr,
428a7039 500 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
247dde4c
JD
501 &sensor_dev_attr_fan3_input.dev_attr.attr,
502 &sensor_dev_attr_fan3_min.dev_attr.attr,
503 &sensor_dev_attr_fan3_div.dev_attr.attr,
428a7039 504 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
c1685f61
MH
505 &dev_attr_alarms.attr,
506 &dev_attr_cpu0_vid.attr,
507
508 NULL
509};
510
511static const struct attribute_group lm78_group = {
512 .attrs = lm78_attributes,
513};
514
c40769fe
JD
515/* I2C devices get this name attribute automatically, but for ISA devices
516 we must create it by ourselves. */
517static ssize_t show_name(struct device *dev, struct device_attribute
518 *devattr, char *buf)
519{
520 struct lm78_data *data = dev_get_drvdata(dev);
521
6e1b5029 522 return sprintf(buf, "%s\n", data->name);
c40769fe
JD
523}
524static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
525
18c73f90
JD
526/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
527static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
528{
0c6e9731 529 struct lm78_data *isa;
18c73f90
JD
530 int i;
531
532 if (!pdev) /* No ISA chip */
533 return 0;
18c73f90
JD
534 isa = platform_get_drvdata(pdev);
535
536 if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr)
537 return 0; /* Address doesn't match */
538 if ((lm78_read_value(isa, LM78_REG_CHIPID) & 0xfe) != (chipid & 0xfe))
539 return 0; /* Chip type doesn't match */
540
541 /* We compare all the limit registers, the config register and the
542 * interrupt mask registers */
543 for (i = 0x2b; i <= 0x3d; i++) {
0c6e9731
JD
544 if (lm78_read_value(isa, i) !=
545 i2c_smbus_read_byte_data(client, i))
18c73f90
JD
546 return 0;
547 }
548 if (lm78_read_value(isa, LM78_REG_CONFIG) !=
0c6e9731 549 i2c_smbus_read_byte_data(client, LM78_REG_CONFIG))
18c73f90
JD
550 return 0;
551 for (i = 0x43; i <= 0x46; i++) {
0c6e9731
JD
552 if (lm78_read_value(isa, i) !=
553 i2c_smbus_read_byte_data(client, i))
18c73f90
JD
554 return 0;
555 }
556
557 return 1;
558}
559
310ec792 560static int lm78_i2c_detect(struct i2c_client *client,
0c6e9731 561 struct i2c_board_info *info)
1da177e4 562{
0c6e9731
JD
563 int i;
564 struct lm78_data *isa = pdev ? platform_get_drvdata(pdev) : NULL;
565 const char *client_name;
566 struct i2c_adapter *adapter = client->adapter;
567 int address = client->addr;
1da177e4 568
0c6e9731
JD
569 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
570 return -ENODEV;
1da177e4 571
0c6e9731
JD
572 /* We block updates of the ISA device to minimize the risk of
573 concurrent access to the same LM78 chip through different
574 interfaces. */
575 if (isa)
576 mutex_lock(&isa->update_lock);
1da177e4 577
52df6440
JD
578 if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
579 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) != address)
580 goto err_nodev;
581
582 /* Explicitly prevent the misdetection of Winbond chips */
583 i = i2c_smbus_read_byte_data(client, 0x4f);
584 if (i == 0xa3 || i == 0x5c)
585 goto err_nodev;
1da177e4
LT
586
587 /* Determine the chip type. */
52df6440
JD
588 i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
589 if (i == 0x00 || i == 0x20 /* LM78 */
590 || i == 0x40) /* LM78-J */
591 client_name = "lm78";
592 else if ((i & 0xfe) == 0xc0)
593 client_name = "lm79";
594 else
595 goto err_nodev;
596
597 if (lm78_alias_detect(client, i)) {
598 dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
599 "be the same as ISA device\n", address);
600 goto err_nodev;
1da177e4
LT
601 }
602
0c6e9731
JD
603 if (isa)
604 mutex_unlock(&isa->update_lock);
605
0c6e9731 606 strlcpy(info->type, client_name, I2C_NAME_SIZE);
1da177e4 607
0c6e9731 608 return 0;
1da177e4 609
0c6e9731
JD
610 err_nodev:
611 if (isa)
612 mutex_unlock(&isa->update_lock);
613 return -ENODEV;
614}
615
616static int lm78_i2c_probe(struct i2c_client *client,
617 const struct i2c_device_id *id)
618{
619 struct lm78_data *data;
620 int err;
621
622 data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
623 if (!data)
624 return -ENOMEM;
625
626 i2c_set_clientdata(client, data);
627 data->client = client;
628 data->type = id->driver_data;
1da177e4
LT
629
630 /* Initialize the LM78 chip */
c59cc301 631 lm78_init_device(data);
1da177e4 632
1da177e4 633 /* Register sysfs hooks */
0c6e9731
JD
634 err = sysfs_create_group(&client->dev.kobj, &lm78_group);
635 if (err)
c1685f61
MH
636 goto ERROR3;
637
0c6e9731 638 data->hwmon_dev = hwmon_device_register(&client->dev);
1beeffe4
TJ
639 if (IS_ERR(data->hwmon_dev)) {
640 err = PTR_ERR(data->hwmon_dev);
c1685f61 641 goto ERROR4;
943b0830
MH
642 }
643
1da177e4
LT
644 return 0;
645
c1685f61 646ERROR4:
0c6e9731 647 sysfs_remove_group(&client->dev.kobj, &lm78_group);
943b0830 648ERROR3:
1da177e4 649 kfree(data);
1da177e4
LT
650 return err;
651}
652
0c6e9731 653static int lm78_i2c_remove(struct i2c_client *client)
1da177e4 654{
943b0830 655 struct lm78_data *data = i2c_get_clientdata(client);
1da177e4 656
1beeffe4 657 hwmon_device_unregister(data->hwmon_dev);
c1685f61 658 sysfs_remove_group(&client->dev.kobj, &lm78_group);
c40769fe
JD
659 kfree(data);
660
661 return 0;
662}
663
664static int __devinit lm78_isa_probe(struct platform_device *pdev)
665{
666 int err;
667 struct lm78_data *data;
668 struct resource *res;
c40769fe
JD
669
670 /* Reserve the ISA region */
671 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
47c15532 672 if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
c40769fe
JD
673 err = -EBUSY;
674 goto exit;
675 }
676
677 if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
678 err = -ENOMEM;
679 goto exit_release_region;
680 }
681 mutex_init(&data->lock);
6e1b5029 682 data->isa_addr = res->start;
c40769fe
JD
683 platform_set_drvdata(pdev, data);
684
c59cc301 685 if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
c40769fe 686 data->type = lm79;
6e1b5029 687 data->name = "lm79";
c40769fe
JD
688 } else {
689 data->type = lm78;
6e1b5029 690 data->name = "lm78";
c40769fe 691 }
c40769fe
JD
692
693 /* Initialize the LM78 chip */
c59cc301 694 lm78_init_device(data);
c40769fe
JD
695
696 /* Register sysfs hooks */
697 if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
698 || (err = device_create_file(&pdev->dev, &dev_attr_name)))
699 goto exit_remove_files;
700
1beeffe4
TJ
701 data->hwmon_dev = hwmon_device_register(&pdev->dev);
702 if (IS_ERR(data->hwmon_dev)) {
703 err = PTR_ERR(data->hwmon_dev);
c40769fe
JD
704 goto exit_remove_files;
705 }
706
707 return 0;
708
709 exit_remove_files:
710 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
711 device_remove_file(&pdev->dev, &dev_attr_name);
712 kfree(data);
713 exit_release_region:
47c15532 714 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
c40769fe
JD
715 exit:
716 return err;
717}
718
719static int __devexit lm78_isa_remove(struct platform_device *pdev)
720{
721 struct lm78_data *data = platform_get_drvdata(pdev);
6e1b5029 722 struct resource *res;
1da177e4 723
1beeffe4 724 hwmon_device_unregister(data->hwmon_dev);
c40769fe
JD
725 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
726 device_remove_file(&pdev->dev, &dev_attr_name);
943b0830 727 kfree(data);
1da177e4 728
6e1b5029
JD
729 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
730 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
731
1da177e4
LT
732 return 0;
733}
734
44bbe87e 735/* The SMBus locks itself, but ISA access must be locked explicitly!
1da177e4
LT
736 We don't want to lock the whole ISA bus, so we lock each client
737 separately.
738 We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
739 would slow down the LM78 access and should not be necessary. */
c59cc301 740static int lm78_read_value(struct lm78_data *data, u8 reg)
1da177e4 741{
0c6e9731 742 struct i2c_client *client = data->client;
c59cc301 743
0c6e9731 744 if (!client) { /* ISA device */
c59cc301 745 int res;
9a61bf63 746 mutex_lock(&data->lock);
6e1b5029
JD
747 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
748 res = inb_p(data->isa_addr + LM78_DATA_REG_OFFSET);
9a61bf63 749 mutex_unlock(&data->lock);
1da177e4
LT
750 return res;
751 } else
752 return i2c_smbus_read_byte_data(client, reg);
753}
754
44bbe87e 755/* The SMBus locks itself, but ISA access muse be locked explicitly!
1da177e4
LT
756 We don't want to lock the whole ISA bus, so we lock each client
757 separately.
758 We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
759 would slow down the LM78 access and should not be necessary.
760 There are some ugly typecasts here, but the good new is - they should
761 nowhere else be necessary! */
c59cc301 762static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
1da177e4 763{
0c6e9731 764 struct i2c_client *client = data->client;
c59cc301 765
0c6e9731 766 if (!client) { /* ISA device */
9a61bf63 767 mutex_lock(&data->lock);
6e1b5029
JD
768 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
769 outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET);
9a61bf63 770 mutex_unlock(&data->lock);
1da177e4
LT
771 return 0;
772 } else
773 return i2c_smbus_write_byte_data(client, reg, value);
774}
775
c59cc301 776static void lm78_init_device(struct lm78_data *data)
1da177e4 777{
c40769fe
JD
778 u8 config;
779 int i;
1da177e4
LT
780
781 /* Start monitoring */
c59cc301 782 config = lm78_read_value(data, LM78_REG_CONFIG);
c40769fe 783 if ((config & 0x09) != 0x01)
c59cc301 784 lm78_write_value(data, LM78_REG_CONFIG,
1da177e4 785 (config & 0xf7) | 0x01);
c40769fe
JD
786
787 /* A few vars need to be filled upon startup */
788 for (i = 0; i < 3; i++) {
c59cc301 789 data->fan_min[i] = lm78_read_value(data,
c40769fe
JD
790 LM78_REG_FAN_MIN(i));
791 }
792
793 mutex_init(&data->update_lock);
1da177e4
LT
794}
795
796static struct lm78_data *lm78_update_device(struct device *dev)
797{
c40769fe 798 struct lm78_data *data = dev_get_drvdata(dev);
1da177e4
LT
799 int i;
800
9a61bf63 801 mutex_lock(&data->update_lock);
1da177e4
LT
802
803 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
804 || !data->valid) {
805
c40769fe 806 dev_dbg(dev, "Starting lm78 update\n");
1da177e4
LT
807
808 for (i = 0; i <= 6; i++) {
809 data->in[i] =
c59cc301 810 lm78_read_value(data, LM78_REG_IN(i));
1da177e4 811 data->in_min[i] =
c59cc301 812 lm78_read_value(data, LM78_REG_IN_MIN(i));
1da177e4 813 data->in_max[i] =
c59cc301 814 lm78_read_value(data, LM78_REG_IN_MAX(i));
1da177e4
LT
815 }
816 for (i = 0; i < 3; i++) {
817 data->fan[i] =
c59cc301 818 lm78_read_value(data, LM78_REG_FAN(i));
1da177e4 819 data->fan_min[i] =
c59cc301 820 lm78_read_value(data, LM78_REG_FAN_MIN(i));
1da177e4 821 }
c59cc301 822 data->temp = lm78_read_value(data, LM78_REG_TEMP);
1da177e4 823 data->temp_over =
c59cc301 824 lm78_read_value(data, LM78_REG_TEMP_OVER);
1da177e4 825 data->temp_hyst =
c59cc301
JD
826 lm78_read_value(data, LM78_REG_TEMP_HYST);
827 i = lm78_read_value(data, LM78_REG_VID_FANDIV);
1da177e4
LT
828 data->vid = i & 0x0f;
829 if (data->type == lm79)
830 data->vid |=
c59cc301 831 (lm78_read_value(data, LM78_REG_CHIPID) &
1da177e4
LT
832 0x01) << 4;
833 else
834 data->vid |= 0x10;
835 data->fan_div[0] = (i >> 4) & 0x03;
836 data->fan_div[1] = i >> 6;
c59cc301
JD
837 data->alarms = lm78_read_value(data, LM78_REG_ALARM1) +
838 (lm78_read_value(data, LM78_REG_ALARM2) << 8);
1da177e4
LT
839 data->last_updated = jiffies;
840 data->valid = 1;
841
842 data->fan_div[2] = 1;
843 }
844
9a61bf63 845 mutex_unlock(&data->update_lock);
1da177e4
LT
846
847 return data;
848}
849
c40769fe
JD
850/* return 1 if a supported chip is found, 0 otherwise */
851static int __init lm78_isa_found(unsigned short address)
852{
853 int val, save, found = 0;
197027e6
JD
854 int port;
855
856 /* Some boards declare base+0 to base+7 as a PNP device, some base+4
857 * to base+7 and some base+5 to base+6. So we better request each port
858 * individually for the probing phase. */
859 for (port = address; port < address + LM78_EXTENT; port++) {
860 if (!request_region(port, 1, "lm78")) {
861 pr_debug("lm78: Failed to request port 0x%x\n", port);
862 goto release;
863 }
47c15532 864 }
c40769fe
JD
865
866#define REALLY_SLOW_IO
867 /* We need the timeouts for at least some LM78-like
868 chips. But only if we read 'undefined' registers. */
869 val = inb_p(address + 1);
870 if (inb_p(address + 2) != val
871 || inb_p(address + 3) != val
872 || inb_p(address + 7) != val)
873 goto release;
874#undef REALLY_SLOW_IO
875
876 /* We should be able to change the 7 LSB of the address port. The
877 MSB (busy flag) should be clear initially, set after the write. */
878 save = inb_p(address + LM78_ADDR_REG_OFFSET);
879 if (save & 0x80)
880 goto release;
881 val = ~save & 0x7f;
882 outb_p(val, address + LM78_ADDR_REG_OFFSET);
883 if (inb_p(address + LM78_ADDR_REG_OFFSET) != (val | 0x80)) {
884 outb_p(save, address + LM78_ADDR_REG_OFFSET);
885 goto release;
886 }
887
888 /* We found a device, now see if it could be an LM78 */
889 outb_p(LM78_REG_CONFIG, address + LM78_ADDR_REG_OFFSET);
890 val = inb_p(address + LM78_DATA_REG_OFFSET);
891 if (val & 0x80)
892 goto release;
893 outb_p(LM78_REG_I2C_ADDR, address + LM78_ADDR_REG_OFFSET);
894 val = inb_p(address + LM78_DATA_REG_OFFSET);
895 if (val < 0x03 || val > 0x77) /* Not a valid I2C address */
896 goto release;
897
898 /* The busy flag should be clear again */
899 if (inb_p(address + LM78_ADDR_REG_OFFSET) & 0x80)
900 goto release;
901
902 /* Explicitly prevent the misdetection of Winbond chips */
903 outb_p(0x4f, address + LM78_ADDR_REG_OFFSET);
904 val = inb_p(address + LM78_DATA_REG_OFFSET);
905 if (val == 0xa3 || val == 0x5c)
906 goto release;
907
908 /* Explicitly prevent the misdetection of ITE chips */
909 outb_p(0x58, address + LM78_ADDR_REG_OFFSET);
910 val = inb_p(address + LM78_DATA_REG_OFFSET);
911 if (val == 0x90)
912 goto release;
913
914 /* Determine the chip type */
915 outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET);
916 val = inb_p(address + LM78_DATA_REG_OFFSET);
acf346a3 917 if (val == 0x00 || val == 0x20 /* LM78 */
c40769fe
JD
918 || val == 0x40 /* LM78-J */
919 || (val & 0xfe) == 0xc0) /* LM79 */
920 found = 1;
921
922 if (found)
923 pr_info("lm78: Found an %s chip at %#x\n",
924 val & 0x80 ? "LM79" : "LM78", (int)address);
925
926 release:
197027e6
JD
927 for (port--; port >= address; port--)
928 release_region(port, 1);
c40769fe
JD
929 return found;
930}
931
932static int __init lm78_isa_device_add(unsigned short address)
933{
934 struct resource res = {
935 .start = address,
15bde2f1 936 .end = address + LM78_EXTENT - 1,
c40769fe
JD
937 .name = "lm78",
938 .flags = IORESOURCE_IO,
939 };
940 int err;
941
942 pdev = platform_device_alloc("lm78", address);
943 if (!pdev) {
944 err = -ENOMEM;
945 printk(KERN_ERR "lm78: Device allocation failed\n");
946 goto exit;
947 }
948
949 err = platform_device_add_resources(pdev, &res, 1);
950 if (err) {
951 printk(KERN_ERR "lm78: Device resource addition failed "
952 "(%d)\n", err);
953 goto exit_device_put;
954 }
955
956 err = platform_device_add(pdev);
957 if (err) {
958 printk(KERN_ERR "lm78: Device addition failed (%d)\n",
959 err);
960 goto exit_device_put;
961 }
962
963 return 0;
964
965 exit_device_put:
966 platform_device_put(pdev);
967 exit:
968 pdev = NULL;
969 return err;
970}
971
1da177e4
LT
972static int __init sm_lm78_init(void)
973{
fde09509
JD
974 int res;
975
18c73f90
JD
976 /* We register the ISA device first, so that we can skip the
977 * registration of an I2C interface to the same device. */
c40769fe
JD
978 if (lm78_isa_found(isa_address)) {
979 res = platform_driver_register(&lm78_isa_driver);
980 if (res)
18c73f90 981 goto exit;
fde09509 982
c40769fe
JD
983 /* Sets global pdev as a side effect */
984 res = lm78_isa_device_add(isa_address);
985 if (res)
986 goto exit_unreg_isa_driver;
987 }
fde09509 988
18c73f90
JD
989 res = i2c_add_driver(&lm78_driver);
990 if (res)
991 goto exit_unreg_isa_device;
992
fde09509 993 return 0;
c40769fe 994
18c73f90
JD
995 exit_unreg_isa_device:
996 platform_device_unregister(pdev);
c40769fe
JD
997 exit_unreg_isa_driver:
998 platform_driver_unregister(&lm78_isa_driver);
c40769fe
JD
999 exit:
1000 return res;
1da177e4
LT
1001}
1002
1003static void __exit sm_lm78_exit(void)
1004{
c40769fe
JD
1005 if (pdev) {
1006 platform_device_unregister(pdev);
1007 platform_driver_unregister(&lm78_isa_driver);
1008 }
1da177e4
LT
1009 i2c_del_driver(&lm78_driver);
1010}
1011
1012
1013
1014MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
27fe048e 1015MODULE_DESCRIPTION("LM78/LM79 driver");
1da177e4
LT
1016MODULE_LICENSE("GPL");
1017
1018module_init(sm_lm78_init);
1019module_exit(sm_lm78_exit);