29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #include <linux/module.h>
32 #include <linux/slab.h>
45 static unsigned short force_id;
51 #define DRVNAME "smsc47m1"
60 superio_outb(
int reg,
int val)
74 #define superio_select() superio_outb(0x07, 0x0A)
88 #define SUPERIO_REG_ACT 0x30
89 #define SUPERIO_REG_BASE 0x60
90 #define SUPERIO_REG_DEVID 0x20
91 #define SUPERIO_REG_DEVREV 0x21
95 #define SMSC_EXTENT 0x80
98 #define SMSC47M1_REG_ALARM 0x04
99 #define SMSC47M1_REG_TPIN(nr) (0x34 - (nr))
100 #define SMSC47M1_REG_PPIN(nr) (0x36 - (nr))
101 #define SMSC47M1_REG_FANDIV 0x58
103 static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b };
104 static const u8 SMSC47M1_REG_FAN_PRELOAD[3] = { 0x5b, 0x5c, 0x6c };
105 static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 };
107 #define SMSC47M2_REG_ALARM6 0x09
108 #define SMSC47M2_REG_TPIN1 0x38
109 #define SMSC47M2_REG_TPIN2 0x37
110 #define SMSC47M2_REG_TPIN3 0x2d
111 #define SMSC47M2_REG_PPIN3 0x2c
112 #define SMSC47M2_REG_FANDIV3 0x6a
114 #define MIN_FROM_REG(reg, div) ((reg) >= 192 ? 0 : \
115 983040 / ((192 - (reg)) * (div)))
116 #define FAN_FROM_REG(reg, div, preload) ((reg) <= (preload) || (reg) == 255 ? \
118 983040 / (((reg) - (preload)) * (div)))
119 #define DIV_FROM_REG(reg) (1 << (reg))
120 #define PWM_FROM_REG(reg) (((reg) & 0x7E) << 1)
121 #define PWM_EN_FROM_REG(reg) ((~(reg)) & 0x01)
122 #define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E)
166 .remove =
__exit_p(smsc47m1_remove),
181 int rpm = (data->
pwm[
nr] & 0x7F) == 0x00 ? 0 :
185 return sprintf(buf,
"%d\n", rpm);
193 int nr = attr->
index;
196 return sprintf(buf,
"%d\n", rpm);
239 *devattr,
const char *buf,
size_t count)
243 int nr = attr->
index;
248 err = kstrtol(buf, 10, &val);
255 if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
260 data->
fan_preload[
nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
261 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
275 *devattr,
const char *buf,
size_t count)
279 int nr = attr->
index;
285 err = kstrtol(buf, 10, &new_div);
289 if (new_div == old_div)
315 & ~(0x03 << (4 + 2 *
nr));
328 + new_div / 2) / new_div;
330 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
338 *devattr,
const char *buf,
size_t count)
342 int nr = attr->
index;
346 err = kstrtol(buf, 10, &val);
350 if (val < 0 || val > 255)
354 data->
pwm[
nr] &= 0x81;
356 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
364 *devattr,
const char *buf,
size_t count)
368 int nr = attr->
index;
372 err = kstrtoul(buf, 10, &val);
380 data->
pwm[
nr] &= 0xFE;
382 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
389 #define fan_present(offset) \
390 static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan, \
392 static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
393 get_fan_min, set_fan_min, offset - 1); \
394 static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
395 get_fan_div, set_fan_div, offset - 1); \
396 static SENSOR_DEVICE_ATTR(fan##offset##_alarm, S_IRUGO, get_fan_alarm, \
398 static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
399 get_pwm, set_pwm, offset - 1); \
400 static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
401 get_pwm_en, set_pwm_en, offset - 1)
418 static struct attribute *smsc47m1_attributes_fan1[] = {
419 &sensor_dev_attr_fan1_input.dev_attr.attr,
420 &sensor_dev_attr_fan1_min.dev_attr.attr,
421 &sensor_dev_attr_fan1_div.dev_attr.attr,
422 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
427 .attrs = smsc47m1_attributes_fan1,
430 static struct attribute *smsc47m1_attributes_fan2[] = {
431 &sensor_dev_attr_fan2_input.dev_attr.attr,
432 &sensor_dev_attr_fan2_min.dev_attr.attr,
433 &sensor_dev_attr_fan2_div.dev_attr.attr,
434 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
439 .attrs = smsc47m1_attributes_fan2,
442 static struct attribute *smsc47m1_attributes_fan3[] = {
443 &sensor_dev_attr_fan3_input.dev_attr.attr,
444 &sensor_dev_attr_fan3_min.dev_attr.attr,
445 &sensor_dev_attr_fan3_div.dev_attr.attr,
446 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
451 .attrs = smsc47m1_attributes_fan3,
454 static struct attribute *smsc47m1_attributes_pwm1[] = {
455 &sensor_dev_attr_pwm1.dev_attr.attr,
456 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
461 .attrs = smsc47m1_attributes_pwm1,
464 static struct attribute *smsc47m1_attributes_pwm2[] = {
465 &sensor_dev_attr_pwm2.dev_attr.attr,
466 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
471 .attrs = smsc47m1_attributes_pwm2,
474 static struct attribute *smsc47m1_attributes_pwm3[] = {
475 &sensor_dev_attr_pwm3.dev_attr.attr,
476 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
481 .attrs = smsc47m1_attributes_pwm3,
484 static struct attribute *smsc47m1_attributes[] = {
485 &dev_attr_alarms.attr,
491 .attrs = smsc47m1_attributes,
518 pr_info(
"Found SMSC LPC47B27x\n");
522 pr_info(
"Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n");
526 pr_info(
"Found SMSC LPC47M14x\n");
530 pr_info(
"Found SMSC LPC47M15x/LPC47M192/LPC47M997\n");
535 pr_debug(
"Found SMSC LPC47M233, unsupported\n");
540 pr_info(
"Found SMSC LPC47M292\n");
552 pr_info(
"Device address not set, will not use\n");
562 if ((sio_data->
activate & 0x01) == 0) {
574 if ((sio_data->
activate & 0x01) == 0) {
595 static int __init smsc47m1_handle_resources(
unsigned short address,
599 static const u8 ports_m1[] = {
606 static const u8 ports_m2[] = {
616 int i, ports_size,
err;
631 for (i = 0; i + 1 < ports_size; i += 2) {
632 unsigned short start = address + ports[
i];
633 unsigned short len = ports[i + 1];
646 "Region 0x%hx-0x%hx already in use!\n",
657 static void smsc47m1_remove_files(
struct device *dev)
677 static const char *
const names[] = {
683 err = smsc47m1_handle_resources(res->
start, sio_data->
type,
696 platform_set_drvdata(pdev, data);
723 if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) {
724 dev_warn(dev,
"Device not configured, will not use\n");
736 smsc47m1_update_device(dev, 1);
741 &smsc47m1_group_fan1);
743 goto error_remove_files;
745 dev_dbg(dev,
"Fan 1 not enabled by hardware, skipping\n");
749 &smsc47m1_group_fan2);
751 goto error_remove_files;
753 dev_dbg(dev,
"Fan 2 not enabled by hardware, skipping\n");
757 &smsc47m1_group_fan3);
759 goto error_remove_files;
761 dev_dbg(dev,
"Fan 3 not enabled by hardware, skipping\n");
765 &smsc47m1_group_pwm1);
767 goto error_remove_files;
769 dev_dbg(dev,
"PWM 1 not enabled by hardware, skipping\n");
773 &smsc47m1_group_pwm2);
775 goto error_remove_files;
777 dev_dbg(dev,
"PWM 2 not enabled by hardware, skipping\n");
781 &smsc47m1_group_pwm3);
783 goto error_remove_files;
785 dev_dbg(dev,
"PWM 3 not enabled by hardware, skipping\n");
789 goto error_remove_files;
794 goto error_remove_files;
800 smsc47m1_remove_files(dev);
809 smsc47m1_remove_files(&pdev->
dev);
825 for (i = 0; i < fan_nr; i++) {
826 data->
fan[
i] = smsc47m1_read_value(data,
827 SMSC47M1_REG_FAN[i]);
829 SMSC47M1_REG_FAN_PRELOAD[i]);
830 data->
pwm[
i] = smsc47m1_read_value(data,
831 SMSC47M1_REG_PWM[i]);
835 data->
fan_div[0] = (i >> 4) & 0x03;
838 data->
alarms = smsc47m1_read_value(data,
845 data->
fan_div[2] = (smsc47m1_read_value(data,
847 data->
alarms |= (smsc47m1_read_value(data,
851 smsc47m1_write_value(data,
863 static int __init smsc47m1_device_add(
unsigned short address,
874 err = smsc47m1_handle_resources(address, sio_data->
type,
CHECK,
NULL);
881 pr_err(
"Device allocation failed\n");
887 pr_err(
"Device resource addition failed (%d)\n", err);
888 goto exit_device_put;
894 pr_err(
"Platform data allocation failed\n");
895 goto exit_device_put;
900 pr_err(
"Device addition failed (%d)\n", err);
901 goto exit_device_put;
912 static int __init sm_smsc47m1_init(
void)
918 err = smsc47m1_find(&sio_data);
924 err = smsc47m1_device_add(address, &sio_data);
936 smsc47m1_restore(&sio_data);
940 static void __exit sm_smsc47m1_exit(
void)
943 smsc47m1_restore(pdev->
dev.platform_data);