@@ -7948,15 +7948,31 @@ static struct ibm_struct volume_driver_data = {
7948
7948
* TPACPI_FAN_WR_TPEC is also available and should be used to
7949
7949
* command the fan. The X31/X40/X41 seems to have 8 fan levels,
7950
7950
* but the ACPI tables just mention level 7.
7951
+ *
7952
+ * TPACPI_FAN_RD_TPEC_NS:
7953
+ * This mode is used for a few ThinkPads (L13 Yoga Gen2, X13 Yoga Gen2 etc.)
7954
+ * that are using non-standard EC locations for reporting fan speeds.
7955
+ * Currently these platforms only provide fan rpm reporting.
7956
+ *
7951
7957
*/
7952
7958
7959
+ #define FAN_RPM_CAL_CONST 491520 /* FAN RPM calculation offset for some non-standard ECFW */
7960
+
7961
+ #define FAN_NS_CTRL_STATUS BIT(2) /* Bit which determines control is enabled or not */
7962
+ #define FAN_NS_CTRL BIT(4) /* Bit which determines control is by host or EC */
7963
+
7953
7964
enum { /* Fan control constants */
7954
7965
fan_status_offset = 0x2f , /* EC register 0x2f */
7955
7966
fan_rpm_offset = 0x84 , /* EC register 0x84: LSB, 0x85 MSB (RPM)
7956
7967
* 0x84 must be read before 0x85 */
7957
7968
fan_select_offset = 0x31 , /* EC register 0x31 (Firmware 7M)
7958
7969
bit 0 selects which fan is active */
7959
7970
7971
+ fan_status_offset_ns = 0x93 , /* Special status/control offset for non-standard EC Fan1 */
7972
+ fan2_status_offset_ns = 0x96 , /* Special status/control offset for non-standard EC Fan2 */
7973
+ fan_rpm_status_ns = 0x95 , /* Special offset for Fan1 RPM status for non-standard EC */
7974
+ fan2_rpm_status_ns = 0x98 , /* Special offset for Fan2 RPM status for non-standard EC */
7975
+
7960
7976
TP_EC_FAN_FULLSPEED = 0x40 , /* EC fan mode: full speed */
7961
7977
TP_EC_FAN_AUTO = 0x80 , /* EC fan mode: auto fan control */
7962
7978
@@ -7967,6 +7983,7 @@ enum fan_status_access_mode {
7967
7983
TPACPI_FAN_NONE = 0 , /* No fan status or control */
7968
7984
TPACPI_FAN_RD_ACPI_GFAN , /* Use ACPI GFAN */
7969
7985
TPACPI_FAN_RD_TPEC , /* Use ACPI EC regs 0x2f, 0x84-0x85 */
7986
+ TPACPI_FAN_RD_TPEC_NS , /* Use non-standard ACPI EC regs (eg: L13 Yoga gen2 etc.) */
7970
7987
};
7971
7988
7972
7989
enum fan_control_access_mode {
@@ -7994,6 +8011,8 @@ static u8 fan_control_desired_level;
7994
8011
static u8 fan_control_resume_level ;
7995
8012
static int fan_watchdog_maxinterval ;
7996
8013
8014
+ static bool fan_with_ns_addr ;
8015
+
7997
8016
static struct mutex fan_mutex ;
7998
8017
7999
8018
static void fan_watchdog_fire (struct work_struct * ignored );
@@ -8123,6 +8142,15 @@ static int fan_get_status(u8 *status)
8123
8142
}
8124
8143
8125
8144
break ;
8145
+ case TPACPI_FAN_RD_TPEC_NS :
8146
+ /* Default mode is AUTO which means controlled by EC */
8147
+ if (!acpi_ec_read (fan_status_offset_ns , & s ))
8148
+ return - EIO ;
8149
+
8150
+ if (status )
8151
+ * status = s ;
8152
+
8153
+ break ;
8126
8154
8127
8155
default :
8128
8156
return - ENXIO ;
@@ -8139,7 +8167,8 @@ static int fan_get_status_safe(u8 *status)
8139
8167
if (mutex_lock_killable (& fan_mutex ))
8140
8168
return - ERESTARTSYS ;
8141
8169
rc = fan_get_status (& s );
8142
- if (!rc )
8170
+ /* NS EC doesn't have register with level settings */
8171
+ if (!rc && !fan_with_ns_addr )
8143
8172
fan_update_desired_level (s );
8144
8173
mutex_unlock (& fan_mutex );
8145
8174
@@ -8166,7 +8195,13 @@ static int fan_get_speed(unsigned int *speed)
8166
8195
8167
8196
if (likely (speed ))
8168
8197
* speed = (hi << 8 ) | lo ;
8198
+ break ;
8199
+ case TPACPI_FAN_RD_TPEC_NS :
8200
+ if (!acpi_ec_read (fan_rpm_status_ns , & lo ))
8201
+ return - EIO ;
8169
8202
8203
+ if (speed )
8204
+ * speed = lo ? FAN_RPM_CAL_CONST / lo : 0 ;
8170
8205
break ;
8171
8206
8172
8207
default :
@@ -8178,7 +8213,7 @@ static int fan_get_speed(unsigned int *speed)
8178
8213
8179
8214
static int fan2_get_speed (unsigned int * speed )
8180
8215
{
8181
- u8 hi , lo ;
8216
+ u8 hi , lo , status ;
8182
8217
bool rc ;
8183
8218
8184
8219
switch (fan_status_access_mode ) {
@@ -8194,7 +8229,21 @@ static int fan2_get_speed(unsigned int *speed)
8194
8229
8195
8230
if (likely (speed ))
8196
8231
* speed = (hi << 8 ) | lo ;
8232
+ break ;
8197
8233
8234
+ case TPACPI_FAN_RD_TPEC_NS :
8235
+ rc = !acpi_ec_read (fan2_status_offset_ns , & status );
8236
+ if (rc )
8237
+ return - EIO ;
8238
+ if (!(status & FAN_NS_CTRL_STATUS )) {
8239
+ pr_info ("secondary fan control not supported\n" );
8240
+ return - EIO ;
8241
+ }
8242
+ rc = !acpi_ec_read (fan2_rpm_status_ns , & lo );
8243
+ if (rc )
8244
+ return - EIO ;
8245
+ if (speed )
8246
+ * speed = lo ? FAN_RPM_CAL_CONST / lo : 0 ;
8198
8247
break ;
8199
8248
8200
8249
default :
@@ -8697,6 +8746,7 @@ static const struct attribute_group fan_driver_attr_group = {
8697
8746
#define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */
8698
8747
#define TPACPI_FAN_2CTL 0x0004 /* selects fan2 control */
8699
8748
#define TPACPI_FAN_NOFAN 0x0008 /* no fan available */
8749
+ #define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */
8700
8750
8701
8751
static const struct tpacpi_quirk fan_quirk_table [] __initconst = {
8702
8752
TPACPI_QEC_IBM ('1' , 'Y' , TPACPI_FAN_Q1 ),
@@ -8715,6 +8765,8 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
8715
8765
TPACPI_Q_LNV3 ('N' , '2' , 'O' , TPACPI_FAN_2CTL ), /* P1 / X1 Extreme (2nd gen) */
8716
8766
TPACPI_Q_LNV3 ('N' , '3' , '0' , TPACPI_FAN_2CTL ), /* P15 (1st gen) / P15v (1st gen) */
8717
8767
TPACPI_Q_LNV3 ('N' , '3' , '7' , TPACPI_FAN_2CTL ), /* T15g (2nd gen) */
8768
+ TPACPI_Q_LNV3 ('R' , '1' , 'F' , TPACPI_FAN_NS ), /* L13 Yoga Gen 2 */
8769
+ TPACPI_Q_LNV3 ('N' , '2' , 'U' , TPACPI_FAN_NS ), /* X13 Yoga Gen 2*/
8718
8770
TPACPI_Q_LNV3 ('N' , '1' , 'O' , TPACPI_FAN_NOFAN ), /* X1 Tablet (2nd gen) */
8719
8771
};
8720
8772
@@ -8749,18 +8801,27 @@ static int __init fan_init(struct ibm_init_struct *iibm)
8749
8801
return - ENODEV ;
8750
8802
}
8751
8803
8804
+ if (quirks & TPACPI_FAN_NS ) {
8805
+ pr_info ("ECFW with non-standard fan reg control found\n" );
8806
+ fan_with_ns_addr = 1 ;
8807
+ /* Fan ctrl support from host is undefined for now */
8808
+ tp_features .fan_ctrl_status_undef = 1 ;
8809
+ }
8810
+
8752
8811
if (gfan_handle ) {
8753
8812
/* 570, 600e/x, 770e, 770x */
8754
8813
fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN ;
8755
8814
} else {
8756
8815
/* all other ThinkPads: note that even old-style
8757
8816
* ThinkPad ECs supports the fan control register */
8758
- if (likely ( acpi_ec_read ( fan_status_offset ,
8759
- & fan_control_initial_status ))) {
8817
+ if (fan_with_ns_addr ||
8818
+ likely ( acpi_ec_read ( fan_status_offset , & fan_control_initial_status ))) {
8760
8819
int res ;
8761
8820
unsigned int speed ;
8762
8821
8763
- fan_status_access_mode = TPACPI_FAN_RD_TPEC ;
8822
+ fan_status_access_mode = fan_with_ns_addr ?
8823
+ TPACPI_FAN_RD_TPEC_NS : TPACPI_FAN_RD_TPEC ;
8824
+
8764
8825
if (quirks & TPACPI_FAN_Q1 )
8765
8826
fan_quirk1_setup ();
8766
8827
/* Try and probe the 2nd fan */
@@ -8769,7 +8830,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
8769
8830
if (res >= 0 && speed != FAN_NOT_PRESENT ) {
8770
8831
/* It responded - so let's assume it's there */
8771
8832
tp_features .second_fan = 1 ;
8772
- tp_features .second_fan_ctl = 1 ;
8833
+ /* fan control not currently available for ns ECFW */
8834
+ tp_features .second_fan_ctl = !fan_with_ns_addr ;
8773
8835
pr_info ("secondary fan control detected & enabled\n" );
8774
8836
} else {
8775
8837
/* Fan not auto-detected */
@@ -8944,6 +9006,7 @@ static int fan_read(struct seq_file *m)
8944
9006
str_enabled_disabled (status ), status );
8945
9007
break ;
8946
9008
9009
+ case TPACPI_FAN_RD_TPEC_NS :
8947
9010
case TPACPI_FAN_RD_TPEC :
8948
9011
/* all except 570, 600e/x, 770e, 770x */
8949
9012
rc = fan_get_status_safe (& status );
@@ -8958,13 +9021,22 @@ static int fan_read(struct seq_file *m)
8958
9021
8959
9022
seq_printf (m , "speed:\t\t%d\n" , speed );
8960
9023
8961
- if (status & TP_EC_FAN_FULLSPEED )
8962
- /* Disengaged mode takes precedence */
8963
- seq_printf (m , "level:\t\tdisengaged\n" );
8964
- else if (status & TP_EC_FAN_AUTO )
8965
- seq_printf (m , "level:\t\tauto\n" );
8966
- else
8967
- seq_printf (m , "level:\t\t%d\n" , status );
9024
+ if (fan_status_access_mode == TPACPI_FAN_RD_TPEC_NS ) {
9025
+ /*
9026
+ * No full speed bit in NS EC
9027
+ * EC Auto mode is set by default.
9028
+ * No other levels settings available
9029
+ */
9030
+ seq_printf (m , "level:\t\t%s\n" , status & FAN_NS_CTRL ? "unknown" : "auto" );
9031
+ } else {
9032
+ if (status & TP_EC_FAN_FULLSPEED )
9033
+ /* Disengaged mode takes precedence */
9034
+ seq_printf (m , "level:\t\tdisengaged\n" );
9035
+ else if (status & TP_EC_FAN_AUTO )
9036
+ seq_printf (m , "level:\t\tauto\n" );
9037
+ else
9038
+ seq_printf (m , "level:\t\t%d\n" , status );
9039
+ }
8968
9040
break ;
8969
9041
8970
9042
case TPACPI_FAN_NONE :
0 commit comments