@@ -388,6 +388,10 @@ static const struct dmi_system_id gmin_vars[] = {
388
388
0xa9, 0x71, 0xe8, 0x77, \
389
389
0x75, 0x60, 0x68, 0xf7)
390
390
391
+ static const guid_t atomisp_dsm_guid = GUID_INIT (0xdc2f6c4f , 0x045b , 0x4f1d ,
392
+ 0x97 , 0xb9 , 0x88 , 0x2a ,
393
+ 0x68 , 0x60 , 0xa4 , 0xbe );
394
+
391
395
#define CFG_VAR_NAME_MAX 64
392
396
393
397
#define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */
@@ -455,15 +459,28 @@ static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg,
455
459
456
460
static struct gmin_subdev * gmin_subdev_add (struct v4l2_subdev * subdev )
457
461
{
458
- int i , ret ;
459
- struct device * dev ;
460
462
struct i2c_client * power = NULL , * client = v4l2_get_subdevdata (subdev );
463
+ struct acpi_device * adev ;
464
+ acpi_handle handle ;
465
+ struct device * dev ;
466
+ int i , ret ;
461
467
462
468
if (!client )
463
469
return NULL ;
464
470
465
471
dev = & client -> dev ;
466
472
473
+ handle = ACPI_HANDLE (dev );
474
+
475
+ // FIXME: may need to release resources allocated by acpi_bus_get_device()
476
+ if (!handle || acpi_bus_get_device (handle , & adev )) {
477
+ dev_err (dev , "Error could not get ACPI device\n" );
478
+ return NULL ;
479
+ }
480
+
481
+ dev_info (& client -> dev , "%s: ACPI detected it on bus ID=%s, HID=%s\n" ,
482
+ __func__ , acpi_device_bid (adev ), acpi_device_hid (adev ));
483
+
467
484
if (!pmic_id ) {
468
485
if (gmin_i2c_dev_exists (dev , PMIC_ACPI_TI , & power ))
469
486
pmic_id = PMIC_TI ;
@@ -944,6 +961,75 @@ static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
944
961
return - EINVAL ;
945
962
}
946
963
964
+
965
+ static int gmin_get_config_dsm_var (struct device * dev ,
966
+ const char * var ,
967
+ char * out , size_t * out_len )
968
+ {
969
+ acpi_handle handle = ACPI_HANDLE (dev );
970
+ union acpi_object * obj , * cur = NULL ;
971
+ int i ;
972
+
973
+ obj = acpi_evaluate_dsm (handle , & atomisp_dsm_guid , 0 , 0 , NULL );
974
+ if (!obj ) {
975
+ dev_info_once (dev , "Didn't find ACPI _DSM table.\n" );
976
+ return - EINVAL ;
977
+ }
978
+
979
+ #if 0 /* Just for debugging purposes */
980
+ for (i = 0 ; i < obj -> package .count ; i ++ ) {
981
+ union acpi_object * cur = & obj -> package .elements [i ];
982
+
983
+ if (cur -> type == ACPI_TYPE_INTEGER )
984
+ dev_info (dev , "object #%d, type %d, value: %lld\n" ,
985
+ i , cur -> type , cur -> integer .value );
986
+ else if (cur -> type == ACPI_TYPE_STRING )
987
+ dev_info (dev , "object #%d, type %d, string: %s\n" ,
988
+ i , cur -> type , cur -> string .pointer );
989
+ else
990
+ dev_info (dev , "object #%d, type %d\n" ,
991
+ i , cur -> type );
992
+ }
993
+ #endif
994
+
995
+ /* Seek for the desired var */
996
+ for (i = 0 ; i < obj -> package .count - 1 ; i += 2 ) {
997
+ if (obj -> package .elements [i ].type == ACPI_TYPE_STRING &&
998
+ !strcmp (obj -> package .elements [i ].string .pointer , var )) {
999
+ /* Next element should be the required value */
1000
+ cur = & obj -> package .elements [i + 1 ];
1001
+ break ;
1002
+ }
1003
+ }
1004
+
1005
+ if (!cur ) {
1006
+ dev_info (dev , "didn't found _DSM entry for '%s'\n" , var );
1007
+ ACPI_FREE (obj );
1008
+ return - EINVAL ;
1009
+ }
1010
+
1011
+ /*
1012
+ * While it could be possible to have an ACPI_TYPE_INTEGER,
1013
+ * and read the value from cur->integer.value, the table
1014
+ * seen so far uses the string type. So, produce a warning
1015
+ * if it founds something different than string, letting it
1016
+ * to fall back to the old code.
1017
+ */
1018
+ if (cur && cur -> type != ACPI_TYPE_STRING ) {
1019
+ dev_info (dev , "found non-string _DSM entry for '%s'\n" , var );
1020
+ ACPI_FREE (obj );
1021
+ return - EINVAL ;
1022
+ }
1023
+
1024
+ dev_info (dev , "found _DSM entry for '%s': %s\n" , var ,
1025
+ cur -> string .pointer );
1026
+ strscpy (out , cur -> string .pointer , * out_len );
1027
+ * out_len = strlen (cur -> string .pointer );
1028
+
1029
+ ACPI_FREE (obj );
1030
+ return 0 ;
1031
+ }
1032
+
947
1033
/* Retrieves a device-specific configuration variable. The dev
948
1034
* argument should be a device with an ACPI companion, as all
949
1035
* configuration is based on firmware ID.
@@ -953,12 +1039,21 @@ static int gmin_get_config_var(struct device *maindev,
953
1039
const char * var ,
954
1040
char * out , size_t * out_len )
955
1041
{
956
- char var8 [CFG_VAR_NAME_MAX ];
957
1042
efi_char16_t var16 [CFG_VAR_NAME_MAX ];
958
- struct efivar_entry * ev ;
959
1043
const struct dmi_system_id * id ;
960
- int i , ret ;
961
1044
struct device * dev = maindev ;
1045
+ char var8 [CFG_VAR_NAME_MAX ];
1046
+ struct efivar_entry * ev ;
1047
+ int i , ret ;
1048
+
1049
+ /* For sensors, try first to use the _DSM table */
1050
+ if (!is_gmin ) {
1051
+ ret = gmin_get_config_dsm_var (maindev , var , out , out_len );
1052
+ if (!ret )
1053
+ return 0 ;
1054
+ }
1055
+
1056
+ /* Fall-back to other approaches */
962
1057
963
1058
if (!is_gmin && ACPI_COMPANION (dev ))
964
1059
dev = & ACPI_COMPANION (dev )-> dev ;
0 commit comments