36 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
38 #include <linux/module.h>
40 #include <linux/slab.h>
53 static unsigned short extra_isa[3];
59 "Chip initialization level:\n"
61 "*1: Forcibly enable internal voltage and temperature channels, except in9\n"
62 " 2: Forcibly enable all voltage and temperature channels, except in9\n"
63 " 3: Forcibly enable all voltage and temperature channels, including in9");
65 static unsigned short force_id;
88 static inline void superio_outb(
int sioaddr,
int reg,
int val)
91 outb(val, sioaddr + 1);
94 static inline int superio_inb(
int sioaddr,
int reg)
97 return inb(sioaddr + 1);
100 static inline void superio_exit(
int sioaddr)
103 outb(0x02, sioaddr + 1);
110 #define PC87360_EXTENT 0x10
111 #define PC87365_REG_BANK 0x09
119 #define PC87360_REG_PRESCALE(nr) (0x00 + 2 * (nr))
120 #define PC87360_REG_PWM(nr) (0x01 + 2 * (nr))
121 #define PC87360_REG_FAN_MIN(nr) (0x06 + 3 * (nr))
122 #define PC87360_REG_FAN(nr) (0x07 + 3 * (nr))
123 #define PC87360_REG_FAN_STATUS(nr) (0x08 + 3 * (nr))
125 #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : \
126 480000 / ((val) * (div)))
127 #define FAN_TO_REG(val, div) ((val) <= 100 ? 0 : \
128 480000 / ((val) * (div)))
129 #define FAN_DIV_FROM_REG(val) (1 << (((val) >> 5) & 0x03))
130 #define FAN_STATUS_FROM_REG(val) ((val) & 0x07)
132 #define FAN_CONFIG_MONITOR(val, nr) (((val) >> (2 + (nr) * 3)) & 1)
133 #define FAN_CONFIG_CONTROL(val, nr) (((val) >> (3 + (nr) * 3)) & 1)
134 #define FAN_CONFIG_INVERT(val, nr) (((val) >> (4 + (nr) * 3)) & 1)
136 #define PWM_FROM_REG(val, inv) ((inv) ? 255 - (val) : (val))
152 #define PC87365_REG_IN_CONVRATE 0x07
153 #define PC87365_REG_IN_CONFIG 0x08
154 #define PC87365_REG_IN 0x0B
155 #define PC87365_REG_IN_MIN 0x0D
156 #define PC87365_REG_IN_MAX 0x0C
157 #define PC87365_REG_IN_STATUS 0x0A
158 #define PC87365_REG_IN_ALARMS1 0x00
159 #define PC87365_REG_IN_ALARMS2 0x01
160 #define PC87365_REG_VID 0x06
162 #define IN_FROM_REG(val, ref) (((val) * (ref) + 128) / 256)
163 #define IN_TO_REG(val, ref) ((val) < 0 ? 0 : \
164 (val) * 256 >= (ref) * 255 ? 255 : \
165 ((val) * 256 + (ref) / 2) / (ref))
171 #define PC87365_REG_TEMP_CONFIG 0x08
172 #define PC87365_REG_TEMP 0x0B
173 #define PC87365_REG_TEMP_MIN 0x0D
174 #define PC87365_REG_TEMP_MAX 0x0C
175 #define PC87365_REG_TEMP_CRIT 0x0E
176 #define PC87365_REG_TEMP_STATUS 0x0A
177 #define PC87365_REG_TEMP_ALARMS 0x00
179 #define TEMP_FROM_REG(val) ((val) * 1000)
180 #define TEMP_TO_REG(val) ((val) < -55000 ? -55 : \
181 (val) > 127000 ? 127 : \
182 (val) < 0 ? ((val) - 500) / 1000 : \
183 ((val) + 500) / 1000)
238 int use_thermistors);
250 .probe = pc87360_probe,
299 err = kstrtol(buf, 10, &fan_min);
349 #define FAN_UNIT_ATTRS(X) \
350 { &fan_input[X].dev_attr.attr, \
351 &fan_status[X].dev_attr.attr, \
352 &fan_div[X].dev_attr.attr, \
353 &fan_min[X].dev_attr.attr, \
368 const char *buf,
size_t count)
375 err = kstrtol(buf, 10, &val);
394 static struct attribute *pc8736x_fan_attr[][5] = {
401 { .attrs = pc8736x_fan_attr[0], },
402 { .attrs = pc8736x_fan_attr[1], },
403 { .attrs = pc8736x_fan_attr[2], },
438 const char *buf,
size_t count)
445 err = kstrtol(buf, 10, &val);
457 const char *buf,
size_t count)
464 err = kstrtol(buf, 10, &val);
531 #define CHAN_ALM_MIN 0x02
532 #define CHAN_ALM_MAX 0x04
533 #define TEMP_ALM_CRIT 0x08
585 #define VIN_UNIT_ATTRS(X) \
586 &in_input[X].dev_attr.attr, \
587 &in_status[X].dev_attr.attr, \
588 &in_min[X].dev_attr.attr, \
589 &in_max[X].dev_attr.attr, \
590 &in_min_alarm[X].dev_attr.attr, \
591 &in_max_alarm[X].dev_attr.attr
608 const char *buf,
size_t count)
614 err = kstrtoul(buf, 10, &val);
631 static struct attribute *pc8736x_vin_attr_array[] = {
643 &dev_attr_cpu0_vid.attr,
645 &dev_attr_alarms_in.attr,
649 .attrs = pc8736x_vin_attr_array,
694 const char *buf,
size_t count)
701 err = kstrtol(buf, 10, &val);
715 const char *buf,
size_t count)
722 err = kstrtol(buf, 10, &val);
735 const char *buf,
size_t count)
742 err = kstrtol(buf, 10, &val);
770 show_therm_min, set_therm_min, 0 + 11),
772 show_therm_min, set_therm_min, 1 + 11),
774 show_therm_min, set_therm_min, 2 + 11),
778 show_therm_max, set_therm_max, 0 + 11),
780 show_therm_max, set_therm_max, 1 + 11),
782 show_therm_max, set_therm_max, 2 + 11),
786 show_therm_crit, set_therm_crit, 0 + 11),
788 show_therm_crit, set_therm_crit, 1 + 11),
790 show_therm_crit, set_therm_crit, 2 + 11),
825 show_therm_min_alarm,
NULL, 0 + 11),
827 show_therm_min_alarm,
NULL, 1 + 11),
829 show_therm_min_alarm,
NULL, 2 + 11),
833 show_therm_max_alarm,
NULL, 0 + 11),
835 show_therm_max_alarm,
NULL, 1 + 11),
837 show_therm_max_alarm,
NULL, 2 + 11),
841 show_therm_crit_alarm,
NULL, 0 + 11),
843 show_therm_crit_alarm,
NULL, 1 + 11),
845 show_therm_crit_alarm,
NULL, 2 + 11),
848 #define THERM_UNIT_ATTRS(X) \
849 &therm_input[X].dev_attr.attr, \
850 &therm_status[X].dev_attr.attr, \
851 &therm_min[X].dev_attr.attr, \
852 &therm_max[X].dev_attr.attr, \
853 &therm_crit[X].dev_attr.attr, \
854 &therm_min_alarm[X].dev_attr.attr, \
855 &therm_max_alarm[X].dev_attr.attr, \
856 &therm_crit_alarm[X].dev_attr.attr
858 static struct attribute *pc8736x_therm_attr_array[] = {
865 .attrs = pc8736x_therm_attr_array,
911 const char *buf,
size_t count)
918 err = kstrtol(buf, 10, &val);
932 const char *buf,
size_t count)
939 err = kstrtol(buf, 10, &val);
960 err = kstrtol(buf, 10, &val);
984 show_temp_min, set_temp_min, 0),
986 show_temp_min, set_temp_min, 1),
988 show_temp_min, set_temp_min, 2),
992 show_temp_max, set_temp_max, 0),
994 show_temp_max, set_temp_max, 1),
996 show_temp_max, set_temp_max, 2),
1000 show_temp_crit, set_temp_crit, 0),
1002 show_temp_crit, set_temp_crit, 1),
1004 show_temp_crit, set_temp_crit, 2),
1010 struct pc87360_data *data = pc87360_update_device(dev);
1025 struct pc87360_data *data = pc87360_update_device(dev);
1034 struct pc87360_data *data = pc87360_update_device(dev);
1043 struct pc87360_data *data = pc87360_update_device(dev);
1067 #define TEMP_FAULT 0x40
1071 struct pc87360_data *data = pc87360_update_device(dev);
1082 #define TEMP_UNIT_ATTRS(X) \
1083 { &temp_input[X].dev_attr.attr, \
1084 &temp_status[X].dev_attr.attr, \
1085 &temp_min[X].dev_attr.attr, \
1086 &temp_max[X].dev_attr.attr, \
1087 &temp_crit[X].dev_attr.attr, \
1088 &temp_min_alarm[X].dev_attr.attr, \
1089 &temp_max_alarm[X].dev_attr.attr, \
1090 &temp_crit_alarm[X].dev_attr.attr, \
1091 &temp_fault[X].dev_attr.attr, \
1095 static struct attribute *pc8736x_temp_attr[][10] = {
1102 { .attrs = pc8736x_temp_attr[0] },
1103 { .attrs = pc8736x_temp_attr[1] },
1104 { .attrs = pc8736x_temp_attr[2] }
1121 unsigned short *addresses)
1130 val = force_id ? force_id : superio_inb(sioaddr,
DEVID);
1142 superio_exit(sioaddr);
1148 for (i = 0; i < nrdev; i++) {
1150 superio_outb(sioaddr,
DEV, logdev[i]);
1152 val = superio_inb(sioaddr,
ACT);
1153 if (!(val & 0x01)) {
1154 pr_info(
"Device 0x%02x not activated\n", logdev[i]);
1158 val = (superio_inb(sioaddr,
BASE) << 8)
1159 | superio_inb(sioaddr,
BASE + 1);
1161 pr_info(
"Base address not set for device 0x%02x\n",
1169 confreg[0] = superio_inb(sioaddr, 0xF0);
1170 confreg[1] = superio_inb(sioaddr, 0xF1);
1172 pr_debug(
"Fan %d: mon=%d ctrl=%d inv=%d\n", 1,
1173 (confreg[0] >> 2) & 1, (confreg[0] >> 3) & 1,
1174 (confreg[0] >> 4) & 1);
1175 pr_debug(
"Fan %d: mon=%d ctrl=%d inv=%d\n", 2,
1176 (confreg[0] >> 5) & 1, (confreg[0] >> 6) & 1,
1177 (confreg[0] >> 7) & 1);
1178 pr_debug(
"Fan %d: mon=%d ctrl=%d inv=%d\n", 3,
1179 confreg[1] & 1, (confreg[1] >> 1) & 1,
1180 (confreg[1] >> 2) & 1);
1181 }
else if (i == 1) {
1183 if (*devid == 0xE9) {
1189 confreg[2] = superio_inb(sioaddr, 0x2B);
1190 confreg[3] = superio_inb(sioaddr, 0x25);
1192 if (confreg[2] & 0x40) {
1193 pr_info(
"Using thermistors for "
1194 "temperature monitoring\n");
1196 if (confreg[3] & 0xE0) {
1197 pr_info(
"VID inputs routed (mode %u)\n",
1204 superio_exit(sioaddr);
1208 static void pc87360_remove_files(
struct device *dev)
1214 for (i = 0; i <
ARRAY_SIZE(pc8736x_temp_attr_group); i++)
1216 for (i = 0; i <
ARRAY_SIZE(pc8736x_fan_attr_group); i++) {
1229 const char *
name =
"pc87360";
1230 int use_thermistors = 0;
1251 data->
fannr = extra_isa[0] ? 3 : 0;
1252 data->
innr = extra_isa[1] ? 11 : 0;
1253 data->
tempnr = extra_isa[2] ? 2 : 0;
1257 data->
fannr = extra_isa[0] ? 3 : 0;
1258 data->
innr = extra_isa[1] ? 14 : 0;
1259 data->
tempnr = extra_isa[2] ? 3 : 0;
1267 platform_set_drvdata(pdev, data);
1273 pc87360_driver.
driver.name)) {
1274 dev_err(dev,
"Region 0x%x-0x%x already "
1275 "in use!\n", extra_isa[i],
1283 data->
fan_conf = confreg[0] | (confreg[1] << 8);
1297 data->
in_vref = (i&0x02) ? 3025 : 2966;
1298 dev_dbg(dev,
"Using %s reference voltage\n",
1299 (i&0x02) ?
"external" :
"internal");
1306 for (i = 0; i < data->
fannr; i++) {
1314 if (devid == 0xe9 && data->
address[1])
1315 use_thermistors = confreg[2] & 0x40;
1317 pc87360_init_device(pdev, use_thermistors);
1328 if (data->
innr == 14) {
1337 for (i = 0; i < data->
tempnr; i++) {
1339 &pc8736x_temp_attr_group[i]);
1348 for (i = 0; i < data->
fannr; i++) {
1351 &pc8736x_fan_attr_group[i]);
1374 pc87360_remove_files(dev);
1380 struct pc87360_data *data = platform_get_drvdata(pdev);
1383 pc87360_remove_files(&pdev->
dev);
1406 static void pc87360_write_value(
struct pc87360_data *data,
u8 ldi,
u8 bank,
1417 #define CHAN_CNVRTD 0x80
1418 #define CHAN_ENA 0x01
1419 #define CHAN_ALM_ENA 0x10
1420 #define CHAN_READY (CHAN_ENA|CHAN_CNVRTD)
1422 #define TEMP_OTS_OE 0x20
1423 #define VIN_RW1C_MASK (CHAN_READY|CHAN_ALM_MAX|CHAN_ALM_MIN)
1424 #define TEMP_RW1C_MASK (VIN_RW1C_MASK|TEMP_ALM_CRIT|TEMP_FAULT)
1427 int use_thermistors)
1429 struct pc87360_data *data = platform_get_drvdata(pdev);
1431 const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
1432 const u8 init_temp[3] = { 2, 2, 1 };
1439 "1s period, 160us delay\n");
1442 (reg & 0xC0) | 0x11);
1445 nr = data->
innr < 11 ? data->
innr : 11;
1446 for (i = 0; i <
nr; i++) {
1447 reg = pc87360_read_value(data,
LD_IN, i,
1449 dev_dbg(&pdev->
dev,
"bios in%d status:0x%02x\n", i, reg);
1450 if (
init >= init_in[i]) {
1454 "enabling in%d\n", i);
1455 pc87360_write_value(data,
LD_IN, i,
1457 (reg & 0x68) | 0x87);
1466 dev_dbg(&pdev->
dev,
"bios thermistors:%d\n", use_thermistors);
1467 for (i = 11; i < data->
innr; i++) {
1468 reg = pc87360_read_value(data,
LD_IN, i,
1470 use_thermistors = use_thermistors || (reg &
CHAN_ENA);
1472 dev_dbg(&pdev->
dev,
"bios temp%d_status:0x%02x\n", i-7, reg);
1474 dev_dbg(&pdev->
dev,
"using thermistors:%d\n", use_thermistors);
1476 i = use_thermistors ? 2 : 0;
1477 for (; i < data->
tempnr; i++) {
1478 reg = pc87360_read_value(data,
LD_TEMP, i,
1480 dev_dbg(&pdev->
dev,
"bios temp%d_status:0x%02x\n", i + 1, reg);
1481 if (
init >= init_temp[i]) {
1485 "Forcibly enabling temp%d\n", i + 1);
1486 pc87360_write_value(data,
LD_TEMP, i,
1493 if (use_thermistors) {
1494 for (i = 11; i < data->
innr; i++) {
1495 if (
init >= init_in[i]) {
1500 reg = pc87360_read_value(data,
LD_TEMP,
1504 "Skipping temp%d, pin already in use by temp%d\n",
1505 i - 7, (i - 11) / 2);
1510 reg = pc87360_read_value(data,
LD_IN, i,
1512 if (!(reg & CHAN_ENA)) {
1514 "Forcibly enabling temp%d\n",
1516 pc87360_write_value(data,
LD_IN, i,
1518 (reg & 0x60) | 0x8F);
1527 dev_dbg(&pdev->
dev,
"bios vin-cfg:0x%02x\n", reg);
1530 "Forcibly enabling monitoring (VLM)\n");
1540 dev_dbg(&pdev->
dev,
"bios temp-cfg:0x%02x\n", reg);
1543 "Forcibly enabling monitoring (TMS)\n");
1551 pc87360_write_value(data,
LD_TEMP, 0xF, 0xA, 0x08);
1566 static void pc87360_autodiv(
struct device *dev,
int nr)
1573 || (data->
fan[nr] >= 224)) {
1577 data->
fan[
nr] >>= 1;
1579 "clock divider to %d for fan %d\n",
1584 while (!(data->
fan_min[nr] & 0x80)
1585 && data->
fan[nr] < 85
1589 data->
fan[
nr] <<= 1;
1591 "clock divider to %d for fan %d\n",
1598 if (old_min != data->
fan_min[nr]) {
1613 dev_dbg(dev,
"Data update\n");
1616 for (i = 0; i < data->
fannr; i++) {
1619 pc87360_read_value(data,
LD_FAN,
1621 data->
fan[
i] = pc87360_read_value(data,
LD_FAN,
1623 data->
fan_min[
i] = pc87360_read_value(data,
1627 pc87360_autodiv(dev, i);
1634 data->
pwm[
i] = pc87360_read_value(data,
LD_FAN,
1639 for (i = 0; i < data->
innr; i++) {
1643 pc87360_write_value(data,
LD_IN, i,
1647 data->
in[
i] = pc87360_read_value(data,
LD_IN,
1651 data->
in_min[
i] = pc87360_read_value(data,
1654 data->
in_max[
i] = pc87360_read_value(data,
1659 pc87360_read_value(data,
LD_IN,
1666 | ((pc87360_read_value(data,
LD_IN,
1670 pc87360_read_value(data,
LD_IN,
1675 for (i = 0; i < data->
tempnr; i++) {
1680 pc87360_write_value(data,
LD_TEMP, i,
1683 if ((data->
temp_status[i] & CHAN_READY) == CHAN_READY) {
1684 data->
temp[
i] = pc87360_read_value(data,
1689 data->
temp_min[
i] = pc87360_read_value(data,
1692 data->
temp_max[
i] = pc87360_read_value(data,
1695 data->
temp_crit[
i] = pc87360_read_value(data,
1715 static int __init pc87360_device_add(
unsigned short address)
1723 pr_err(
"Device allocation failed\n");
1729 for (i = 0; i < 3; i++) {
1739 goto exit_device_put;
1746 pr_err(
"Device resources addition failed (%d)\n", err);
1747 goto exit_device_put;
1752 pr_err(
"Device addition failed (%d)\n", err);
1753 goto exit_device_put;
1764 static int __init pc87360_init(
void)
1767 unsigned short address = 0;
1769 if (pc87360_find(0x2e, &devid, extra_isa)
1770 && pc87360_find(0x4e, &devid, extra_isa)) {
1771 pr_warn(
"PC8736x not detected, module not inserted\n");
1776 for (i = 0; i < 3; i++) {
1777 if (extra_isa[i] != 0x0000) {
1778 address = extra_isa[
i];
1783 if (address == 0x0000) {
1784 pr_warn(
"No active logical device, module not inserted\n");
1793 err = pc87360_device_add(address);
1805 static void __exit pc87360_exit(
void)