lm80.c 21.0 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 21 22 23 24 25 26 27 28
/*
 * lm80.c - From lm_sensors, Linux kernel modules for hardware
 * monitoring
 * Copyright (C) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
 * and Philip Edelbrock <phil@netroedge.com>
 *
 * Ported to Linux 2.6 by Tiago Sousa <mirage@kaotik.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.
 */

#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-sysfs.h>
31
#include <linux/err.h>
32
#include <linux/mutex.h>
L
Linus Torvalds 已提交
33 34

/* Addresses to scan */
35 36
static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
						0x2e, 0x2f, I2C_CLIENT_END };
L
Linus Torvalds 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

/* Many LM80 constants specified below */

/* The LM80 registers */
#define LM80_REG_IN_MAX(nr)		(0x2a + (nr) * 2)
#define LM80_REG_IN_MIN(nr)		(0x2b + (nr) * 2)
#define LM80_REG_IN(nr)			(0x20 + (nr))

#define LM80_REG_FAN1			0x28
#define LM80_REG_FAN2			0x29
#define LM80_REG_FAN_MIN(nr)		(0x3b + (nr))

#define LM80_REG_TEMP			0x27
#define LM80_REG_TEMP_HOT_MAX		0x38
#define LM80_REG_TEMP_HOT_HYST		0x39
#define LM80_REG_TEMP_OS_MAX		0x3a
#define LM80_REG_TEMP_OS_HYST		0x3b

#define LM80_REG_CONFIG			0x00
#define LM80_REG_ALARM1			0x01
#define LM80_REG_ALARM2			0x02
#define LM80_REG_MASK1			0x03
#define LM80_REG_MASK2			0x04
#define LM80_REG_FANDIV			0x05
#define LM80_REG_RES			0x06


/* Conversions. Rounding and limit checking is only done on the TO_REG
   variants. Note that you should be a bit careful with which arguments
   these macros are called: arguments may be evaluated more than once.
   Fixing this is just not worth it. */

69 70
#define IN_TO_REG(val)		(SENSORS_LIMIT(((val) + 5) / 10, 0, 255))
#define IN_FROM_REG(val)	((val) * 10)
L
Linus Torvalds 已提交
71 72 73 74 75 76

static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div)
{
	if (rpm == 0)
		return 255;
	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
77
	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
L
Linus Torvalds 已提交
78 79
}

80 81
#define FAN_FROM_REG(val, div)	((val) == 0 ? -1 : \
				(val) == 255 ? 0 : 1350000/((div) * (val)))
L
Linus Torvalds 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95

static inline long TEMP_FROM_REG(u16 temp)
{
	long res;

	temp >>= 4;
	if (temp < 0x0800)
		res = 625 * (long) temp;
	else
		res = ((long) temp - 0x01000) * 625;

	return res / 10;
}

96 97
#define TEMP_LIMIT_FROM_REG(val)	(((val) > 0x80 ? \
	(val) - 0x100 : (val)) * 1000)
L
Linus Torvalds 已提交
98

99 100
#define TEMP_LIMIT_TO_REG(val)		SENSORS_LIMIT((val) < 0 ? \
	((val) - 500) / 1000 : ((val) + 500) / 1000, 0, 255)
L
Linus Torvalds 已提交
101 102 103 104 105 106 107 108

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

/*
 * Client data (each client gets its own)
 */

struct lm80_data {
109
	struct device *hwmon_dev;
110
	struct mutex update_lock;
111
	char error;		/* !=0 if error occurred during last update */
L
Linus Torvalds 已提交
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	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[2];		/* Register value */
	u8 fan_min[2];		/* Register value */
	u8 fan_div[2];		/* Register encoding, shifted right */
	u16 temp;		/* Register values, shifted right */
	u8 temp_hot_max;	/* Register value */
	u8 temp_hot_hyst;	/* Register value */
	u8 temp_os_max;		/* Register value */
	u8 temp_os_hyst;	/* Register value */
	u16 alarms;		/* Register encoding, combined */
};

J
Jean Delvare 已提交
129
/*
L
Linus Torvalds 已提交
130 131 132
 * Functions declaration
 */

133 134
static int lm80_probe(struct i2c_client *client,
		      const struct i2c_device_id *id);
135
static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info);
L
Linus Torvalds 已提交
136
static void lm80_init_client(struct i2c_client *client);
137
static int lm80_remove(struct i2c_client *client);
L
Linus Torvalds 已提交
138 139 140 141 142 143 144 145
static struct lm80_data *lm80_update_device(struct device *dev);
static int lm80_read_value(struct i2c_client *client, u8 reg);
static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);

/*
 * Driver data (common to all clients)
 */

146
static const struct i2c_device_id lm80_id[] = {
J
Jean Delvare 已提交
147
	{ "lm80", 0 },
148 149 150 151
	{ }
};
MODULE_DEVICE_TABLE(i2c, lm80_id);

L
Linus Torvalds 已提交
152
static struct i2c_driver lm80_driver = {
153
	.class		= I2C_CLASS_HWMON,
154 155 156
	.driver = {
		.name	= "lm80",
	},
157 158 159 160
	.probe		= lm80_probe,
	.remove		= lm80_remove,
	.id_table	= lm80_id,
	.detect		= lm80_detect,
161
	.address_list	= normal_i2c,
L
Linus Torvalds 已提交
162 163 164 165 166 167 168
};

/*
 * Sysfs stuff
 */

#define show_in(suffix, value) \
169 170
static ssize_t show_in_##suffix(struct device *dev, \
	struct device_attribute *attr, char *buf) \
L
Linus Torvalds 已提交
171
{ \
172
	int nr = to_sensor_dev_attr(attr)->index; \
L
Linus Torvalds 已提交
173
	struct lm80_data *data = lm80_update_device(dev); \
174 175
	if (IS_ERR(data)) \
		return PTR_ERR(data); \
176
	return sprintf(buf, "%d\n", IN_FROM_REG(data->value[nr])); \
L
Linus Torvalds 已提交
177
}
178 179 180
show_in(min, in_min)
show_in(max, in_max)
show_in(input, in)
L
Linus Torvalds 已提交
181 182

#define set_in(suffix, value, reg) \
183 184
static ssize_t set_in_##suffix(struct device *dev, \
	struct device_attribute *attr, const char *buf, size_t count) \
L
Linus Torvalds 已提交
185
{ \
186
	int nr = to_sensor_dev_attr(attr)->index; \
L
Linus Torvalds 已提交
187 188
	struct i2c_client *client = to_i2c_client(dev); \
	struct lm80_data *data = i2c_get_clientdata(client); \
189 190 191 192
	long val; \
	int err = kstrtol(buf, 10, &val); \
	if (err < 0) \
		return err; \
193
\
194
	mutex_lock(&data->update_lock);\
195 196
	data->value[nr] = IN_TO_REG(val); \
	lm80_write_value(client, reg(nr), data->value[nr]); \
197
	mutex_unlock(&data->update_lock);\
L
Linus Torvalds 已提交
198 199
	return count; \
}
200 201 202 203
set_in(min, in_min, LM80_REG_IN_MIN)
set_in(max, in_max, LM80_REG_IN_MAX)

#define show_fan(suffix, value) \
204 205
static ssize_t show_fan_##suffix(struct device *dev, \
	struct device_attribute *attr, char *buf) \
L
Linus Torvalds 已提交
206
{ \
207
	int nr = to_sensor_dev_attr(attr)->index; \
L
Linus Torvalds 已提交
208
	struct lm80_data *data = lm80_update_device(dev); \
209 210
	if (IS_ERR(data)) \
		return PTR_ERR(data); \
211 212
	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[nr], \
		       DIV_FROM_REG(data->fan_div[nr]))); \
L
Linus Torvalds 已提交
213
}
214 215
show_fan(min, fan_min)
show_fan(input, fan)
L
Linus Torvalds 已提交
216

217 218 219 220 221
static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
	char *buf)
{
	int nr = to_sensor_dev_attr(attr)->index;
	struct lm80_data *data = lm80_update_device(dev);
222 223
	if (IS_ERR(data))
		return PTR_ERR(data);
224
	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
L
Linus Torvalds 已提交
225 226
}

227 228 229 230 231 232
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
	const char *buf, size_t count)
{
	int nr = to_sensor_dev_attr(attr)->index;
	struct i2c_client *client = to_i2c_client(dev);
	struct lm80_data *data = i2c_get_clientdata(client);
233 234 235 236
	unsigned long val;
	int err = kstrtoul(buf, 10, &val);
	if (err < 0)
		return err;
237 238 239 240 241 242

	mutex_lock(&data->update_lock);
	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
	lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
	mutex_unlock(&data->update_lock);
	return count;
L
Linus Torvalds 已提交
243 244 245 246
}

/* 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
A
Andreas Mohr 已提交
247
   least surprise; the user doesn't expect the fan minimum to change just
L
Linus Torvalds 已提交
248
   because the divisor changed. */
249 250
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
	const char *buf, size_t count)
L
Linus Torvalds 已提交
251
{
252
	int nr = to_sensor_dev_attr(attr)->index;
L
Linus Torvalds 已提交
253 254
	struct i2c_client *client = to_i2c_client(dev);
	struct lm80_data *data = i2c_get_clientdata(client);
255
	unsigned long min, val;
L
Linus Torvalds 已提交
256
	u8 reg;
257 258 259
	int err = kstrtoul(buf, 10, &val);
	if (err < 0)
		return err;
L
Linus Torvalds 已提交
260 261

	/* Save fan_min */
262
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
263 264 265 266
	min = FAN_FROM_REG(data->fan_min[nr],
			   DIV_FROM_REG(data->fan_div[nr]));

	switch (val) {
267 268 269 270 271 272 273 274 275 276 277 278
	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 已提交
279 280 281
	default:
		dev_err(&client->dev, "fan_div value %ld not "
			"supported. Choose one of 1, 2, 4 or 8!\n", val);
282
		mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
283 284 285 286 287 288 289 290 291 292
		return -EINVAL;
	}

	reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1))))
	    | (data->fan_div[nr] << (2 * (nr + 1)));
	lm80_write_value(client, LM80_REG_FANDIV, reg);

	/* Restore fan_min */
	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
	lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
293
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
294 295 296 297

	return count;
}

298 299
static ssize_t show_temp_input1(struct device *dev,
	struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
300 301
{
	struct lm80_data *data = lm80_update_device(dev);
302 303
	if (IS_ERR(data))
		return PTR_ERR(data);
L
Linus Torvalds 已提交
304 305 306 307
	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp));
}

#define show_temp(suffix, value) \
308 309
static ssize_t show_temp_##suffix(struct device *dev, \
	struct device_attribute *attr, char *buf) \
L
Linus Torvalds 已提交
310 311
{ \
	struct lm80_data *data = lm80_update_device(dev); \
312 313
	if (IS_ERR(data)) \
		return PTR_ERR(data); \
L
Linus Torvalds 已提交
314 315 316 317 318 319 320 321
	return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \
}
show_temp(hot_max, temp_hot_max);
show_temp(hot_hyst, temp_hot_hyst);
show_temp(os_max, temp_os_max);
show_temp(os_hyst, temp_os_hyst);

#define set_temp(suffix, value, reg) \
322 323
static ssize_t set_temp_##suffix(struct device *dev, \
	struct device_attribute *attr, const char *buf, size_t count) \
L
Linus Torvalds 已提交
324 325 326
{ \
	struct i2c_client *client = to_i2c_client(dev); \
	struct lm80_data *data = i2c_get_clientdata(client); \
327 328 329 330
	long val; \
	int err = kstrtol(buf, 10, &val); \
	if (err < 0) \
		return err; \
331
\
332
	mutex_lock(&data->update_lock); \
L
Linus Torvalds 已提交
333 334
	data->value = TEMP_LIMIT_TO_REG(val); \
	lm80_write_value(client, reg, data->value); \
335
	mutex_unlock(&data->update_lock); \
L
Linus Torvalds 已提交
336 337 338 339 340 341 342
	return count; \
}
set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX);
set_temp(hot_hyst, temp_hot_hyst, LM80_REG_TEMP_HOT_HYST);
set_temp(os_max, temp_os_max, LM80_REG_TEMP_OS_MAX);
set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST);

J
Jean Delvare 已提交
343 344
static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
			   char *buf)
L
Linus Torvalds 已提交
345 346
{
	struct lm80_data *data = lm80_update_device(dev);
347 348
	if (IS_ERR(data))
		return PTR_ERR(data);
L
Linus Torvalds 已提交
349 350 351
	return sprintf(buf, "%u\n", data->alarms);
}

352 353 354 355 356
static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	int bitnr = to_sensor_dev_attr(attr)->index;
	struct lm80_data *data = lm80_update_device(dev);
357 358
	if (IS_ERR(data))
		return PTR_ERR(data);
359 360 361
	return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
}

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
static SENSOR_DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 0);
static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 1);
static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 2);
static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 3);
static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 4);
static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 5);
static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO,
		show_in_min, set_in_min, 6);
static SENSOR_DEVICE_ATTR(in0_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 0);
static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 1);
static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 2);
static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 3);
static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 4);
static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 5);
static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO,
		show_in_max, set_in_max, 6);
static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in_input, NULL, 0);
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in_input, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in_input, NULL, 2);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in_input, NULL, 3);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in_input, NULL, 4);
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in_input, NULL, 5);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in_input, NULL, 6);
static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
		show_fan_min, set_fan_min, 0);
static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
		show_fan_min, set_fan_min, 1);
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO,
		show_fan_div, set_fan_div, 0);
static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO,
		show_fan_div, set_fan_div, 1);
L
Linus Torvalds 已提交
407 408
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max,
409
	set_temp_hot_max);
L
Linus Torvalds 已提交
410
static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hot_hyst,
411
	set_temp_hot_hyst);
L
Linus Torvalds 已提交
412
static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_os_max,
413
	set_temp_os_max);
L
Linus Torvalds 已提交
414
static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_os_hyst,
415
	set_temp_os_hyst);
L
Linus Torvalds 已提交
416
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
417 418 419 420 421 422 423 424 425 426 427
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, 4);
static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 10);
static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 8);
static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 13);
L
Linus Torvalds 已提交
428 429 430 431 432

/*
 * Real code
 */

433
static struct attribute *lm80_attributes[] = {
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
	&sensor_dev_attr_in0_min.dev_attr.attr,
	&sensor_dev_attr_in1_min.dev_attr.attr,
	&sensor_dev_attr_in2_min.dev_attr.attr,
	&sensor_dev_attr_in3_min.dev_attr.attr,
	&sensor_dev_attr_in4_min.dev_attr.attr,
	&sensor_dev_attr_in5_min.dev_attr.attr,
	&sensor_dev_attr_in6_min.dev_attr.attr,
	&sensor_dev_attr_in0_max.dev_attr.attr,
	&sensor_dev_attr_in1_max.dev_attr.attr,
	&sensor_dev_attr_in2_max.dev_attr.attr,
	&sensor_dev_attr_in3_max.dev_attr.attr,
	&sensor_dev_attr_in4_max.dev_attr.attr,
	&sensor_dev_attr_in5_max.dev_attr.attr,
	&sensor_dev_attr_in6_max.dev_attr.attr,
	&sensor_dev_attr_in0_input.dev_attr.attr,
	&sensor_dev_attr_in1_input.dev_attr.attr,
	&sensor_dev_attr_in2_input.dev_attr.attr,
	&sensor_dev_attr_in3_input.dev_attr.attr,
	&sensor_dev_attr_in4_input.dev_attr.attr,
	&sensor_dev_attr_in5_input.dev_attr.attr,
	&sensor_dev_attr_in6_input.dev_attr.attr,
	&sensor_dev_attr_fan1_min.dev_attr.attr,
	&sensor_dev_attr_fan2_min.dev_attr.attr,
	&sensor_dev_attr_fan1_input.dev_attr.attr,
	&sensor_dev_attr_fan2_input.dev_attr.attr,
	&sensor_dev_attr_fan1_div.dev_attr.attr,
	&sensor_dev_attr_fan2_div.dev_attr.attr,
461 462 463 464 465 466
	&dev_attr_temp1_input.attr,
	&dev_attr_temp1_max.attr,
	&dev_attr_temp1_max_hyst.attr,
	&dev_attr_temp1_crit.attr,
	&dev_attr_temp1_crit_hyst.attr,
	&dev_attr_alarms.attr,
467 468 469 470 471 472 473 474 475 476 477
	&sensor_dev_attr_in0_alarm.dev_attr.attr,
	&sensor_dev_attr_in1_alarm.dev_attr.attr,
	&sensor_dev_attr_in2_alarm.dev_attr.attr,
	&sensor_dev_attr_in3_alarm.dev_attr.attr,
	&sensor_dev_attr_in4_alarm.dev_attr.attr,
	&sensor_dev_attr_in5_alarm.dev_attr.attr,
	&sensor_dev_attr_in6_alarm.dev_attr.attr,
	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
	&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
478 479 480 481 482 483 484
	NULL
};

static const struct attribute_group lm80_group = {
	.attrs = lm80_attributes,
};

485
/* Return 0 if detection is successful, -ENODEV otherwise */
486
static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
L
Linus Torvalds 已提交
487
{
488
	struct i2c_adapter *adapter = client->adapter;
L
Linus Torvalds 已提交
489 490 491
	int i, cur;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
492
		return -ENODEV;
L
Linus Torvalds 已提交
493 494

	/* Now, we do the remaining detection. It is lousy. */
J
Jean Delvare 已提交
495
	if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
496
		return -ENODEV;
L
Linus Torvalds 已提交
497
	for (i = 0x2a; i <= 0x3d; i++) {
J
Jean Delvare 已提交
498 499 500 501
		cur = i2c_smbus_read_byte_data(client, i);
		if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur)
		 || (i2c_smbus_read_byte_data(client, i + 0x80) != cur)
		 || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur))
502
			return -ENODEV;
L
Linus Torvalds 已提交
503 504
	}

505
	strlcpy(info->type, "lm80", I2C_NAME_SIZE);
L
Linus Torvalds 已提交
506

507 508
	return 0;
}
L
Linus Torvalds 已提交
509

510 511 512 513 514 515 516 517 518 519 520 521 522 523
static int lm80_probe(struct i2c_client *client,
		      const struct i2c_device_id *id)
{
	struct lm80_data *data;
	int err;

	data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}

	i2c_set_clientdata(client, data);
	mutex_init(&data->update_lock);
L
Linus Torvalds 已提交
524 525

	/* Initialize the LM80 chip */
J
Jean Delvare 已提交
526
	lm80_init_client(client);
L
Linus Torvalds 已提交
527 528

	/* A few vars need to be filled upon startup */
J
Jean Delvare 已提交
529 530
	data->fan_min[0] = lm80_read_value(client, LM80_REG_FAN_MIN(1));
	data->fan_min[1] = lm80_read_value(client, LM80_REG_FAN_MIN(2));
L
Linus Torvalds 已提交
531 532

	/* Register sysfs hooks */
533 534
	err = sysfs_create_group(&client->dev.kobj, &lm80_group);
	if (err)
535
		goto error_free;
536

J
Jean Delvare 已提交
537
	data->hwmon_dev = hwmon_device_register(&client->dev);
538 539
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
540
		goto error_remove;
541 542
	}

L
Linus Torvalds 已提交
543 544
	return 0;

545
error_remove:
J
Jean Delvare 已提交
546
	sysfs_remove_group(&client->dev.kobj, &lm80_group);
L
Linus Torvalds 已提交
547 548 549 550 551 552
error_free:
	kfree(data);
exit:
	return err;
}

553
static int lm80_remove(struct i2c_client *client)
L
Linus Torvalds 已提交
554
{
555
	struct lm80_data *data = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
556

557
	hwmon_device_unregister(data->hwmon_dev);
558
	sysfs_remove_group(&client->dev.kobj, &lm80_group);
L
Linus Torvalds 已提交
559

560
	kfree(data);
L
Linus Torvalds 已提交
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
	return 0;
}

static int lm80_read_value(struct i2c_client *client, u8 reg)
{
	return i2c_smbus_read_byte_data(client, reg);
}

static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(client, reg, value);
}

/* Called when we have found a new LM80. */
static void lm80_init_client(struct i2c_client *client)
{
	/* Reset all except Watchdog values and last conversion values
	   This sets fan-divs to 2, among others. This makes most other
	   initializations unnecessary */
	lm80_write_value(client, LM80_REG_CONFIG, 0x80);
	/* Set 11-bit temperature resolution */
	lm80_write_value(client, LM80_REG_RES, 0x08);

	/* Start monitoring */
	lm80_write_value(client, LM80_REG_CONFIG, 0x01);
}

static struct lm80_data *lm80_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm80_data *data = i2c_get_clientdata(client);
	int i;
593 594 595
	int rv;
	int prev_rv;
	struct lm80_data *ret = data;
L
Linus Torvalds 已提交
596

597
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
598

599 600 601
	if (data->error)
		lm80_init_client(client);

L
Linus Torvalds 已提交
602 603 604
	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
		dev_dbg(&client->dev, "Starting lm80 update\n");
		for (i = 0; i <= 6; i++) {
605 606 607 608 609 610 611 612 613 614 615 616 617 618
			rv = lm80_read_value(client, LM80_REG_IN(i));
			if (rv < 0)
				goto abort;
			data->in[i] = rv;

			rv = lm80_read_value(client, LM80_REG_IN_MIN(i));
			if (rv < 0)
				goto abort;
			data->in_min[i] = rv;

			rv = lm80_read_value(client, LM80_REG_IN_MAX(i));
			if (rv < 0)
				goto abort;
			data->in_max[i] = rv;
L
Linus Torvalds 已提交
619
		}
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682

		rv = lm80_read_value(client, LM80_REG_FAN1);
		if (rv < 0)
			goto abort;
		data->fan[0] = rv;

		rv = lm80_read_value(client, LM80_REG_FAN_MIN(1));
		if (rv < 0)
			goto abort;
		data->fan_min[0] = rv;

		rv = lm80_read_value(client, LM80_REG_FAN2);
		if (rv < 0)
			goto abort;
		data->fan[1] = rv;

		rv = lm80_read_value(client, LM80_REG_FAN_MIN(2));
		if (rv < 0)
			goto abort;
		data->fan_min[1] = rv;

		prev_rv = rv = lm80_read_value(client, LM80_REG_TEMP);
		if (rv < 0)
			goto abort;
		rv = lm80_read_value(client, LM80_REG_RES);
		if (rv < 0)
			goto abort;
		data->temp = (prev_rv << 8) | (rv & 0xf0);

		rv = lm80_read_value(client, LM80_REG_TEMP_OS_MAX);
		if (rv < 0)
			goto abort;
		data->temp_os_max = rv;

		rv = lm80_read_value(client, LM80_REG_TEMP_OS_HYST);
		if (rv < 0)
			goto abort;
		data->temp_os_hyst = rv;

		rv = lm80_read_value(client, LM80_REG_TEMP_HOT_MAX);
		if (rv < 0)
			goto abort;
		data->temp_hot_max = rv;

		rv = lm80_read_value(client, LM80_REG_TEMP_HOT_HYST);
		if (rv < 0)
			goto abort;
		data->temp_hot_hyst = rv;

		rv = lm80_read_value(client, LM80_REG_FANDIV);
		if (rv < 0)
			goto abort;
		data->fan_div[0] = (rv >> 2) & 0x03;
		data->fan_div[1] = (rv >> 4) & 0x03;

		prev_rv = rv = lm80_read_value(client, LM80_REG_ALARM1);
		if (rv < 0)
			goto abort;
		rv = lm80_read_value(client, LM80_REG_ALARM2);
		if (rv < 0)
			goto abort;
		data->alarms = prev_rv + (rv << 8);

L
Linus Torvalds 已提交
683 684
		data->last_updated = jiffies;
		data->valid = 1;
685
		data->error = 0;
L
Linus Torvalds 已提交
686
	}
687 688 689 690 691
	goto done;

abort:
	ret = ERR_PTR(rv);
	data->valid = 0;
692
	data->error = 1;
L
Linus Torvalds 已提交
693

694
done:
695
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
696

697
	return ret;
L
Linus Torvalds 已提交
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
}

static int __init sensors_lm80_init(void)
{
	return i2c_add_driver(&lm80_driver);
}

static void __exit sensors_lm80_exit(void)
{
	i2c_del_driver(&lm80_driver);
}

MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
	"Philip Edelbrock <phil@netroedge.com>");
MODULE_DESCRIPTION("LM80 driver");
MODULE_LICENSE("GPL");

module_init(sensors_lm80_init);
module_exit(sensors_lm80_exit);