]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/hwmon/smsc47m1.c
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[mirror_ubuntu-artful-kernel.git] / drivers / hwmon / smsc47m1.c
CommitLineData
1da177e4
LT
1/*
2 smsc47m1.c - Part of lm_sensors, Linux kernel modules
3 for hardware monitoring
4
0db9714a 5 Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
b890a07f 6 LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
1da177e4
LT
7
8 Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
9 Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
10 Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
11 and Jean Delvare
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28#include <linux/module.h>
29#include <linux/slab.h>
30#include <linux/ioport.h>
31#include <linux/jiffies.h>
32#include <linux/i2c.h>
fde09509 33#include <linux/i2c-isa.h>
943b0830
MH
34#include <linux/hwmon.h>
35#include <linux/err.h>
1da177e4 36#include <linux/init.h>
9a61bf63 37#include <linux/mutex.h>
1da177e4
LT
38#include <asm/io.h>
39
1da177e4 40/* Address is autodetected, there is no default value */
2d8672c5 41static unsigned short address;
1da177e4
LT
42
43/* Super-I/0 registers and commands */
44
45#define REG 0x2e /* The register to read/write */
46#define VAL 0x2f /* The value to read/write */
47
48static inline void
49superio_outb(int reg, int val)
50{
51 outb(reg, REG);
52 outb(val, VAL);
53}
54
55static inline int
56superio_inb(int reg)
57{
58 outb(reg, REG);
59 return inb(VAL);
60}
61
62/* logical device for fans is 0x0A */
63#define superio_select() superio_outb(0x07, 0x0A)
64
65static inline void
66superio_enter(void)
67{
68 outb(0x55, REG);
69}
70
71static inline void
72superio_exit(void)
73{
74 outb(0xAA, REG);
75}
76
77#define SUPERIO_REG_ACT 0x30
78#define SUPERIO_REG_BASE 0x60
79#define SUPERIO_REG_DEVID 0x20
80
81/* Logical device registers */
82
83#define SMSC_EXTENT 0x80
84
85/* nr is 0 or 1 in the macros below */
86#define SMSC47M1_REG_ALARM 0x04
87#define SMSC47M1_REG_TPIN(nr) (0x34 - (nr))
88#define SMSC47M1_REG_PPIN(nr) (0x36 - (nr))
89#define SMSC47M1_REG_PWM(nr) (0x56 + (nr))
90#define SMSC47M1_REG_FANDIV 0x58
91#define SMSC47M1_REG_FAN(nr) (0x59 + (nr))
92#define SMSC47M1_REG_FAN_PRELOAD(nr) (0x5B + (nr))
93
94#define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \
95 983040/((192-(reg))*(div)))
96#define FAN_FROM_REG(reg,div,preload) ((reg)<=(preload) || (reg)==255 ? 0 : \
97 983040/(((reg)-(preload))*(div)))
98#define DIV_FROM_REG(reg) (1 << (reg))
99#define PWM_FROM_REG(reg) (((reg) & 0x7E) << 1)
100#define PWM_EN_FROM_REG(reg) ((~(reg)) & 0x01)
101#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E)
102
103struct smsc47m1_data {
104 struct i2c_client client;
943b0830 105 struct class_device *class_dev;
9a61bf63 106 struct mutex lock;
1da177e4 107
9a61bf63 108 struct mutex update_lock;
1da177e4
LT
109 unsigned long last_updated; /* In jiffies */
110
111 u8 fan[2]; /* Register value */
112 u8 fan_preload[2]; /* Register value */
113 u8 fan_div[2]; /* Register encoding, shifted right */
114 u8 alarms; /* Register encoding */
115 u8 pwm[2]; /* Register value (bit 7 is enable) */
116};
117
118
2d8672c5 119static int smsc47m1_detect(struct i2c_adapter *adapter);
1da177e4
LT
120static int smsc47m1_detach_client(struct i2c_client *client);
121
122static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
123static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
124
125static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
126 int init);
127
128
129static struct i2c_driver smsc47m1_driver = {
cdaf7934 130 .driver = {
87218842 131 .owner = THIS_MODULE,
cdaf7934
LR
132 .name = "smsc47m1",
133 },
2d8672c5 134 .attach_adapter = smsc47m1_detect,
1da177e4
LT
135 .detach_client = smsc47m1_detach_client,
136};
137
138/* nr is 0 or 1 in the callback functions below */
139
140static ssize_t get_fan(struct device *dev, char *buf, int nr)
141{
142 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
143 /* This chip (stupidly) stops monitoring fan speed if PWM is
144 enabled and duty cycle is 0%. This is fine if the monitoring
145 and control concern the same fan, but troublesome if they are
146 not (which could as well happen). */
147 int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
148 FAN_FROM_REG(data->fan[nr],
149 DIV_FROM_REG(data->fan_div[nr]),
150 data->fan_preload[nr]);
151 return sprintf(buf, "%d\n", rpm);
152}
153
154static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
155{
156 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
157 int rpm = MIN_FROM_REG(data->fan_preload[nr],
158 DIV_FROM_REG(data->fan_div[nr]));
159 return sprintf(buf, "%d\n", rpm);
160}
161
162static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
163{
164 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
165 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
166}
167
168static ssize_t get_pwm(struct device *dev, char *buf, int nr)
169{
170 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
171 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
172}
173
174static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
175{
176 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
177 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
178}
179
a5099cfc 180static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
1da177e4
LT
181{
182 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
183 return sprintf(buf, "%d\n", data->alarms);
184}
185
186static ssize_t set_fan_min(struct device *dev, const char *buf,
187 size_t count, int nr)
188{
189 struct i2c_client *client = to_i2c_client(dev);
190 struct smsc47m1_data *data = i2c_get_clientdata(client);
191 long rpmdiv, val = simple_strtol(buf, NULL, 10);
192
9a61bf63 193 mutex_lock(&data->update_lock);
1da177e4
LT
194 rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
195
196 if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
9a61bf63 197 mutex_unlock(&data->update_lock);
1da177e4
LT
198 return -EINVAL;
199 }
200
201 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
202 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
203 data->fan_preload[nr]);
9a61bf63 204 mutex_unlock(&data->update_lock);
1da177e4
LT
205
206 return count;
207}
208
209/* Note: we save and restore the fan minimum here, because its value is
210 determined in part by the fan clock divider. This follows the principle
d6e05edc 211 of least surprise; the user doesn't expect the fan minimum to change just
1da177e4
LT
212 because the divider changed. */
213static ssize_t set_fan_div(struct device *dev, const char *buf,
214 size_t count, int nr)
215{
216 struct i2c_client *client = to_i2c_client(dev);
217 struct smsc47m1_data *data = i2c_get_clientdata(client);
218
219 long new_div = simple_strtol(buf, NULL, 10), tmp;
220 u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
221
222 if (new_div == old_div) /* No change */
223 return count;
224
9a61bf63 225 mutex_lock(&data->update_lock);
1da177e4
LT
226 switch (new_div) {
227 case 1: data->fan_div[nr] = 0; break;
228 case 2: data->fan_div[nr] = 1; break;
229 case 4: data->fan_div[nr] = 2; break;
230 case 8: data->fan_div[nr] = 3; break;
231 default:
9a61bf63 232 mutex_unlock(&data->update_lock);
1da177e4
LT
233 return -EINVAL;
234 }
235
236 tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
237 tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6);
238 smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp);
239
240 /* Preserve fan min */
241 tmp = 192 - (old_div * (192 - data->fan_preload[nr])
242 + new_div / 2) / new_div;
243 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
244 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
245 data->fan_preload[nr]);
9a61bf63 246 mutex_unlock(&data->update_lock);
1da177e4
LT
247
248 return count;
249}
250
251static ssize_t set_pwm(struct device *dev, const char *buf,
252 size_t count, int nr)
253{
254 struct i2c_client *client = to_i2c_client(dev);
255 struct smsc47m1_data *data = i2c_get_clientdata(client);
256
257 long val = simple_strtol(buf, NULL, 10);
258
259 if (val < 0 || val > 255)
260 return -EINVAL;
261
9a61bf63 262 mutex_lock(&data->update_lock);
1da177e4
LT
263 data->pwm[nr] &= 0x81; /* Preserve additional bits */
264 data->pwm[nr] |= PWM_TO_REG(val);
265 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
266 data->pwm[nr]);
9a61bf63 267 mutex_unlock(&data->update_lock);
1da177e4
LT
268
269 return count;
270}
271
272static ssize_t set_pwm_en(struct device *dev, const char *buf,
273 size_t count, int nr)
274{
275 struct i2c_client *client = to_i2c_client(dev);
276 struct smsc47m1_data *data = i2c_get_clientdata(client);
277
278 long val = simple_strtol(buf, NULL, 10);
279
280 if (val != 0 && val != 1)
281 return -EINVAL;
282
9a61bf63 283 mutex_lock(&data->update_lock);
1da177e4
LT
284 data->pwm[nr] &= 0xFE; /* preserve the other bits */
285 data->pwm[nr] |= !val;
286 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
287 data->pwm[nr]);
9a61bf63 288 mutex_unlock(&data->update_lock);
1da177e4
LT
289
290 return count;
291}
292
293#define fan_present(offset) \
a5099cfc 294static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \
1da177e4
LT
295{ \
296 return get_fan(dev, buf, offset - 1); \
297} \
a5099cfc 298static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
1da177e4
LT
299{ \
300 return get_fan_min(dev, buf, offset - 1); \
301} \
a5099cfc 302static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \
1da177e4
LT
303 const char *buf, size_t count) \
304{ \
305 return set_fan_min(dev, buf, count, offset - 1); \
306} \
a5099cfc 307static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
1da177e4
LT
308{ \
309 return get_fan_div(dev, buf, offset - 1); \
310} \
a5099cfc 311static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \
1da177e4
LT
312 const char *buf, size_t count) \
313{ \
314 return set_fan_div(dev, buf, count, offset - 1); \
315} \
a5099cfc 316static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
1da177e4
LT
317{ \
318 return get_pwm(dev, buf, offset - 1); \
319} \
a5099cfc 320static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
1da177e4
LT
321 const char *buf, size_t count) \
322{ \
323 return set_pwm(dev, buf, count, offset - 1); \
324} \
a5099cfc 325static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \
1da177e4
LT
326{ \
327 return get_pwm_en(dev, buf, offset - 1); \
328} \
a5099cfc 329static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \
1da177e4
LT
330 const char *buf, size_t count) \
331{ \
332 return set_pwm_en(dev, buf, count, offset - 1); \
333} \
334static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
335 NULL); \
336static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
337 get_fan##offset##_min, set_fan##offset##_min); \
338static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
339 get_fan##offset##_div, set_fan##offset##_div); \
340static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
341 get_pwm##offset, set_pwm##offset); \
342static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
343 get_pwm##offset##_en, set_pwm##offset##_en);
344
345fan_present(1);
346fan_present(2);
347
348static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
349
e6cfb3ad 350static int __init smsc47m1_find(unsigned short *addr)
1da177e4
LT
351{
352 u8 val;
353
354 superio_enter();
355 val = superio_inb(SUPERIO_REG_DEVID);
356
357 /*
358 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
359 * 0x5F) and LPC47B27x (device id 0x51) have fan control.
360 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
ec5ce552 361 * can do much more besides (device id 0x60).
b890a07f
JD
362 * The LPC47M997 is undocumented, but seems to be compatible with
363 * the LPC47M192, and has the same device id.
1da177e4
LT
364 */
365 if (val == 0x51)
ec5ce552 366 printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
1da177e4 367 else if (val == 0x59)
ec5ce552 368 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n");
1da177e4 369 else if (val == 0x5F)
ec5ce552
JD
370 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
371 else if (val == 0x60)
b890a07f
JD
372 printk(KERN_INFO "smsc47m1: Found SMSC "
373 "LPC47M15x/LPC47M192/LPC47M997\n");
1da177e4
LT
374 else {
375 superio_exit();
376 return -ENODEV;
377 }
378
379 superio_select();
2d8672c5
JD
380 *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
381 | superio_inb(SUPERIO_REG_BASE + 1);
1da177e4 382 val = superio_inb(SUPERIO_REG_ACT);
2d8672c5 383 if (*addr == 0 || (val & 0x01) == 0) {
1da177e4
LT
384 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
385 superio_exit();
386 return -ENODEV;
387 }
388
389 superio_exit();
390 return 0;
391}
392
2d8672c5 393static int smsc47m1_detect(struct i2c_adapter *adapter)
1da177e4
LT
394{
395 struct i2c_client *new_client;
396 struct smsc47m1_data *data;
397 int err = 0;
398 int fan1, fan2, pwm1, pwm2;
399
cdaf7934 400 if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) {
1da177e4
LT
401 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
402 return -EBUSY;
403 }
404
ba9c2e8d 405 if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
1da177e4
LT
406 err = -ENOMEM;
407 goto error_release;
408 }
1da177e4
LT
409
410 new_client = &data->client;
411 i2c_set_clientdata(new_client, data);
412 new_client->addr = address;
9a61bf63 413 mutex_init(&data->lock);
1da177e4
LT
414 new_client->adapter = adapter;
415 new_client->driver = &smsc47m1_driver;
416 new_client->flags = 0;
417
418 strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
9a61bf63 419 mutex_init(&data->update_lock);
1da177e4
LT
420
421 /* If no function is properly configured, there's no point in
422 actually registering the chip. */
423 fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05)
424 == 0x05;
425 fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
426 == 0x05;
427 pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
428 == 0x04;
429 pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
430 == 0x04;
431 if (!(fan1 || fan2 || pwm1 || pwm2)) {
432 dev_warn(&new_client->dev, "Device is not configured, will not use\n");
433 err = -ENODEV;
434 goto error_free;
435 }
436
437 if ((err = i2c_attach_client(new_client)))
438 goto error_free;
439
440 /* Some values (fan min, clock dividers, pwm registers) may be
441 needed before any update is triggered, so we better read them
442 at least once here. We don't usually do it that way, but in
443 this particular case, manually reading 5 registers out of 8
444 doesn't make much sense and we're better using the existing
445 function. */
446 smsc47m1_update_device(&new_client->dev, 1);
447
943b0830
MH
448 /* Register sysfs hooks */
449 data->class_dev = hwmon_device_register(&new_client->dev);
450 if (IS_ERR(data->class_dev)) {
451 err = PTR_ERR(data->class_dev);
452 goto error_detach;
453 }
454
1da177e4
LT
455 if (fan1) {
456 device_create_file(&new_client->dev, &dev_attr_fan1_input);
457 device_create_file(&new_client->dev, &dev_attr_fan1_min);
458 device_create_file(&new_client->dev, &dev_attr_fan1_div);
459 } else
460 dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
461 "skipping\n");
462
463 if (fan2) {
464 device_create_file(&new_client->dev, &dev_attr_fan2_input);
465 device_create_file(&new_client->dev, &dev_attr_fan2_min);
466 device_create_file(&new_client->dev, &dev_attr_fan2_div);
467 } else
468 dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
469 "skipping\n");
470
471 if (pwm1) {
472 device_create_file(&new_client->dev, &dev_attr_pwm1);
473 device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
474 } else
475 dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
476 "skipping\n");
477 if (pwm2) {
478 device_create_file(&new_client->dev, &dev_attr_pwm2);
479 device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
480 } else
481 dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
482 "skipping\n");
483
484 device_create_file(&new_client->dev, &dev_attr_alarms);
485
486 return 0;
487
943b0830
MH
488error_detach:
489 i2c_detach_client(new_client);
1da177e4 490error_free:
1f57ff89 491 kfree(data);
1da177e4
LT
492error_release:
493 release_region(address, SMSC_EXTENT);
494 return err;
495}
496
497static int smsc47m1_detach_client(struct i2c_client *client)
498{
943b0830 499 struct smsc47m1_data *data = i2c_get_clientdata(client);
1da177e4
LT
500 int err;
501
943b0830
MH
502 hwmon_device_unregister(data->class_dev);
503
7bef5594 504 if ((err = i2c_detach_client(client)))
1da177e4 505 return err;
1da177e4
LT
506
507 release_region(client->addr, SMSC_EXTENT);
943b0830 508 kfree(data);
1da177e4
LT
509
510 return 0;
511}
512
513static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
514{
515 int res;
516
9a61bf63 517 mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
1da177e4 518 res = inb_p(client->addr + reg);
9a61bf63 519 mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
1da177e4
LT
520 return res;
521}
522
523static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
524{
9a61bf63 525 mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
1da177e4 526 outb_p(value, client->addr + reg);
9a61bf63 527 mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
1da177e4
LT
528}
529
530static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
531 int init)
532{
533 struct i2c_client *client = to_i2c_client(dev);
534 struct smsc47m1_data *data = i2c_get_clientdata(client);
535
9a61bf63 536 mutex_lock(&data->update_lock);
1da177e4
LT
537
538 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
539 int i;
540
541 for (i = 0; i < 2; i++) {
542 data->fan[i] = smsc47m1_read_value(client,
543 SMSC47M1_REG_FAN(i));
544 data->fan_preload[i] = smsc47m1_read_value(client,
545 SMSC47M1_REG_FAN_PRELOAD(i));
546 data->pwm[i] = smsc47m1_read_value(client,
547 SMSC47M1_REG_PWM(i));
548 }
549
550 i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
551 data->fan_div[0] = (i >> 4) & 0x03;
552 data->fan_div[1] = i >> 6;
553
554 data->alarms = smsc47m1_read_value(client,
555 SMSC47M1_REG_ALARM) >> 6;
556 /* Clear alarms if needed */
557 if (data->alarms)
558 smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0);
559
560 data->last_updated = jiffies;
561 }
562
9a61bf63 563 mutex_unlock(&data->update_lock);
1da177e4
LT
564 return data;
565}
566
567static int __init sm_smsc47m1_init(void)
568{
2d8672c5 569 if (smsc47m1_find(&address)) {
1da177e4
LT
570 return -ENODEV;
571 }
572
fde09509 573 return i2c_isa_add_driver(&smsc47m1_driver);
1da177e4
LT
574}
575
576static void __exit sm_smsc47m1_exit(void)
577{
fde09509 578 i2c_isa_del_driver(&smsc47m1_driver);
1da177e4
LT
579}
580
581MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
582MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
583MODULE_LICENSE("GPL");
584
585module_init(sm_smsc47m1_init);
586module_exit(sm_smsc47m1_exit);