Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Device physical location support
0004  *
0005  * Author: Won Chung <wonchung@google.com>
0006  */
0007 
0008 #include <linux/acpi.h>
0009 #include <linux/sysfs.h>
0010 
0011 #include "physical_location.h"
0012 
0013 bool dev_add_physical_location(struct device *dev)
0014 {
0015     struct acpi_pld_info *pld;
0016     acpi_status status;
0017 
0018     if (!has_acpi_companion(dev))
0019         return false;
0020 
0021     status = acpi_get_physical_device_location(ACPI_HANDLE(dev), &pld);
0022     if (ACPI_FAILURE(status))
0023         return false;
0024 
0025     dev->physical_location =
0026         kzalloc(sizeof(*dev->physical_location), GFP_KERNEL);
0027     if (!dev->physical_location)
0028         return false;
0029     dev->physical_location->panel = pld->panel;
0030     dev->physical_location->vertical_position = pld->vertical_position;
0031     dev->physical_location->horizontal_position = pld->horizontal_position;
0032     dev->physical_location->dock = pld->dock;
0033     dev->physical_location->lid = pld->lid;
0034 
0035     ACPI_FREE(pld);
0036     return true;
0037 }
0038 
0039 static ssize_t panel_show(struct device *dev, struct device_attribute *attr,
0040     char *buf)
0041 {
0042     const char *panel;
0043 
0044     switch (dev->physical_location->panel) {
0045     case DEVICE_PANEL_TOP:
0046         panel = "top";
0047         break;
0048     case DEVICE_PANEL_BOTTOM:
0049         panel = "bottom";
0050         break;
0051     case DEVICE_PANEL_LEFT:
0052         panel = "left";
0053         break;
0054     case DEVICE_PANEL_RIGHT:
0055         panel = "right";
0056         break;
0057     case DEVICE_PANEL_FRONT:
0058         panel = "front";
0059         break;
0060     case DEVICE_PANEL_BACK:
0061         panel = "back";
0062         break;
0063     default:
0064         panel = "unknown";
0065     }
0066     return sysfs_emit(buf, "%s\n", panel);
0067 }
0068 static DEVICE_ATTR_RO(panel);
0069 
0070 static ssize_t vertical_position_show(struct device *dev,
0071     struct device_attribute *attr, char *buf)
0072 {
0073     const char *vertical_position;
0074 
0075     switch (dev->physical_location->vertical_position) {
0076     case DEVICE_VERT_POS_UPPER:
0077         vertical_position = "upper";
0078         break;
0079     case DEVICE_VERT_POS_CENTER:
0080         vertical_position = "center";
0081         break;
0082     case DEVICE_VERT_POS_LOWER:
0083         vertical_position = "lower";
0084         break;
0085     default:
0086         vertical_position = "unknown";
0087     }
0088     return sysfs_emit(buf, "%s\n", vertical_position);
0089 }
0090 static DEVICE_ATTR_RO(vertical_position);
0091 
0092 static ssize_t horizontal_position_show(struct device *dev,
0093     struct device_attribute *attr, char *buf)
0094 {
0095     const char *horizontal_position;
0096 
0097     switch (dev->physical_location->horizontal_position) {
0098     case DEVICE_HORI_POS_LEFT:
0099         horizontal_position = "left";
0100         break;
0101     case DEVICE_HORI_POS_CENTER:
0102         horizontal_position = "center";
0103         break;
0104     case DEVICE_HORI_POS_RIGHT:
0105         horizontal_position = "right";
0106         break;
0107     default:
0108         horizontal_position = "unknown";
0109     }
0110     return sysfs_emit(buf, "%s\n", horizontal_position);
0111 }
0112 static DEVICE_ATTR_RO(horizontal_position);
0113 
0114 static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
0115     char *buf)
0116 {
0117     return sysfs_emit(buf, "%s\n",
0118         dev->physical_location->dock ? "yes" : "no");
0119 }
0120 static DEVICE_ATTR_RO(dock);
0121 
0122 static ssize_t lid_show(struct device *dev, struct device_attribute *attr,
0123     char *buf)
0124 {
0125     return sysfs_emit(buf, "%s\n",
0126         dev->physical_location->lid ? "yes" : "no");
0127 }
0128 static DEVICE_ATTR_RO(lid);
0129 
0130 static struct attribute *dev_attr_physical_location[] = {
0131     &dev_attr_panel.attr,
0132     &dev_attr_vertical_position.attr,
0133     &dev_attr_horizontal_position.attr,
0134     &dev_attr_dock.attr,
0135     &dev_attr_lid.attr,
0136     NULL,
0137 };
0138 
0139 const struct attribute_group dev_attr_physical_location_group = {
0140     .name = "physical_location",
0141     .attrs = dev_attr_physical_location,
0142 };
0143