1 // SPDX-License-Identifier: GPL-2.0
3 * Device physical location support
5 * Author: Won Chung <wonchung@google.com>
8 #include <linux/acpi.h>
9 #include <linux/sysfs.h>
11 #include "physical_location.h"
13 bool dev_add_physical_location(struct device
*dev
)
15 struct acpi_pld_info
*pld
;
18 if (!has_acpi_companion(dev
))
21 status
= acpi_get_physical_device_location(ACPI_HANDLE(dev
), &pld
);
22 if (ACPI_FAILURE(status
))
25 dev
->physical_location
=
26 kzalloc(sizeof(*dev
->physical_location
), GFP_KERNEL
);
27 if (!dev
->physical_location
) {
32 dev
->physical_location
->panel
= pld
->panel
;
33 dev
->physical_location
->vertical_position
= pld
->vertical_position
;
34 dev
->physical_location
->horizontal_position
= pld
->horizontal_position
;
35 dev
->physical_location
->dock
= pld
->dock
;
36 dev
->physical_location
->lid
= pld
->lid
;
42 static ssize_t
panel_show(struct device
*dev
, struct device_attribute
*attr
,
47 switch (dev
->physical_location
->panel
) {
48 case DEVICE_PANEL_TOP
:
51 case DEVICE_PANEL_BOTTOM
:
54 case DEVICE_PANEL_LEFT
:
57 case DEVICE_PANEL_RIGHT
:
60 case DEVICE_PANEL_FRONT
:
63 case DEVICE_PANEL_BACK
:
69 return sysfs_emit(buf
, "%s\n", panel
);
71 static DEVICE_ATTR_RO(panel
);
73 static ssize_t
vertical_position_show(struct device
*dev
,
74 struct device_attribute
*attr
, char *buf
)
76 const char *vertical_position
;
78 switch (dev
->physical_location
->vertical_position
) {
79 case DEVICE_VERT_POS_UPPER
:
80 vertical_position
= "upper";
82 case DEVICE_VERT_POS_CENTER
:
83 vertical_position
= "center";
85 case DEVICE_VERT_POS_LOWER
:
86 vertical_position
= "lower";
89 vertical_position
= "unknown";
91 return sysfs_emit(buf
, "%s\n", vertical_position
);
93 static DEVICE_ATTR_RO(vertical_position
);
95 static ssize_t
horizontal_position_show(struct device
*dev
,
96 struct device_attribute
*attr
, char *buf
)
98 const char *horizontal_position
;
100 switch (dev
->physical_location
->horizontal_position
) {
101 case DEVICE_HORI_POS_LEFT
:
102 horizontal_position
= "left";
104 case DEVICE_HORI_POS_CENTER
:
105 horizontal_position
= "center";
107 case DEVICE_HORI_POS_RIGHT
:
108 horizontal_position
= "right";
111 horizontal_position
= "unknown";
113 return sysfs_emit(buf
, "%s\n", horizontal_position
);
115 static DEVICE_ATTR_RO(horizontal_position
);
117 static ssize_t
dock_show(struct device
*dev
, struct device_attribute
*attr
,
120 return sysfs_emit(buf
, "%s\n",
121 dev
->physical_location
->dock
? "yes" : "no");
123 static DEVICE_ATTR_RO(dock
);
125 static ssize_t
lid_show(struct device
*dev
, struct device_attribute
*attr
,
128 return sysfs_emit(buf
, "%s\n",
129 dev
->physical_location
->lid
? "yes" : "no");
131 static DEVICE_ATTR_RO(lid
);
133 static struct attribute
*dev_attr_physical_location
[] = {
134 &dev_attr_panel
.attr
,
135 &dev_attr_vertical_position
.attr
,
136 &dev_attr_horizontal_position
.attr
,
142 const struct attribute_group dev_attr_physical_location_group
= {
143 .name
= "physical_location",
144 .attrs
= dev_attr_physical_location
,