aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c122
1 files changed, 121 insertions, 1 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index c8d74dbacbbd..27ca676a7092 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -264,6 +264,7 @@ static struct {
264 u32 wan:1; 264 u32 wan:1;
265 u32 uwb:1; 265 u32 uwb:1;
266 u32 fan_ctrl_status_undef:1; 266 u32 fan_ctrl_status_undef:1;
267 u32 second_fan:1;
267 u32 beep_needs_two_args:1; 268 u32 beep_needs_two_args:1;
268 u32 input_device_registered:1; 269 u32 input_device_registered:1;
269 u32 platform_drv_registered:1; 270 u32 platform_drv_registered:1;
@@ -6298,6 +6299,21 @@ static struct ibm_struct volume_driver_data = {
6298 * For firmware bugs, refer to: 6299 * For firmware bugs, refer to:
6299 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 6300 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
6300 * 6301 *
6302 * ----
6303 *
6304 * ThinkPad EC register 0x31 bit 0 (only on select models)
6305 *
6306 * When bit 0 of EC register 0x31 is zero, the tachometer registers
6307 * show the speed of the main fan. When bit 0 of EC register 0x31
6308 * is one, the tachometer registers show the speed of the auxiliary
6309 * fan.
6310 *
6311 * Fan control seems to affect both fans, regardless of the state
6312 * of this bit.
6313 *
6314 * So far, only the firmware for the X60/X61 non-tablet versions
6315 * seem to support this (firmware TP-7M).
6316 *
6301 * TPACPI_FAN_WR_ACPI_FANS: 6317 * TPACPI_FAN_WR_ACPI_FANS:
6302 * ThinkPad X31, X40, X41. Not available in the X60. 6318 * ThinkPad X31, X40, X41. Not available in the X60.
6303 * 6319 *
@@ -6324,6 +6340,8 @@ enum { /* Fan control constants */
6324 fan_status_offset = 0x2f, /* EC register 0x2f */ 6340 fan_status_offset = 0x2f, /* EC register 0x2f */
6325 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) 6341 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
6326 * 0x84 must be read before 0x85 */ 6342 * 0x84 must be read before 0x85 */
6343 fan_select_offset = 0x31, /* EC register 0x31 (Firmware 7M)
6344 bit 0 selects which fan is active */
6327 6345
6328 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */ 6346 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */
6329 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */ 6347 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */
@@ -6417,6 +6435,38 @@ static void fan_quirk1_handle(u8 *fan_status)
6417 } 6435 }
6418} 6436}
6419 6437
6438/* Select main fan on X60/X61, NOOP on others */
6439static bool fan_select_fan1(void)
6440{
6441 if (tp_features.second_fan) {
6442 u8 val;
6443
6444 if (ec_read(fan_select_offset, &val) < 0)
6445 return false;
6446 val &= 0xFEU;
6447 if (ec_write(fan_select_offset, val) < 0)
6448 return false;
6449 }
6450 return true;
6451}
6452
6453/* Select secondary fan on X60/X61 */
6454static bool fan_select_fan2(void)
6455{
6456 u8 val;
6457
6458 if (!tp_features.second_fan)
6459 return false;
6460
6461 if (ec_read(fan_select_offset, &val) < 0)
6462 return false;
6463 val |= 0x01U;
6464 if (ec_write(fan_select_offset, val) < 0)
6465 return false;
6466
6467 return true;
6468}
6469
6420/* 6470/*
6421 * Call with fan_mutex held 6471 * Call with fan_mutex held
6422 */ 6472 */
@@ -6494,6 +6544,8 @@ static int fan_get_speed(unsigned int *speed)
6494 switch (fan_status_access_mode) { 6544 switch (fan_status_access_mode) {
6495 case TPACPI_FAN_RD_TPEC: 6545 case TPACPI_FAN_RD_TPEC:
6496 /* all except 570, 600e/x, 770e, 770x */ 6546 /* all except 570, 600e/x, 770e, 770x */
6547 if (unlikely(!fan_select_fan1()))
6548 return -EIO;
6497 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || 6549 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
6498 !acpi_ec_read(fan_rpm_offset + 1, &hi))) 6550 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
6499 return -EIO; 6551 return -EIO;
@@ -6510,6 +6562,34 @@ static int fan_get_speed(unsigned int *speed)
6510 return 0; 6562 return 0;
6511} 6563}
6512 6564
6565static int fan2_get_speed(unsigned int *speed)
6566{
6567 u8 hi, lo;
6568 bool rc;
6569
6570 switch (fan_status_access_mode) {
6571 case TPACPI_FAN_RD_TPEC:
6572 /* all except 570, 600e/x, 770e, 770x */
6573 if (unlikely(!fan_select_fan2()))
6574 return -EIO;
6575 rc = !acpi_ec_read(fan_rpm_offset, &lo) ||
6576 !acpi_ec_read(fan_rpm_offset + 1, &hi);
6577 fan_select_fan1(); /* play it safe */
6578 if (rc)
6579 return -EIO;
6580
6581 if (likely(speed))
6582 *speed = (hi << 8) | lo;
6583
6584 break;
6585
6586 default:
6587 return -ENXIO;
6588 }
6589
6590 return 0;
6591}
6592
6513static int fan_set_level(int level) 6593static int fan_set_level(int level)
6514{ 6594{
6515 if (!fan_control_allowed) 6595 if (!fan_control_allowed)
@@ -6915,6 +6995,25 @@ static struct device_attribute dev_attr_fan_fan1_input =
6915 __ATTR(fan1_input, S_IRUGO, 6995 __ATTR(fan1_input, S_IRUGO,
6916 fan_fan1_input_show, NULL); 6996 fan_fan1_input_show, NULL);
6917 6997
6998/* sysfs fan fan2_input ------------------------------------------------ */
6999static ssize_t fan_fan2_input_show(struct device *dev,
7000 struct device_attribute *attr,
7001 char *buf)
7002{
7003 int res;
7004 unsigned int speed;
7005
7006 res = fan2_get_speed(&speed);
7007 if (res < 0)
7008 return res;
7009
7010 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
7011}
7012
7013static struct device_attribute dev_attr_fan_fan2_input =
7014 __ATTR(fan2_input, S_IRUGO,
7015 fan_fan2_input_show, NULL);
7016
6918/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ 7017/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
6919static ssize_t fan_fan_watchdog_show(struct device_driver *drv, 7018static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
6920 char *buf) 7019 char *buf)
@@ -6948,6 +7047,7 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
6948static struct attribute *fan_attributes[] = { 7047static struct attribute *fan_attributes[] = {
6949 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, 7048 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
6950 &dev_attr_fan_fan1_input.attr, 7049 &dev_attr_fan_fan1_input.attr,
7050 NULL, /* for fan2_input */
6951 NULL 7051 NULL
6952}; 7052};
6953 7053
@@ -6955,7 +7055,8 @@ static const struct attribute_group fan_attr_group = {
6955 .attrs = fan_attributes, 7055 .attrs = fan_attributes,
6956}; 7056};
6957 7057
6958#define TPACPI_FAN_Q1 0x0001 7058#define TPACPI_FAN_Q1 0x0001 /* Unitialized HFSP */
7059#define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */
6959 7060
6960#define TPACPI_FAN_QI(__id1, __id2, __quirks) \ 7061#define TPACPI_FAN_QI(__id1, __id2, __quirks) \
6961 { .vendor = PCI_VENDOR_ID_IBM, \ 7062 { .vendor = PCI_VENDOR_ID_IBM, \
@@ -6963,13 +7064,21 @@ static const struct attribute_group fan_attr_group = {
6963 .ec = TPID(__id1, __id2), \ 7064 .ec = TPID(__id1, __id2), \
6964 .quirks = __quirks } 7065 .quirks = __quirks }
6965 7066
7067#define TPACPI_FAN_QL(__id1, __id2, __quirks) \
7068 { .vendor = PCI_VENDOR_ID_LENOVO, \
7069 .bios = TPACPI_MATCH_ANY, \
7070 .ec = TPID(__id1, __id2), \
7071 .quirks = __quirks }
7072
6966static const struct tpacpi_quirk fan_quirk_table[] __initconst = { 7073static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
6967 TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1), 7074 TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1),
6968 TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1), 7075 TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1),
6969 TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1), 7076 TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
6970 TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1), 7077 TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
7078 TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
6971}; 7079};
6972 7080
7081#undef TPACPI_FAN_QL
6973#undef TPACPI_FAN_QI 7082#undef TPACPI_FAN_QI
6974 7083
6975static int __init fan_init(struct ibm_init_struct *iibm) 7084static int __init fan_init(struct ibm_init_struct *iibm)
@@ -6986,6 +7095,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6986 fan_control_commands = 0; 7095 fan_control_commands = 0;
6987 fan_watchdog_maxinterval = 0; 7096 fan_watchdog_maxinterval = 0;
6988 tp_features.fan_ctrl_status_undef = 0; 7097 tp_features.fan_ctrl_status_undef = 0;
7098 tp_features.second_fan = 0;
6989 fan_control_desired_level = 7; 7099 fan_control_desired_level = 7;
6990 7100
6991 TPACPI_ACPIHANDLE_INIT(fans); 7101 TPACPI_ACPIHANDLE_INIT(fans);
@@ -7006,6 +7116,11 @@ static int __init fan_init(struct ibm_init_struct *iibm)
7006 fan_status_access_mode = TPACPI_FAN_RD_TPEC; 7116 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
7007 if (quirks & TPACPI_FAN_Q1) 7117 if (quirks & TPACPI_FAN_Q1)
7008 fan_quirk1_setup(); 7118 fan_quirk1_setup();
7119 if (quirks & TPACPI_FAN_2FAN) {
7120 tp_features.second_fan = 1;
7121 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
7122 "secondary fan support enabled\n");
7123 }
7009 } else { 7124 } else {
7010 printk(TPACPI_ERR 7125 printk(TPACPI_ERR
7011 "ThinkPad ACPI EC access misbehaving, " 7126 "ThinkPad ACPI EC access misbehaving, "
@@ -7061,6 +7176,11 @@ static int __init fan_init(struct ibm_init_struct *iibm)
7061 7176
7062 if (fan_status_access_mode != TPACPI_FAN_NONE || 7177 if (fan_status_access_mode != TPACPI_FAN_NONE ||
7063 fan_control_access_mode != TPACPI_FAN_WR_NONE) { 7178 fan_control_access_mode != TPACPI_FAN_WR_NONE) {
7179 if (tp_features.second_fan) {
7180 /* attach second fan tachometer */
7181 fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
7182 &dev_attr_fan_fan2_input.attr;
7183 }
7064 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 7184 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
7065 &fan_attr_group); 7185 &fan_attr_group);
7066 if (rc < 0) 7186 if (rc < 0)