@@ -4030,8 +4030,8 @@ static bool hotkey_notify_6xxx(const u32 hkey,
4030
4030
return true;
4031
4031
case TP_HKEY_EV_THM_CSM_COMPLETED :
4032
4032
pr_debug ("EC reports: Thermal Control Command set completed (DYTC)\n" );
4033
- /* recommended action: do nothing, we don't have
4034
- * Lenovo ATM information */
4033
+ /* Thermal event - pass on to event handler */
4034
+ tpacpi_driver_event ( hkey );
4035
4035
return true;
4036
4036
case TP_HKEY_EV_THM_TRANSFM_CHANGED :
4037
4037
pr_debug ("EC reports: Thermal Transformation changed (GMTS)\n" );
@@ -9803,6 +9803,105 @@ static struct ibm_struct lcdshadow_driver_data = {
9803
9803
.write = lcdshadow_write ,
9804
9804
};
9805
9805
9806
+ /*************************************************************************
9807
+ * DYTC subdriver, for the Lenovo lapmode feature
9808
+ */
9809
+
9810
+ #define DYTC_CMD_GET 2 /* To get current IC function and mode */
9811
+ #define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */
9812
+
9813
+ static bool dytc_lapmode ;
9814
+
9815
+ static void dytc_lapmode_notify_change (void )
9816
+ {
9817
+ sysfs_notify (& tpacpi_pdev -> dev .kobj , NULL , "dytc_lapmode" );
9818
+ }
9819
+
9820
+ static int dytc_command (int command , int * output )
9821
+ {
9822
+ acpi_handle dytc_handle ;
9823
+
9824
+ if (ACPI_FAILURE (acpi_get_handle (hkey_handle , "DYTC" , & dytc_handle ))) {
9825
+ /* Platform doesn't support DYTC */
9826
+ return - ENODEV ;
9827
+ }
9828
+ if (!acpi_evalf (dytc_handle , output , NULL , "dd" , command ))
9829
+ return - EIO ;
9830
+ return 0 ;
9831
+ }
9832
+
9833
+ static int dytc_lapmode_get (bool * state )
9834
+ {
9835
+ int output , err ;
9836
+
9837
+ err = dytc_command (DYTC_CMD_GET , & output );
9838
+ if (err )
9839
+ return err ;
9840
+ * state = output & BIT (DYTC_GET_LAPMODE_BIT ) ? true : false;
9841
+ return 0 ;
9842
+ }
9843
+
9844
+ static void dytc_lapmode_refresh (void )
9845
+ {
9846
+ bool new_state ;
9847
+ int err ;
9848
+
9849
+ err = dytc_lapmode_get (& new_state );
9850
+ if (err || (new_state == dytc_lapmode ))
9851
+ return ;
9852
+
9853
+ dytc_lapmode = new_state ;
9854
+ dytc_lapmode_notify_change ();
9855
+ }
9856
+
9857
+ /* sysfs lapmode entry */
9858
+ static ssize_t dytc_lapmode_show (struct device * dev ,
9859
+ struct device_attribute * attr ,
9860
+ char * buf )
9861
+ {
9862
+ return snprintf (buf , PAGE_SIZE , "%d\n" , dytc_lapmode );
9863
+ }
9864
+
9865
+ static DEVICE_ATTR_RO (dytc_lapmode );
9866
+
9867
+ static struct attribute * dytc_attributes [] = {
9868
+ & dev_attr_dytc_lapmode .attr ,
9869
+ NULL ,
9870
+ };
9871
+
9872
+ static const struct attribute_group dytc_attr_group = {
9873
+ .attrs = dytc_attributes ,
9874
+ };
9875
+
9876
+ static int tpacpi_dytc_init (struct ibm_init_struct * iibm )
9877
+ {
9878
+ int err ;
9879
+
9880
+ err = dytc_lapmode_get (& dytc_lapmode );
9881
+ /* If support isn't available (ENODEV) then don't return an error
9882
+ * but just don't create the sysfs group
9883
+ */
9884
+ if (err == - ENODEV )
9885
+ return 0 ;
9886
+ /* For all other errors we can flag the failure */
9887
+ if (err )
9888
+ return err ;
9889
+
9890
+ /* Platform supports this feature - create the group */
9891
+ err = sysfs_create_group (& tpacpi_pdev -> dev .kobj , & dytc_attr_group );
9892
+ return err ;
9893
+ }
9894
+
9895
+ static void dytc_exit (void )
9896
+ {
9897
+ sysfs_remove_group (& tpacpi_pdev -> dev .kobj , & dytc_attr_group );
9898
+ }
9899
+
9900
+ static struct ibm_struct dytc_driver_data = {
9901
+ .name = "dytc" ,
9902
+ .exit = dytc_exit ,
9903
+ };
9904
+
9806
9905
/****************************************************************************
9807
9906
****************************************************************************
9808
9907
*
@@ -9850,6 +9949,10 @@ static void tpacpi_driver_event(const unsigned int hkey_event)
9850
9949
9851
9950
mutex_unlock (& kbdlight_mutex );
9852
9951
}
9952
+
9953
+ if (hkey_event == TP_HKEY_EV_THM_CSM_COMPLETED )
9954
+ dytc_lapmode_refresh ();
9955
+
9853
9956
}
9854
9957
9855
9958
static void hotkey_driver_event (const unsigned int scancode )
@@ -10288,6 +10391,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
10288
10391
.init = tpacpi_lcdshadow_init ,
10289
10392
.data = & lcdshadow_driver_data ,
10290
10393
},
10394
+ {
10395
+ .init = tpacpi_dytc_init ,
10396
+ .data = & dytc_driver_data ,
10397
+ },
10291
10398
};
10292
10399
10293
10400
static int __init set_ibm_param (const char * val , const struct kernel_param * kp )
0 commit comments