lm78.c 28.9 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 663 664 665 666 667 668 669
 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;

	data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
	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 678
		goto ERROR3;

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 ERROR4;
683 684
	}

L
Linus Torvalds 已提交
685 686
	return 0;

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

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

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

	return 0;
}

705 706 707 708 709 710
static const struct i2c_device_id lm78_i2c_id[] = {
	{ "lm78", lm78 },
	{ "lm79", lm79 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
711

712 713 714 715 716 717 718 719 720 721 722
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 已提交
723

724 725 726 727 728 729 730
/*
 * 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.
 */
731
static int lm78_read_value(struct lm78_data *data, u8 reg)
L
Linus Torvalds 已提交
732
{
733
	struct i2c_client *client = data->client;
734

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

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

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

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

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

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

	mutex_init(&data->update_lock);
L
Linus Torvalds 已提交
782 783 784 785
}

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

789
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
790 791 792 793

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

J
Jean Delvare 已提交
794
		dev_dbg(dev, "Starting lm78 update\n");
L
Linus Torvalds 已提交
795 796 797

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

		data->fan_div[2] = 1;
	}

833
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
834 835 836 837

	return data;
}

838
#ifdef CONFIG_ISA
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
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);
	if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
		err = -EBUSY;
		goto exit;
	}

	data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit_release_region;
	}
	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 */
873 874 875 876 877
	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)
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 909 910 911 912 913 914 915 916 917 918 919 920 921 922
		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);
	kfree(data);
 exit_release_region:
	release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
 exit:
	return err;
}

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

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

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	release_region(res->start + LM78_ADDR_REG_OFFSET, 2);

	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 已提交
923 924 925 926
/* return 1 if a supported chip is found, 0 otherwise */
static int __init lm78_isa_found(unsigned short address)
{
	int val, save, found = 0;
927 928
	int port;

929 930
	/*
	 * Some boards declare base+0 to base+7 as a PNP device, some base+4
931
	 * to base+7 and some base+5 to base+6. So we better request each port
932 933
	 * individually for the probing phase.
	 */
934 935
	for (port = address; port < address + LM78_EXTENT; port++) {
		if (!request_region(port, 1, "lm78")) {
936
			pr_debug("Failed to request port 0x%x\n", port);
937 938
			goto release;
		}
939
	}
J
Jean Delvare 已提交
940 941

#define REALLY_SLOW_IO
942 943 944 945
	/*
	 * We need the timeouts for at least some LM78-like
	 * chips. But only if we read 'undefined' registers.
	 */
J
Jean Delvare 已提交
946 947 948 949 950 951 952
	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

953 954 955 956
	/*
	 * 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 已提交
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 982 983 984 985 986 987 988 989 990 991 992 993 994 995
	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);
996
	if (val == 0x00 || val == 0x20	/* LM78 */
J
Jean Delvare 已提交
997 998 999 1000 1001
	 || val == 0x40			/* LM78-J */
	 || (val & 0xfe) == 0xc0)	/* LM79 */
		found = 1;

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

 release:
1006 1007
	for (port--; port >= address; port--)
		release_region(port, 1);
J
Jean Delvare 已提交
1008 1009 1010 1011 1012 1013 1014
	return found;
}

static int __init lm78_isa_device_add(unsigned short address)
{
	struct resource res = {
		.start	= address,
1015
		.end	= address + LM78_EXTENT - 1,
J
Jean Delvare 已提交
1016 1017 1018 1019 1020 1021 1022 1023
		.name	= "lm78",
		.flags	= IORESOURCE_IO,
	};
	int err;

	pdev = platform_device_alloc("lm78", address);
	if (!pdev) {
		err = -ENOMEM;
1024
		pr_err("Device allocation failed\n");
J
Jean Delvare 已提交
1025 1026 1027 1028 1029
		goto exit;
	}

	err = platform_device_add_resources(pdev, &res, 1);
	if (err) {
1030
		pr_err("Device resource addition failed (%d)\n", err);
J
Jean Delvare 已提交
1031 1032 1033 1034 1035
		goto exit_device_put;
	}

	err = platform_device_add(pdev);
	if (err) {
1036
		pr_err("Device addition failed (%d)\n", err);
J
Jean Delvare 已提交
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
		goto exit_device_put;
	}

	return 0;

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

1049
static int __init lm78_isa_register(void)
L
Linus Torvalds 已提交
1050
{
1051 1052
	int res;

J
Jean Delvare 已提交
1053 1054 1055
	if (lm78_isa_found(isa_address)) {
		res = platform_driver_register(&lm78_isa_driver);
		if (res)
J
Jean Delvare 已提交
1056
			goto exit;
1057

J
Jean Delvare 已提交
1058 1059 1060 1061 1062
		/* Sets global pdev as a side effect */
		res = lm78_isa_device_add(isa_address);
		if (res)
			goto exit_unreg_isa_driver;
	}
1063 1064

	return 0;
J
Jean Delvare 已提交
1065 1066 1067 1068 1069

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

1072
static void lm78_isa_unregister(void)
L
Linus Torvalds 已提交
1073
{
J
Jean Delvare 已提交
1074 1075 1076 1077
	if (pdev) {
		platform_device_unregister(pdev);
		platform_driver_unregister(&lm78_isa_driver);
	}
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
}
#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;

1095 1096 1097 1098
	/*
	 * We register the ISA device first, so that we can skip the
	 * registration of an I2C interface to the same device.
	 */
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
	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 已提交
1118 1119 1120
	i2c_del_driver(&lm78_driver);
}

1121
MODULE_AUTHOR("Frodo Looijaard, Jean Delvare <khali@linux-fr.org>");
1122
MODULE_DESCRIPTION("LM78/LM79 driver");
L
Linus Torvalds 已提交
1123 1124 1125 1126
MODULE_LICENSE("GPL");

module_init(sm_lm78_init);
module_exit(sm_lm78_exit);