// SPDX-License-Identifier: GPL-2.0
/*
 * Device physical location support
 *
 * Author: Won Chung <wonchung@google.com>
 */

#include <linux/acpi.h>
#include <linux/sysfs.h>

#include "physical_location.h"

bool dev_add_physical_location(struct device *dev)
{
	struct acpi_pld_info *pld;

	if (!has_acpi_companion(dev))
		return false;

	if (!acpi_get_physical_device_location(ACPI_HANDLE(dev), &pld))
		return false;

	dev->physical_location =
		kzalloc(sizeof(*dev->physical_location), GFP_KERNEL);
	if (!dev->physical_location) {
		ACPI_FREE(pld);
		return false;
	}

	dev->physical_location->panel = pld->panel;
	dev->physical_location->vertical_position = pld->vertical_position;
	dev->physical_location->horizontal_position = pld->horizontal_position;
	dev->physical_location->dock = pld->dock;
	dev->physical_location->lid = pld->lid;

	ACPI_FREE(pld);
	return true;
}

static ssize_t panel_show(struct device *dev, struct device_attribute *attr,
	char *buf)
{
	const char *panel;

	switch (dev->physical_location->panel) {
	case DEVICE_PANEL_TOP:
		panel = "top";
		break;
	case DEVICE_PANEL_BOTTOM:
		panel = "bottom";
		break;
	case DEVICE_PANEL_LEFT:
		panel = "left";
		break;
	case DEVICE_PANEL_RIGHT:
		panel = "right";
		break;
	case DEVICE_PANEL_FRONT:
		panel = "front";
		break;
	case DEVICE_PANEL_BACK:
		panel = "back";
		break;
	default:
		panel = "unknown";
	}
	return sysfs_emit(buf, "%s\n", panel);
}
static DEVICE_ATTR_RO(panel);

static ssize_t vertical_position_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	const char *vertical_position;

	switch (dev->physical_location->vertical_position) {
	case DEVICE_VERT_POS_UPPER:
		vertical_position = "upper";
		break;
	case DEVICE_VERT_POS_CENTER:
		vertical_position = "center";
		break;
	case DEVICE_VERT_POS_LOWER:
		vertical_position = "lower";
		break;
	default:
		vertical_position = "unknown";
	}
	return sysfs_emit(buf, "%s\n", vertical_position);
}
static DEVICE_ATTR_RO(vertical_position);

static ssize_t horizontal_position_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	const char *horizontal_position;

	switch (dev->physical_location->horizontal_position) {
	case DEVICE_HORI_POS_LEFT:
		horizontal_position = "left";
		break;
	case DEVICE_HORI_POS_CENTER:
		horizontal_position = "center";
		break;
	case DEVICE_HORI_POS_RIGHT:
		horizontal_position = "right";
		break;
	default:
		horizontal_position = "unknown";
	}
	return sysfs_emit(buf, "%s\n", horizontal_position);
}
static DEVICE_ATTR_RO(horizontal_position);

static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
	char *buf)
{
	return sysfs_emit(buf, "%s\n",
		dev->physical_location->dock ? "yes" : "no");
}
static DEVICE_ATTR_RO(dock);

static ssize_t lid_show(struct device *dev, struct device_attribute *attr,
	char *buf)
{
	return sysfs_emit(buf, "%s\n",
		dev->physical_location->lid ? "yes" : "no");
}
static DEVICE_ATTR_RO(lid);

static struct attribute *dev_attr_physical_location[] = {
	&dev_attr_panel.attr,
	&dev_attr_vertical_position.attr,
	&dev_attr_horizontal_position.attr,
	&dev_attr_dock.attr,
	&dev_attr_lid.attr,
	NULL,
};

const struct attribute_group dev_attr_physical_location_group = {
	.name = "physical_location",
	.attrs = dev_attr_physical_location,
};

