2 smsc47m1.c - Part of lm_sensors, Linux kernel modules
3 for hardware monitoring
5 Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
6 LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997
9 Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
10 Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
11 Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <linux/module.h>
30 #include <linux/slab.h>
31 #include <linux/ioport.h>
32 #include <linux/jiffies.h>
33 #include <linux/platform_device.h>
34 #include <linux/hwmon.h>
35 #include <linux/err.h>
36 #include <linux/init.h>
37 #include <linux/mutex.h>
38 #include <linux/sysfs.h>
41 static struct platform_device *pdev;
43 #define DRVNAME "smsc47m1"
44 enum chips { smsc47m1, smsc47m2 };
46 /* Super-I/0 registers and commands */
48 #define REG 0x2e /* The register to read/write */
49 #define VAL 0x2f /* The value to read/write */
52 superio_outb(int reg, int val)
65 /* logical device for fans is 0x0A */
66 #define superio_select() superio_outb(0x07, 0x0A)
80 #define SUPERIO_REG_ACT 0x30
81 #define SUPERIO_REG_BASE 0x60
82 #define SUPERIO_REG_DEVID 0x20
84 /* Logical device registers */
86 #define SMSC_EXTENT 0x80
88 /* nr is 0 or 1 in the macros below */
89 #define SMSC47M1_REG_ALARM 0x04
90 #define SMSC47M1_REG_TPIN(nr) (0x34 - (nr))
91 #define SMSC47M1_REG_PPIN(nr) (0x36 - (nr))
92 #define SMSC47M1_REG_FANDIV 0x58
94 static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b };
95 static const u8 SMSC47M1_REG_FAN_PRELOAD[3] = { 0x5b, 0x5c, 0x6c };
96 static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 };
98 #define SMSC47M2_REG_ALARM6 0x09
99 #define SMSC47M2_REG_TPIN1 0x38
100 #define SMSC47M2_REG_TPIN2 0x37
101 #define SMSC47M2_REG_TPIN3 0x2d
102 #define SMSC47M2_REG_PPIN3 0x2c
103 #define SMSC47M2_REG_FANDIV3 0x6a
105 #define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \
106 983040/((192-(reg))*(div)))
107 #define FAN_FROM_REG(reg,div,preload) ((reg)<=(preload) || (reg)==255 ? 0 : \
108 983040/(((reg)-(preload))*(div)))
109 #define DIV_FROM_REG(reg) (1 << (reg))
110 #define PWM_FROM_REG(reg) (((reg) & 0x7E) << 1)
111 #define PWM_EN_FROM_REG(reg) ((~(reg)) & 0x01)
112 #define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E)
114 struct smsc47m1_data {
118 struct class_device *class_dev;
120 struct mutex update_lock;
121 unsigned long last_updated; /* In jiffies */
123 u8 fan[3]; /* Register value */
124 u8 fan_preload[3]; /* Register value */
125 u8 fan_div[3]; /* Register encoding, shifted right */
126 u8 alarms; /* Register encoding */
127 u8 pwm[3]; /* Register value (bit 0 is disable) */
130 struct smsc47m1_sio_data {
135 static int smsc47m1_probe(struct platform_device *pdev);
136 static int smsc47m1_remove(struct platform_device *pdev);
137 static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
140 static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
142 return inb_p(data->addr + reg);
145 static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
148 outb_p(value, data->addr + reg);
151 static struct platform_driver smsc47m1_driver = {
153 .owner = THIS_MODULE,
156 .probe = smsc47m1_probe,
157 .remove = __devexit_p(smsc47m1_remove),
160 /* nr is 0 or 1 in the callback functions below */
162 static ssize_t get_fan(struct device *dev, char *buf, int nr)
164 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
165 /* This chip (stupidly) stops monitoring fan speed if PWM is
166 enabled and duty cycle is 0%. This is fine if the monitoring
167 and control concern the same fan, but troublesome if they are
168 not (which could as well happen). */
169 int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
170 FAN_FROM_REG(data->fan[nr],
171 DIV_FROM_REG(data->fan_div[nr]),
172 data->fan_preload[nr]);
173 return sprintf(buf, "%d\n", rpm);
176 static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
178 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
179 int rpm = MIN_FROM_REG(data->fan_preload[nr],
180 DIV_FROM_REG(data->fan_div[nr]));
181 return sprintf(buf, "%d\n", rpm);
184 static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
186 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
187 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
190 static ssize_t get_pwm(struct device *dev, char *buf, int nr)
192 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
193 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
196 static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
198 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
199 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
202 static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
204 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
205 return sprintf(buf, "%d\n", data->alarms);
208 static ssize_t set_fan_min(struct device *dev, const char *buf,
209 size_t count, int nr)
211 struct smsc47m1_data *data = dev_get_drvdata(dev);
212 long rpmdiv, val = simple_strtol(buf, NULL, 10);
214 mutex_lock(&data->update_lock);
215 rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
217 if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
218 mutex_unlock(&data->update_lock);
222 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
223 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
224 data->fan_preload[nr]);
225 mutex_unlock(&data->update_lock);
230 /* Note: we save and restore the fan minimum here, because its value is
231 determined in part by the fan clock divider. This follows the principle
232 of least surprise; the user doesn't expect the fan minimum to change just
233 because the divider changed. */
234 static ssize_t set_fan_div(struct device *dev, const char *buf,
235 size_t count, int nr)
237 struct smsc47m1_data *data = dev_get_drvdata(dev);
239 long new_div = simple_strtol(buf, NULL, 10), tmp;
240 u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
242 if (new_div == old_div) /* No change */
245 mutex_lock(&data->update_lock);
247 case 1: data->fan_div[nr] = 0; break;
248 case 2: data->fan_div[nr] = 1; break;
249 case 4: data->fan_div[nr] = 2; break;
250 case 8: data->fan_div[nr] = 3; break;
252 mutex_unlock(&data->update_lock);
259 tmp = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV)
260 & ~(0x03 << (4 + 2 * nr));
261 tmp |= data->fan_div[nr] << (4 + 2 * nr);
262 smsc47m1_write_value(data, SMSC47M1_REG_FANDIV, tmp);
265 tmp = smsc47m1_read_value(data, SMSC47M2_REG_FANDIV3) & 0xCF;
266 tmp |= data->fan_div[2] << 4;
267 smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp);
271 /* Preserve fan min */
272 tmp = 192 - (old_div * (192 - data->fan_preload[nr])
273 + new_div / 2) / new_div;
274 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
275 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
276 data->fan_preload[nr]);
277 mutex_unlock(&data->update_lock);
282 static ssize_t set_pwm(struct device *dev, const char *buf,
283 size_t count, int nr)
285 struct smsc47m1_data *data = dev_get_drvdata(dev);
287 long val = simple_strtol(buf, NULL, 10);
289 if (val < 0 || val > 255)
292 mutex_lock(&data->update_lock);
293 data->pwm[nr] &= 0x81; /* Preserve additional bits */
294 data->pwm[nr] |= PWM_TO_REG(val);
295 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
297 mutex_unlock(&data->update_lock);
302 static ssize_t set_pwm_en(struct device *dev, const char *buf,
303 size_t count, int nr)
305 struct smsc47m1_data *data = dev_get_drvdata(dev);
307 long val = simple_strtol(buf, NULL, 10);
309 if (val != 0 && val != 1)
312 mutex_lock(&data->update_lock);
313 data->pwm[nr] &= 0xFE; /* preserve the other bits */
314 data->pwm[nr] |= !val;
315 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
317 mutex_unlock(&data->update_lock);
322 #define fan_present(offset) \
323 static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \
325 return get_fan(dev, buf, offset - 1); \
327 static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
329 return get_fan_min(dev, buf, offset - 1); \
331 static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \
332 const char *buf, size_t count) \
334 return set_fan_min(dev, buf, count, offset - 1); \
336 static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
338 return get_fan_div(dev, buf, offset - 1); \
340 static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \
341 const char *buf, size_t count) \
343 return set_fan_div(dev, buf, count, offset - 1); \
345 static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
347 return get_pwm(dev, buf, offset - 1); \
349 static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
350 const char *buf, size_t count) \
352 return set_pwm(dev, buf, count, offset - 1); \
354 static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \
356 return get_pwm_en(dev, buf, offset - 1); \
358 static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \
359 const char *buf, size_t count) \
361 return set_pwm_en(dev, buf, count, offset - 1); \
363 static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
365 static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
366 get_fan##offset##_min, set_fan##offset##_min); \
367 static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
368 get_fan##offset##_div, set_fan##offset##_div); \
369 static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
370 get_pwm##offset, set_pwm##offset); \
371 static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
372 get_pwm##offset##_en, set_pwm##offset##_en);
378 static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
380 static ssize_t show_name(struct device *dev, struct device_attribute
383 struct smsc47m1_data *data = dev_get_drvdata(dev);
385 return sprintf(buf, "%s\n", data->name);
387 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
389 /* Almost all sysfs files may or may not be created depending on the chip
390 setup so we create them individually. It is still convenient to define a
391 group to remove them all at once. */
392 static struct attribute *smsc47m1_attributes[] = {
393 &dev_attr_fan1_input.attr,
394 &dev_attr_fan1_min.attr,
395 &dev_attr_fan1_div.attr,
396 &dev_attr_fan2_input.attr,
397 &dev_attr_fan2_min.attr,
398 &dev_attr_fan2_div.attr,
399 &dev_attr_fan3_input.attr,
400 &dev_attr_fan3_min.attr,
401 &dev_attr_fan3_div.attr,
404 &dev_attr_pwm1_enable.attr,
406 &dev_attr_pwm2_enable.attr,
408 &dev_attr_pwm3_enable.attr,
410 &dev_attr_alarms.attr,
415 static const struct attribute_group smsc47m1_group = {
416 .attrs = smsc47m1_attributes,
419 static int __init smsc47m1_find(unsigned short *addr,
420 struct smsc47m1_sio_data *sio_data)
425 val = superio_inb(SUPERIO_REG_DEVID);
428 * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
429 * (device id 0x5F) and LPC47B27x (device id 0x51) have fan control.
430 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
431 * can do much more besides (device id 0x60).
432 * The LPC47M997 is undocumented, but seems to be compatible with
433 * the LPC47M192, and has the same device id.
434 * The LPC47M292 (device id 0x6B) is somewhat compatible, but it
435 * supports a 3rd fan, and the pin configuration registers are
436 * unfortunately different.
440 printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
441 sio_data->type = smsc47m1;
444 printk(KERN_INFO "smsc47m1: Found SMSC "
445 "LPC47M10x/LPC47M112/LPC47M13x\n");
446 sio_data->type = smsc47m1;
449 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
450 sio_data->type = smsc47m1;
453 printk(KERN_INFO "smsc47m1: Found SMSC "
454 "LPC47M15x/LPC47M192/LPC47M997\n");
455 sio_data->type = smsc47m1;
458 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M292\n");
459 sio_data->type = smsc47m2;
467 *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
468 | superio_inb(SUPERIO_REG_BASE + 1);
469 val = superio_inb(SUPERIO_REG_ACT);
470 if (*addr == 0 || (val & 0x01) == 0) {
471 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
480 static int __devinit smsc47m1_probe(struct platform_device *pdev)
482 struct device *dev = &pdev->dev;
483 struct smsc47m1_sio_data *sio_data = dev->platform_data;
484 struct smsc47m1_data *data;
485 struct resource *res;
487 int fan1, fan2, fan3, pwm1, pwm2, pwm3;
489 static const char *names[] = {
494 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
495 if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) {
496 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
497 (unsigned long)res->start,
498 (unsigned long)res->end);
502 if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
507 data->addr = res->start;
508 data->type = sio_data->type;
509 data->name = names[sio_data->type];
510 mutex_init(&data->update_lock);
511 platform_set_drvdata(pdev, data);
513 /* If no function is properly configured, there's no point in
514 actually registering the chip. */
515 pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05)
517 pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05)
519 if (data->type == smsc47m2) {
520 fan1 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN1)
522 fan2 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN2)
524 fan3 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN3)
526 pwm3 = (smsc47m1_read_value(data, SMSC47M2_REG_PPIN3)
529 fan1 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(0))
531 fan2 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(1))
536 if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) {
537 dev_warn(dev, "Device not configured, will not use\n");
542 /* Some values (fan min, clock dividers, pwm registers) may be
543 needed before any update is triggered, so we better read them
544 at least once here. We don't usually do it that way, but in
545 this particular case, manually reading 5 registers out of 8
546 doesn't make much sense and we're better using the existing
548 smsc47m1_update_device(dev, 1);
550 /* Register sysfs hooks */
552 if ((err = device_create_file(dev, &dev_attr_fan1_input))
553 || (err = device_create_file(dev, &dev_attr_fan1_min))
554 || (err = device_create_file(dev, &dev_attr_fan1_div)))
555 goto error_remove_files;
557 dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
560 if ((err = device_create_file(dev, &dev_attr_fan2_input))
561 || (err = device_create_file(dev, &dev_attr_fan2_min))
562 || (err = device_create_file(dev, &dev_attr_fan2_div)))
563 goto error_remove_files;
565 dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
568 if ((err = device_create_file(dev, &dev_attr_fan3_input))
569 || (err = device_create_file(dev, &dev_attr_fan3_min))
570 || (err = device_create_file(dev, &dev_attr_fan3_div)))
571 goto error_remove_files;
573 dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
576 if ((err = device_create_file(dev, &dev_attr_pwm1))
577 || (err = device_create_file(dev, &dev_attr_pwm1_enable)))
578 goto error_remove_files;
580 dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
583 if ((err = device_create_file(dev, &dev_attr_pwm2))
584 || (err = device_create_file(dev, &dev_attr_pwm2_enable)))
585 goto error_remove_files;
587 dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
590 if ((err = device_create_file(dev, &dev_attr_pwm3))
591 || (err = device_create_file(dev, &dev_attr_pwm3_enable)))
592 goto error_remove_files;
594 dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");
596 if ((err = device_create_file(dev, &dev_attr_alarms)))
597 goto error_remove_files;
599 data->class_dev = hwmon_device_register(dev);
600 if (IS_ERR(data->class_dev)) {
601 err = PTR_ERR(data->class_dev);
602 goto error_remove_files;
608 sysfs_remove_group(&dev->kobj, &smsc47m1_group);
612 release_region(res->start, SMSC_EXTENT);
616 static int __devexit smsc47m1_remove(struct platform_device *pdev)
618 struct smsc47m1_data *data = platform_get_drvdata(pdev);
619 struct resource *res;
621 platform_set_drvdata(pdev, NULL);
622 hwmon_device_unregister(data->class_dev);
623 sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
625 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
626 release_region(res->start, SMSC_EXTENT);
632 static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
635 struct smsc47m1_data *data = dev_get_drvdata(dev);
637 mutex_lock(&data->update_lock);
639 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
641 fan_nr = data->type == smsc47m2 ? 3 : 2;
643 for (i = 0; i < fan_nr; i++) {
644 data->fan[i] = smsc47m1_read_value(data,
645 SMSC47M1_REG_FAN[i]);
646 data->fan_preload[i] = smsc47m1_read_value(data,
647 SMSC47M1_REG_FAN_PRELOAD[i]);
648 data->pwm[i] = smsc47m1_read_value(data,
649 SMSC47M1_REG_PWM[i]);
652 i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
653 data->fan_div[0] = (i >> 4) & 0x03;
654 data->fan_div[1] = i >> 6;
656 data->alarms = smsc47m1_read_value(data,
657 SMSC47M1_REG_ALARM) >> 6;
658 /* Clear alarms if needed */
660 smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
663 data->fan_div[2] = (smsc47m1_read_value(data,
664 SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
665 data->alarms |= (smsc47m1_read_value(data,
666 SMSC47M2_REG_ALARM6) & 0x40) >> 4;
667 /* Clear alarm if needed */
668 if (data->alarms & 0x04)
669 smsc47m1_write_value(data,
674 data->last_updated = jiffies;
677 mutex_unlock(&data->update_lock);
681 static int __init smsc47m1_device_add(unsigned short address,
682 const struct smsc47m1_sio_data *sio_data)
684 struct resource res = {
686 .end = address + SMSC_EXTENT - 1,
688 .flags = IORESOURCE_IO,
692 pdev = platform_device_alloc(DRVNAME, address);
695 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
699 err = platform_device_add_resources(pdev, &res, 1);
701 printk(KERN_ERR DRVNAME ": Device resource addition failed "
703 goto exit_device_put;
706 pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data),
708 if (!pdev->dev.platform_data) {
710 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
711 goto exit_device_put;
713 memcpy(pdev->dev.platform_data, sio_data,
714 sizeof(struct smsc47m1_sio_data));
716 err = platform_device_add(pdev);
718 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
720 goto exit_device_put;
726 platform_device_put(pdev);
731 static int __init sm_smsc47m1_init(void)
734 unsigned short address;
735 struct smsc47m1_sio_data sio_data;
737 if (smsc47m1_find(&address, &sio_data))
740 err = platform_driver_register(&smsc47m1_driver);
744 /* Sets global pdev as a side effect */
745 err = smsc47m1_device_add(address, &sio_data);
752 platform_driver_unregister(&smsc47m1_driver);
757 static void __exit sm_smsc47m1_exit(void)
759 platform_device_unregister(pdev);
760 platform_driver_unregister(&smsc47m1_driver);
763 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
764 MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
765 MODULE_LICENSE("GPL");
767 module_init(sm_smsc47m1_init);
768 module_exit(sm_smsc47m1_exit);