summaryrefslogtreecommitdiffstats
path: root/src/include/acpi/acpi_pld.h
blob: f89a68054e0de462ab3c5d88aeeffd8dacf213ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* 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__ */