/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef __ACPI_ACPI_PLD_H__ #define __ACPI_ACPI_PLD_H__ #include <acpi/acpi.h> #include <stdint.h> enum acpi_pld_panel { PLD_PANEL_TOP, PLD_PANEL_BOTTOM, PLD_PANEL_LEFT, PLD_PANEL_RIGHT, PLD_PANEL_FRONT, PLD_PANEL_BACK, PLD_PANEL_UNKNOWN }; enum acpi_pld_vertical_position { PLD_VERTICAL_POSITION_UPPER, PLD_VERTICAL_POSITION_CENTER, PLD_VERTICAL_POSITION_LOWER }; /* * The ACPI spec 6.2A does not define the horizontal position field. * These values are taken from the IASL compiler: * https://github.com/acpica/acpica/blob/master/source/components/utilities/utglobal.c#L321 */ enum acpi_pld_horizontal_position { PLD_HORIZONTAL_POSITION_LEFT, PLD_HORIZONTAL_POSITION_CENTER, PLD_HORIZONTAL_POSITION_RIGHT }; enum acpi_pld_shape { PLD_SHAPE_ROUND, PLD_SHAPE_OVAL, PLD_SHAPE_SQUARE, PLD_SHAPE_VERTICAL_RECTANGLE, PLD_SHAPE_HORIZONTAL_RECTANGLE, PLD_SHAPE_VERTICAL_TRAPEZOID, PLD_SHAPE_HORIZONTAL_TRAPEZOID, PLD_SHAPE_UNKNOWN, PLD_SHAPE_CHAMFERED }; enum acpi_pld_orientation { PLD_ORIENTATION_HORIZONTAL, PLD_ORIENTATION_VERTICAL, }; enum acpi_pld_rotate { PLD_ROTATE_0, PLD_ROTATE_45, PLD_ROTATE_90, PLD_ROTATE_135, PLD_ROTATE_180, PLD_ROTATE_225, PLD_ROTATE_270, PLD_ROTATE_315 }; #define ACPI_PLD_GROUP(__token, __position) \ { \ .token = __token, \ .position = __position, \ } /* * ACPI specification 6.3 third paragraph of section 6.1.8: * All Panel references (Top, Bottom, Right, Left, etc.) are interpreted * as though the user is facing the front of the system. * * A `_PLD` describes the offset and rotation of a single device connection point * from an `origin` that resides in the lower left hand corner of its Panel. */ #define ACPI_PLD_TYPE_A(__panel, __horiz, __grp) \ { \ .visible = true, \ .panel = PLD_PANEL_##__panel, \ .shape = PLD_SHAPE_HORIZONTAL_RECTANGLE, \ .horizontal_position = PLD_HORIZONTAL_POSITION_##__horiz, \ .group = __grp, \ } #define ACPI_PLD_TYPE_C(__panel, __horiz, __grp) \ { \ .visible = true, \ .panel = PLD_PANEL_##__panel, \ .shape = PLD_SHAPE_OVAL, \ .horizontal_position = PLD_HORIZONTAL_POSITION_##__horiz, \ .group = __grp, \ } struct acpi_pld_group { uint8_t token; uint8_t position; }; struct acpi_pld { /* Color field can be explicitly ignored */ bool ignore_color; uint8_t color_red; uint8_t color_blue; uint8_t color_green; /* Port characteristics */ bool visible; /* Can be seen by the user */ bool lid; /* Port is on lid of device */ bool dock; /* Port is in a docking station */ bool bay; /* Port is in a bay */ bool ejectable; /* Device is ejectable, has _EJx objects */ bool ejectable_ospm; /* Device needs OSPM to eject */ uint16_t width; /* Width in mm */ uint16_t height; /* Height in mm */ uint16_t vertical_offset; uint16_t horizontal_offset; enum acpi_pld_panel panel; enum acpi_pld_horizontal_position horizontal_position; enum acpi_pld_vertical_position vertical_position; enum acpi_pld_shape shape; enum acpi_pld_rotate rotation; /* Port grouping */ enum acpi_pld_orientation orientation; struct acpi_pld_group group; uint8_t draw_order; uint8_t cabinet_number; uint8_t card_cage_number; /* Set if this PLD defines a reference shape */ bool reference_shape; }; /* Fill out PLD structure with defaults based on USB port type */ int acpi_pld_fill_usb(struct acpi_pld *pld, enum acpi_upc_type type, struct acpi_pld_group *group); /* Turn PLD structure into a 20 byte ACPI buffer */ int acpi_pld_to_buffer(const struct acpi_pld *pld, uint8_t *buf, int buf_len); #endif /* __ACPI_ACPI_PLD_H__ */