lm78.c 28.7 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * lm78.c - Part of lm_sensors, Linux kernel modules for hardware
 *	    monitoring
 * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
 * Copyright (c) 2007, 2011  Jean Delvare <khali@linux-fr.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
L
Linus Torvalds 已提交
21

22 23
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

L
Linus Torvalds 已提交
24 25 26 27 28
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
29
#include <linux/hwmon.h>
30
#include <linux/hwmon-vid.h>
31
#include <linux/hwmon-sysfs.h>
32
#include <linux/err.h>
33
#include <linux/mutex.h>
L
Linus Torvalds 已提交
34

35 36 37 38 39
#ifdef CONFIG_ISA
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#endif
J
Jean Delvare 已提交
40

L
Linus Torvalds 已提交
41
/* Addresses to scan */
42 43
static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
						0x2e, 0x2f, I2C_CLIENT_END };
J
Jean Delvare 已提交
44
enum chips { lm78, lm79 };
L
Linus Torvalds 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

/* Many LM78 constants specified below */

/* Length of ISA address segment */
#define LM78_EXTENT 8

/* Where are the ISA address/data registers relative to the base address */
#define LM78_ADDR_REG_OFFSET 5
#define LM78_DATA_REG_OFFSET 6

/* The LM78 registers */
#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
#define LM78_REG_IN(nr) (0x20 + (nr))

#define LM78_REG_FAN_MIN(nr) (0x3b + (nr))
#define LM78_REG_FAN(nr) (0x28 + (nr))

#define LM78_REG_TEMP 0x27
#define LM78_REG_TEMP_OVER 0x39
#define LM78_REG_TEMP_HYST 0x3a

#define LM78_REG_ALARM1 0x41
#define LM78_REG_ALARM2 0x42

#define LM78_REG_VID_FANDIV 0x47

#define LM78_REG_CONFIG 0x40
#define LM78_REG_CHIPID 0x49
#define LM78_REG_I2C_ADDR 0x48


77 78 79 80
/*
 * Conversions. Rounding and limit checking is only done on the TO_REG
 * variants.
 */
L
Linus Torvalds 已提交
81

82 83 84 85
/*
 * IN: mV (0V to 4.08V)
 * REG: 16mV/bit
 */
L
Linus Torvalds 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
static inline u8 IN_TO_REG(unsigned long val)
{
	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
	return (nval + 8) / 16;
}
#define IN_FROM_REG(val) ((val) *  16)

static inline u8 FAN_TO_REG(long rpm, int div)
{
	if (rpm <= 0)
		return 255;
	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
}

static inline int FAN_FROM_REG(u8 val, int div)
{
102
	return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div);
L
Linus Torvalds 已提交
103 104
}

105 106 107 108
/*
 * TEMP: mC (-128C to +127C)
 * REG: 1C/bit, two's complement
 */
L
Linus Torvalds 已提交
109 110 111
static inline s8 TEMP_TO_REG(int val)
{
	int nval = SENSORS_LIMIT(val, -128000, 127000) ;
112
	return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000;
L
Linus Torvalds 已提交
113 114 115 116 117 118 119 120 121 122
}

static inline int TEMP_FROM_REG(s8 val)
{
	return val * 1000;
}

#define DIV_FROM_REG(val) (1 << (val))

struct lm78_data {
123
	struct i2c_client *client;
124
	struct device *hwmon_dev;
125
	struct mutex lock;
L
Linus Torvalds 已提交
126 127
	enum chips type;

128 129 130 131
	/* For ISA device only */
	const char *name;
	int isa_addr;

132
	struct mutex update_lock;
L
Linus Torvalds 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	char valid;		/* !=0 if following fields are valid */
	unsigned long last_updated;	/* In jiffies */

	u8 in[7];		/* Register value */
	u8 in_max[7];		/* Register value */
	u8 in_min[7];		/* Register value */
	u8 fan[3];		/* Register value */
	u8 fan_min[3];		/* Register value */
	s8 temp;		/* Register value */
	s8 temp_over;		/* Register value */
	s8 temp_hyst;		/* Register value */
	u8 fan_div[3];		/* Register encoding, shifted right */
	u8 vid;			/* Register encoding, combined */
	u16 alarms;		/* Register encoding, combined */
};


150 151
static int lm78_read_value(struct lm78_data *data, u8 reg);
static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
L
Linus Torvalds 已提交
152
static struct lm78_data *lm78_update_device(struct device *dev);
153
static void lm78_init_device(struct lm78_data *data);
L
Linus Torvalds 已提交
154 155 156


/* 7 Voltages */
157 158
static ssize_t show_in(struct device *dev, struct device_attribute *da,
		       char *buf)
L
Linus Torvalds 已提交
159
{
160
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
L
Linus Torvalds 已提交
161
	struct lm78_data *data = lm78_update_device(dev);
162
	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index]));
L
Linus Torvalds 已提交
163 164
}

165 166
static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
			   char *buf)
L
Linus Torvalds 已提交
167
{
168
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
L
Linus Torvalds 已提交
169
	struct lm78_data *data = lm78_update_device(dev);
170
	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index]));
L
Linus Torvalds 已提交
171 172
}

173 174
static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
			   char *buf)
L
Linus Torvalds 已提交
175
{
176
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
L
Linus Torvalds 已提交
177
	struct lm78_data *data = lm78_update_device(dev);
178
	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index]));
L
Linus Torvalds 已提交
179 180
}

181 182
static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
			  const char *buf, size_t count)
L
Linus Torvalds 已提交
183
{
184
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
J
Jean Delvare 已提交
185
	struct lm78_data *data = dev_get_drvdata(dev);
186
	int nr = attr->index;
187 188 189 190 191 192
	unsigned long val;
	int err;

	err = kstrtoul(buf, 10, &val);
	if (err)
		return err;
L
Linus Torvalds 已提交
193

194
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
195
	data->in_min[nr] = IN_TO_REG(val);
196
	lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]);
197
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
198 199 200
	return count;
}

201 202
static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
			  const char *buf, size_t count)
L
Linus Torvalds 已提交
203
{
204
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
J
Jean Delvare 已提交
205
	struct lm78_data *data = dev_get_drvdata(dev);
206
	int nr = attr->index;
207 208 209 210 211 212
	unsigned long val;
	int err;

	err = kstrtoul(buf, 10, &val);
	if (err)
		return err;
L
Linus Torvalds 已提交
213

214
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
215
	data->in_max[nr] = IN_TO_REG(val);
216
	lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]);
217
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
218 219
	return count;
}
220

L
Linus Torvalds 已提交
221
#define show_in_offset(offset)					\
222 223 224 225 226 227
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
		show_in, NULL, offset);				\
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
		show_in_min, set_in_min, offset);		\
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
		show_in_max, set_in_max, offset);
L
Linus Torvalds 已提交
228 229 230 231 232 233 234 235 236 237

show_in_offset(0);
show_in_offset(1);
show_in_offset(2);
show_in_offset(3);
show_in_offset(4);
show_in_offset(5);
show_in_offset(6);

/* Temperature */
238 239
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
			 char *buf)
L
Linus Torvalds 已提交
240 241 242 243 244
{
	struct lm78_data *data = lm78_update_device(dev);
	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
}

245 246
static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
			      char *buf)
L
Linus Torvalds 已提交
247 248 249 250 251
{
	struct lm78_data *data = lm78_update_device(dev);
	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}

252 253
static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
			     const char *buf, size_t count)
L
Linus Torvalds 已提交
254
{
J
Jean Delvare 已提交
255
	struct lm78_data *data = dev_get_drvdata(dev);
256 257 258 259 260 261
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
L
Linus Torvalds 已提交
262

263
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
264
	data->temp_over = TEMP_TO_REG(val);
265
	lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over);
266
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
267 268 269
	return count;
}

270 271
static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
			      char *buf)
L
Linus Torvalds 已提交
272 273 274 275 276
{
	struct lm78_data *data = lm78_update_device(dev);
	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
}

277 278
static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
			     const char *buf, size_t count)
L
Linus Torvalds 已提交
279
{
J
Jean Delvare 已提交
280
	struct lm78_data *data = dev_get_drvdata(dev);
281 282 283 284 285 286
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err)
		return err;
L
Linus Torvalds 已提交
287

288
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
289
	data->temp_hyst = TEMP_TO_REG(val);
290
	lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst);
291
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
292 293 294 295 296 297 298 299 300 301
	return count;
}

static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
		show_temp_over, set_temp_over);
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
		show_temp_hyst, set_temp_hyst);

/* 3 Fans */
302 303
static ssize_t show_fan(struct device *dev, struct device_attribute *da,
			char *buf)
L
Linus Torvalds 已提交
304
{
305
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
L
Linus Torvalds 已提交
306
	struct lm78_data *data = lm78_update_device(dev);
307
	int nr = attr->index;
L
Linus Torvalds 已提交
308
	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
309
		DIV_FROM_REG(data->fan_div[nr])));
L
Linus Torvalds 已提交
310 311
}

312 313
static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
			    char *buf)
L
Linus Torvalds 已提交
314
{
315
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
L
Linus Torvalds 已提交
316
	struct lm78_data *data = lm78_update_device(dev);
317
	int nr = attr->index;
318 319
	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
		DIV_FROM_REG(data->fan_div[nr])));
L
Linus Torvalds 已提交
320 321
}

322 323
static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
			   const char *buf, size_t count)
L
Linus Torvalds 已提交
324
{
325
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
J
Jean Delvare 已提交
326
	struct lm78_data *data = dev_get_drvdata(dev);
327
	int nr = attr->index;
328 329 330 331 332 333
	unsigned long val;
	int err;

	err = kstrtoul(buf, 10, &val);
	if (err)
		return err;
L
Linus Torvalds 已提交
334

335
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
336
	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
337
	lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
338
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
339 340 341
	return count;
}

342 343
static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
			    char *buf)
L
Linus Torvalds 已提交
344
{
345
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
L
Linus Torvalds 已提交
346
	struct lm78_data *data = lm78_update_device(dev);
347
	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
L
Linus Torvalds 已提交
348 349
}

350 351 352 353 354 355
/*
 * Note: we save and restore the fan minimum here, because its value is
 * determined in part by the fan divisor.  This follows the principle of
 * least surprise; the user doesn't expect the fan minimum to change just
 * because the divisor changed.
 */
356 357
static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
			   const char *buf, size_t count)
L
Linus Torvalds 已提交
358
{
359
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
J
Jean Delvare 已提交
360
	struct lm78_data *data = dev_get_drvdata(dev);
361
	int nr = attr->index;
L
Linus Torvalds 已提交
362 363
	unsigned long min;
	u8 reg;
364 365 366 367 368 369
	unsigned long val;
	int err;

	err = kstrtoul(buf, 10, &val);
	if (err)
		return err;
L
Linus Torvalds 已提交
370

371
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
372 373 374 375
	min = FAN_FROM_REG(data->fan_min[nr],
			   DIV_FROM_REG(data->fan_div[nr]));

	switch (val) {
376 377 378 379 380 381 382 383 384 385 386 387
	case 1:
		data->fan_div[nr] = 0;
		break;
	case 2:
		data->fan_div[nr] = 1;
		break;
	case 4:
		data->fan_div[nr] = 2;
		break;
	case 8:
		data->fan_div[nr] = 3;
		break;
L
Linus Torvalds 已提交
388
	default:
J
Jean Delvare 已提交
389
		dev_err(dev, "fan_div value %ld not "
L
Linus Torvalds 已提交
390
			"supported. Choose one of 1, 2, 4 or 8!\n", val);
391
		mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
392 393 394
		return -EINVAL;
	}

395
	reg = lm78_read_value(data, LM78_REG_VID_FANDIV);
L
Linus Torvalds 已提交
396 397 398 399 400 401 402 403
	switch (nr) {
	case 0:
		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
		break;
	case 1:
		reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
		break;
	}
404
	lm78_write_value(data, LM78_REG_VID_FANDIV, reg);
L
Linus Torvalds 已提交
405 406 407

	data->fan_min[nr] =
		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
408
	lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
409
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
410 411 412 413

	return count;
}

414 415 416 417 418
#define show_fan_offset(offset)				\
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,		\
		show_fan, NULL, offset - 1);			\
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,	\
		show_fan_min, set_fan_min, offset - 1);
L
Linus Torvalds 已提交
419 420 421 422 423 424

show_fan_offset(1);
show_fan_offset(2);
show_fan_offset(3);

/* Fan 3 divisor is locked in H/W */
425 426 427 428 429
static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
		show_fan_div, set_fan_div, 0);
static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
		show_fan_div, set_fan_div, 1);
static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2);
L
Linus Torvalds 已提交
430 431

/* VID */
432 433
static ssize_t show_vid(struct device *dev, struct device_attribute *da,
			char *buf)
L
Linus Torvalds 已提交
434 435
{
	struct lm78_data *data = lm78_update_device(dev);
436
	return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82));
L
Linus Torvalds 已提交
437 438 439 440
}
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);

/* Alarms */
441 442
static ssize_t show_alarms(struct device *dev, struct device_attribute *da,
			   char *buf)
L
Linus Torvalds 已提交
443 444 445 446 447 448
{
	struct lm78_data *data = lm78_update_device(dev);
	return sprintf(buf, "%u\n", data->alarms);
}
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
			  char *buf)
{
	struct lm78_data *data = lm78_update_device(dev);
	int nr = to_sensor_dev_attr(da)->index;
	return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
}
static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9);
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10);
static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);

468
static struct attribute *lm78_attributes[] = {
469 470 471
	&sensor_dev_attr_in0_input.dev_attr.attr,
	&sensor_dev_attr_in0_min.dev_attr.attr,
	&sensor_dev_attr_in0_max.dev_attr.attr,
472
	&sensor_dev_attr_in0_alarm.dev_attr.attr,
473 474 475
	&sensor_dev_attr_in1_input.dev_attr.attr,
	&sensor_dev_attr_in1_min.dev_attr.attr,
	&sensor_dev_attr_in1_max.dev_attr.attr,
476
	&sensor_dev_attr_in1_alarm.dev_attr.attr,
477 478 479
	&sensor_dev_attr_in2_input.dev_attr.attr,
	&sensor_dev_attr_in2_min.dev_attr.attr,
	&sensor_dev_attr_in2_max.dev_attr.attr,
480
	&sensor_dev_attr_in2_alarm.dev_attr.attr,
481 482 483
	&sensor_dev_attr_in3_input.dev_attr.attr,
	&sensor_dev_attr_in3_min.dev_attr.attr,
	&sensor_dev_attr_in3_max.dev_attr.attr,
484
	&sensor_dev_attr_in3_alarm.dev_attr.attr,
485 486 487
	&sensor_dev_attr_in4_input.dev_attr.attr,
	&sensor_dev_attr_in4_min.dev_attr.attr,
	&sensor_dev_attr_in4_max.dev_attr.attr,
488
	&sensor_dev_attr_in4_alarm.dev_attr.attr,
489 490 491
	&sensor_dev_attr_in5_input.dev_attr.attr,
	&sensor_dev_attr_in5_min.dev_attr.attr,
	&sensor_dev_attr_in5_max.dev_attr.attr,
492
	&sensor_dev_attr_in5_alarm.dev_attr.attr,
493 494 495
	&sensor_dev_attr_in6_input.dev_attr.attr,
	&sensor_dev_attr_in6_min.dev_attr.attr,
	&sensor_dev_attr_in6_max.dev_attr.attr,
496
	&sensor_dev_attr_in6_alarm.dev_attr.attr,
497 498 499
	&dev_attr_temp1_input.attr,
	&dev_attr_temp1_max.attr,
	&dev_attr_temp1_max_hyst.attr,
500
	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
501 502 503
	&sensor_dev_attr_fan1_input.dev_attr.attr,
	&sensor_dev_attr_fan1_min.dev_attr.attr,
	&sensor_dev_attr_fan1_div.dev_attr.attr,
504
	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
505 506 507
	&sensor_dev_attr_fan2_input.dev_attr.attr,
	&sensor_dev_attr_fan2_min.dev_attr.attr,
	&sensor_dev_attr_fan2_div.dev_attr.attr,
508
	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
509 510 511
	&sensor_dev_attr_fan3_input.dev_attr.attr,
	&sensor_dev_attr_fan3_min.dev_attr.attr,
	&sensor_dev_attr_fan3_div.dev_attr.attr,
512
	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
513 514 515 516 517 518 519 520 521 522
	&dev_attr_alarms.attr,
	&dev_attr_cpu0_vid.attr,

	NULL
};

static const struct attribute_group lm78_group = {
	.attrs = lm78_attributes,
};

523 524 525 526 527 528 529 530 531 532
/*
 * ISA related code
 */
#ifdef CONFIG_ISA

/* ISA device, if found */
static struct platform_device *pdev;

static unsigned short isa_address = 0x290;

533 534 535 536
/*
 * I2C devices get this name attribute automatically, but for ISA devices
 * we must create it by ourselves.
 */
J
Jean Delvare 已提交
537 538 539 540 541
static ssize_t show_name(struct device *dev, struct device_attribute
			 *devattr, char *buf)
{
	struct lm78_data *data = dev_get_drvdata(dev);

542
	return sprintf(buf, "%s\n", data->name);
J
Jean Delvare 已提交
543 544 545
}
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);

546 547 548 549 550
static struct lm78_data *lm78_data_if_isa(void)
{
	return pdev ? platform_get_drvdata(pdev) : NULL;
}

J
Jean Delvare 已提交
551 552 553
/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
{
554
	struct lm78_data *isa;
J
Jean Delvare 已提交
555 556 557 558 559 560 561 562 563 564 565
	int i;

	if (!pdev)	/* No ISA chip */
		return 0;
	isa = platform_get_drvdata(pdev);

	if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr)
		return 0;	/* Address doesn't match */
	if ((lm78_read_value(isa, LM78_REG_CHIPID) & 0xfe) != (chipid & 0xfe))
		return 0;	/* Chip type doesn't match */

566 567 568 569
	/*
	 * We compare all the limit registers, the config register and the
	 * interrupt mask registers
	 */
J
Jean Delvare 已提交
570
	for (i = 0x2b; i <= 0x3d; i++) {
571 572
		if (lm78_read_value(isa, i) !=
		    i2c_smbus_read_byte_data(client, i))
J
Jean Delvare 已提交
573 574 575
			return 0;
	}
	if (lm78_read_value(isa, LM78_REG_CONFIG) !=
576
	    i2c_smbus_read_byte_data(client, LM78_REG_CONFIG))
J
Jean Delvare 已提交
577 578
		return 0;
	for (i = 0x43; i <= 0x46; i++) {
579 580
		if (lm78_read_value(isa, i) !=
		    i2c_smbus_read_byte_data(client, i))
J
Jean Delvare 已提交
581 582 583 584 585
			return 0;
	}

	return 1;
}
586 587 588 589 590 591 592 593 594 595 596 597
#else /* !CONFIG_ISA */

static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
{
	return 0;
}

static struct lm78_data *lm78_data_if_isa(void)
{
	return NULL;
}
#endif /* CONFIG_ISA */
J
Jean Delvare 已提交
598

599
static int lm78_i2c_detect(struct i2c_client *client,
600
			   struct i2c_board_info *info)
L
Linus Torvalds 已提交
601
{
602
	int i;
603
	struct lm78_data *isa = lm78_data_if_isa();
604 605 606
	const char *client_name;
	struct i2c_adapter *adapter = client->adapter;
	int address = client->addr;
L
Linus Torvalds 已提交
607

608 609
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -ENODEV;
L
Linus Torvalds 已提交
610

611 612 613 614 615
	/*
	 * We block updates of the ISA device to minimize the risk of
	 * concurrent access to the same LM78 chip through different
	 * interfaces.
	 */
616 617
	if (isa)
		mutex_lock(&isa->update_lock);
L
Linus Torvalds 已提交
618

J
Jean Delvare 已提交
619 620 621 622 623 624 625 626
	if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
	 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) != address)
		goto err_nodev;

	/* Explicitly prevent the misdetection of Winbond chips */
	i = i2c_smbus_read_byte_data(client, 0x4f);
	if (i == 0xa3 || i == 0x5c)
		goto err_nodev;
L
Linus Torvalds 已提交
627 628

	/* Determine the chip type. */
J
Jean Delvare 已提交
629 630 631 632 633 634 635 636 637 638 639 640 641
	i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
	if (i == 0x00 || i == 0x20	/* LM78 */
	 || i == 0x40)			/* LM78-J */
		client_name = "lm78";
	else if ((i & 0xfe) == 0xc0)
		client_name = "lm79";
	else
		goto err_nodev;

	if (lm78_alias_detect(client, i)) {
		dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
			"be the same as ISA device\n", address);
		goto err_nodev;
L
Linus Torvalds 已提交
642 643
	}

644 645 646 647
	if (isa)
		mutex_unlock(&isa->update_lock);

	strlcpy(info->type, client_name, I2C_NAME_SIZE);
L
Linus Torvalds 已提交
648

649
	return 0;
L
Linus Torvalds 已提交
650

651 652 653 654 655 656 657 658 659 660 661 662
 err_nodev:
	if (isa)
		mutex_unlock(&isa->update_lock);
	return -ENODEV;
}

static int lm78_i2c_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	struct lm78_data *data;
	int err;

663
	data = devm_kzalloc(&client->dev, sizeof(struct lm78_data), GFP_KERNEL);
664 665 666 667 668 669
	if (!data)
		return -ENOMEM;

	i2c_set_clientdata(client, data);
	data->client = client;
	data->type = id->driver_data;
L
Linus Torvalds 已提交
670 671

	/* Initialize the LM78 chip */
672
	lm78_init_device(data);
L
Linus Torvalds 已提交
673 674

	/* Register sysfs hooks */
675 676
	err = sysfs_create_group(&client->dev.kobj, &lm78_group);
	if (err)
677
		return err;
678

679
	data->hwmon_dev = hwmon_device_register(&client->dev);
680 681
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
682
		goto error;
683 684
	}

L
Linus Torvalds 已提交
685 686
	return 0;

687
error:
688
	sysfs_remove_group(&client->dev.kobj, &lm78_group);
L
Linus Torvalds 已提交
689 690 691
	return err;
}

692
static int lm78_i2c_remove(struct i2c_client *client)
L
Linus Torvalds 已提交
693
{
694
	struct lm78_data *data = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
695

696
	hwmon_device_unregister(data->hwmon_dev);
697
	sysfs_remove_group(&client->dev.kobj, &lm78_group);
J
Jean Delvare 已提交
698 699 700 701

	return 0;
}

702 703 704 705 706 707
static const struct i2c_device_id lm78_i2c_id[] = {
	{ "lm78", lm78 },
	{ "lm79", lm79 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
708

709 710 711 712 713 714 715 716 717 718 719
static struct i2c_driver lm78_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name	= "lm78",
	},
	.probe		= lm78_i2c_probe,
	.remove		= lm78_i2c_remove,
	.id_table	= lm78_i2c_id,
	.detect		= lm78_i2c_detect,
	.address_list	= normal_i2c,
};
L
Linus Torvalds 已提交
720

721 722 723 724 725 726 727
/*
 * The SMBus locks itself, but ISA access must be locked explicitly!
 * We don't want to lock the whole ISA bus, so we lock each client
 * separately.
 * We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
 * would slow down the LM78 access and should not be necessary.
 */
728
static int lm78_read_value(struct lm78_data *data, u8 reg)
L
Linus Torvalds 已提交
729
{
730
	struct i2c_client *client = data->client;
731

732
#ifdef CONFIG_ISA
733
	if (!client) { /* ISA device */
734
		int res;
735
		mutex_lock(&data->lock);
736 737
		outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
		res = inb_p(data->isa_addr + LM78_DATA_REG_OFFSET);
738
		mutex_unlock(&data->lock);
L
Linus Torvalds 已提交
739 740
		return res;
	} else
741
#endif
L
Linus Torvalds 已提交
742 743 744
		return i2c_smbus_read_byte_data(client, reg);
}

745
static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
L
Linus Torvalds 已提交
746
{
747
	struct i2c_client *client = data->client;
748

749
#ifdef CONFIG_ISA
750
	if (!client) { /* ISA device */
751
		mutex_lock(&data->lock);
752 753
		outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
		outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET);
754
		mutex_unlock(&data->lock);
L
Linus Torvalds 已提交
755 756
		return 0;
	} else
757
#endif
L
Linus Torvalds 已提交
758 759 760
		return i2c_smbus_write_byte_data(client, reg, value);
}

761
static void lm78_init_device(struct lm78_data *data)
L
Linus Torvalds 已提交
762
{
J
Jean Delvare 已提交
763 764
	u8 config;
	int i;
L
Linus Torvalds 已提交
765 766

	/* Start monitoring */
767
	config = lm78_read_value(data, LM78_REG_CONFIG);
J
Jean Delvare 已提交
768
	if ((config & 0x09) != 0x01)
769
		lm78_write_value(data, LM78_REG_CONFIG,
L
Linus Torvalds 已提交
770
				 (config & 0xf7) | 0x01);
J
Jean Delvare 已提交
771 772 773

	/* A few vars need to be filled upon startup */
	for (i = 0; i < 3; i++) {
774
		data->fan_min[i] = lm78_read_value(data,
J
Jean Delvare 已提交
775 776 777 778
					LM78_REG_FAN_MIN(i));
	}

	mutex_init(&data->update_lock);
L
Linus Torvalds 已提交
779 780 781 782
}

static struct lm78_data *lm78_update_device(struct device *dev)
{
J
Jean Delvare 已提交
783
	struct lm78_data *data = dev_get_drvdata(dev);
L
Linus Torvalds 已提交
784 785
	int i;

786
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
787 788 789 790

	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
	    || !data->valid) {

J
Jean Delvare 已提交
791
		dev_dbg(dev, "Starting lm78 update\n");
L
Linus Torvalds 已提交
792 793 794

		for (i = 0; i <= 6; i++) {
			data->in[i] =
795
			    lm78_read_value(data, LM78_REG_IN(i));
L
Linus Torvalds 已提交
796
			data->in_min[i] =
797
			    lm78_read_value(data, LM78_REG_IN_MIN(i));
L
Linus Torvalds 已提交
798
			data->in_max[i] =
799
			    lm78_read_value(data, LM78_REG_IN_MAX(i));
L
Linus Torvalds 已提交
800 801 802
		}
		for (i = 0; i < 3; i++) {
			data->fan[i] =
803
			    lm78_read_value(data, LM78_REG_FAN(i));
L
Linus Torvalds 已提交
804
			data->fan_min[i] =
805
			    lm78_read_value(data, LM78_REG_FAN_MIN(i));
L
Linus Torvalds 已提交
806
		}
807
		data->temp = lm78_read_value(data, LM78_REG_TEMP);
L
Linus Torvalds 已提交
808
		data->temp_over =
809
		    lm78_read_value(data, LM78_REG_TEMP_OVER);
L
Linus Torvalds 已提交
810
		data->temp_hyst =
811 812
		    lm78_read_value(data, LM78_REG_TEMP_HYST);
		i = lm78_read_value(data, LM78_REG_VID_FANDIV);
L
Linus Torvalds 已提交
813 814 815
		data->vid = i & 0x0f;
		if (data->type == lm79)
			data->vid |=
816
			    (lm78_read_value(data, LM78_REG_CHIPID) &
L
Linus Torvalds 已提交
817 818 819 820 821
			     0x01) << 4;
		else
			data->vid |= 0x10;
		data->fan_div[0] = (i >> 4) & 0x03;
		data->fan_div[1] = i >> 6;
822 823
		data->alarms = lm78_read_value(data, LM78_REG_ALARM1) +
		    (lm78_read_value(data, LM78_REG_ALARM2) << 8);
L
Linus Torvalds 已提交
824 825 826 827 828 829
		data->last_updated = jiffies;
		data->valid = 1;

		data->fan_div[2] = 1;
	}

830
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
831 832 833 834

	return data;
}

835
#ifdef CONFIG_ISA
836 837 838 839 840 841 842 843
static int __devinit lm78_isa_probe(struct platform_device *pdev)
{
	int err;
	struct lm78_data *data;
	struct resource *res;

	/* Reserve the ISA region */
	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
844 845 846 847 848 849 850
	if (!devm_request_region(&pdev->dev, res->start + LM78_ADDR_REG_OFFSET,
				 2, "lm78"))
		return -EBUSY;

	data = devm_kzalloc(&pdev->dev, sizeof(struct lm78_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867

	mutex_init(&data->lock);
	data->isa_addr = res->start;
	platform_set_drvdata(pdev, data);

	if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
		data->type = lm79;
		data->name = "lm79";
	} else {
		data->type = lm78;
		data->name = "lm78";
	}

	/* Initialize the LM78 chip */
	lm78_init_device(data);

	/* Register sysfs hooks */
868 869 870 871 872
	err = sysfs_create_group(&pdev->dev.kobj, &lm78_group);
	if (err)
		goto exit_remove_files;
	err = device_create_file(&pdev->dev, &dev_attr_name);
	if (err)
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
		goto exit_remove_files;

	data->hwmon_dev = hwmon_device_register(&pdev->dev);
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
		goto exit_remove_files;
	}

	return 0;

 exit_remove_files:
	sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
	device_remove_file(&pdev->dev, &dev_attr_name);
	return err;
}

static int __devexit lm78_isa_remove(struct platform_device *pdev)
{
	struct lm78_data *data = platform_get_drvdata(pdev);

	hwmon_device_unregister(data->hwmon_dev);
	sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
	device_remove_file(&pdev->dev, &dev_attr_name);

	return 0;
}

static struct platform_driver lm78_isa_driver = {
	.driver = {
		.owner	= THIS_MODULE,
		.name	= "lm78",
	},
	.probe		= lm78_isa_probe,
	.remove		= __devexit_p(lm78_isa_remove),
};

J
Jean Delvare 已提交
909 910 911 912
/* return 1 if a supported chip is found, 0 otherwise */
static int __init lm78_isa_found(unsigned short address)
{
	int val, save, found = 0;
913 914
	int port;

915 916
	/*
	 * Some boards declare base+0 to base+7 as a PNP device, some base+4
917
	 * to base+7 and some base+5 to base+6. So we better request each port
918 919
	 * individually for the probing phase.
	 */
920 921
	for (port = address; port < address + LM78_EXTENT; port++) {
		if (!request_region(port, 1, "lm78")) {
922
			pr_debug("Failed to request port 0x%x\n", port);
923 924
			goto release;
		}
925
	}
J
Jean Delvare 已提交
926 927

#define REALLY_SLOW_IO
928 929 930 931
	/*
	 * We need the timeouts for at least some LM78-like
	 * chips. But only if we read 'undefined' registers.
	 */
J
Jean Delvare 已提交
932 933 934 935 936 937 938
	val = inb_p(address + 1);
	if (inb_p(address + 2) != val
	 || inb_p(address + 3) != val
	 || inb_p(address + 7) != val)
		goto release;
#undef REALLY_SLOW_IO

939 940 941 942
	/*
	 * We should be able to change the 7 LSB of the address port. The
	 * MSB (busy flag) should be clear initially, set after the write.
	 */
J
Jean Delvare 已提交
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
	save = inb_p(address + LM78_ADDR_REG_OFFSET);
	if (save & 0x80)
		goto release;
	val = ~save & 0x7f;
	outb_p(val, address + LM78_ADDR_REG_OFFSET);
	if (inb_p(address + LM78_ADDR_REG_OFFSET) != (val | 0x80)) {
		outb_p(save, address + LM78_ADDR_REG_OFFSET);
		goto release;
	}

	/* We found a device, now see if it could be an LM78 */
	outb_p(LM78_REG_CONFIG, address + LM78_ADDR_REG_OFFSET);
	val = inb_p(address + LM78_DATA_REG_OFFSET);
	if (val & 0x80)
		goto release;
	outb_p(LM78_REG_I2C_ADDR, address + LM78_ADDR_REG_OFFSET);
	val = inb_p(address + LM78_DATA_REG_OFFSET);
	if (val < 0x03 || val > 0x77)	/* Not a valid I2C address */
		goto release;

	/* The busy flag should be clear again */
	if (inb_p(address + LM78_ADDR_REG_OFFSET) & 0x80)
		goto release;

	/* Explicitly prevent the misdetection of Winbond chips */
	outb_p(0x4f, address + LM78_ADDR_REG_OFFSET);
	val = inb_p(address + LM78_DATA_REG_OFFSET);
	if (val == 0xa3 || val == 0x5c)
		goto release;

	/* Explicitly prevent the misdetection of ITE chips */
	outb_p(0x58, address + LM78_ADDR_REG_OFFSET);
	val = inb_p(address + LM78_DATA_REG_OFFSET);
	if (val == 0x90)
		goto release;

	/* Determine the chip type */
	outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET);
	val = inb_p(address + LM78_DATA_REG_OFFSET);
982
	if (val == 0x00 || val == 0x20	/* LM78 */
J
Jean Delvare 已提交
983 984 985 986 987
	 || val == 0x40			/* LM78-J */
	 || (val & 0xfe) == 0xc0)	/* LM79 */
		found = 1;

	if (found)
988
		pr_info("Found an %s chip at %#x\n",
J
Jean Delvare 已提交
989 990 991
			val & 0x80 ? "LM79" : "LM78", (int)address);

 release:
992 993
	for (port--; port >= address; port--)
		release_region(port, 1);
J
Jean Delvare 已提交
994 995 996 997 998 999 1000
	return found;
}

static int __init lm78_isa_device_add(unsigned short address)
{
	struct resource res = {
		.start	= address,
1001
		.end	= address + LM78_EXTENT - 1,
J
Jean Delvare 已提交
1002 1003 1004 1005 1006 1007 1008 1009
		.name	= "lm78",
		.flags	= IORESOURCE_IO,
	};
	int err;

	pdev = platform_device_alloc("lm78", address);
	if (!pdev) {
		err = -ENOMEM;
1010
		pr_err("Device allocation failed\n");
J
Jean Delvare 已提交
1011 1012 1013 1014 1015
		goto exit;
	}

	err = platform_device_add_resources(pdev, &res, 1);
	if (err) {
1016
		pr_err("Device resource addition failed (%d)\n", err);
J
Jean Delvare 已提交
1017 1018 1019 1020 1021
		goto exit_device_put;
	}

	err = platform_device_add(pdev);
	if (err) {
1022
		pr_err("Device addition failed (%d)\n", err);
J
Jean Delvare 已提交
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
		goto exit_device_put;
	}

	return 0;

 exit_device_put:
	platform_device_put(pdev);
 exit:
	pdev = NULL;
	return err;
}

1035
static int __init lm78_isa_register(void)
L
Linus Torvalds 已提交
1036
{
1037 1038
	int res;

J
Jean Delvare 已提交
1039 1040 1041
	if (lm78_isa_found(isa_address)) {
		res = platform_driver_register(&lm78_isa_driver);
		if (res)
J
Jean Delvare 已提交
1042
			goto exit;
1043

J
Jean Delvare 已提交
1044 1045 1046 1047 1048
		/* Sets global pdev as a side effect */
		res = lm78_isa_device_add(isa_address);
		if (res)
			goto exit_unreg_isa_driver;
	}
1049 1050

	return 0;
J
Jean Delvare 已提交
1051 1052 1053 1054 1055

 exit_unreg_isa_driver:
	platform_driver_unregister(&lm78_isa_driver);
 exit:
	return res;
L
Linus Torvalds 已提交
1056 1057
}

1058
static void lm78_isa_unregister(void)
L
Linus Torvalds 已提交
1059
{
J
Jean Delvare 已提交
1060 1061 1062 1063
	if (pdev) {
		platform_device_unregister(pdev);
		platform_driver_unregister(&lm78_isa_driver);
	}
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
}
#else /* !CONFIG_ISA */

static int __init lm78_isa_register(void)
{
	return 0;
}

static void lm78_isa_unregister(void)
{
}
#endif /* CONFIG_ISA */

static int __init sm_lm78_init(void)
{
	int res;

1081 1082 1083 1084
	/*
	 * We register the ISA device first, so that we can skip the
	 * registration of an I2C interface to the same device.
	 */
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
	res = lm78_isa_register();
	if (res)
		goto exit;

	res = i2c_add_driver(&lm78_driver);
	if (res)
		goto exit_unreg_isa_device;

	return 0;

 exit_unreg_isa_device:
	lm78_isa_unregister();
 exit:
	return res;
}

static void __exit sm_lm78_exit(void)
{
	lm78_isa_unregister();
L
Linus Torvalds 已提交
1104 1105 1106
	i2c_del_driver(&lm78_driver);
}

1107
MODULE_AUTHOR("Frodo Looijaard, Jean Delvare <khali@linux-fr.org>");
1108
MODULE_DESCRIPTION("LM78/LM79 driver");
L
Linus Torvalds 已提交
1109 1110 1111 1112
MODULE_LICENSE("GPL");

module_init(sm_lm78_init);
module_exit(sm_lm78_exit);