blob: 0978042fb12913552be3696cddfb798e065a2ae8 [file] [log] [blame]
Felix Held3f3eca92020-01-23 17:12:32 +01001/* SPDX-License-Identifier: GPL-2.0-only */
Nico Huber1c811282013-06-15 20:33:44 +02002
3#include <arch/io.h>
4#include <device/device.h>
5#include <superio/conf_mode.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07006#include <acpi/acpigen.h>
Nico Huber1c811282013-06-15 20:33:44 +02007
8/* Common enter/exit implementations */
9
Edward O'Callaghan377fd752014-10-21 07:51:24 +110010void pnp_enter_conf_mode_55(struct device *dev)
Nico Huber1c811282013-06-15 20:33:44 +020011{
12 outb(0x55, dev->path.pnp.port);
13}
14
Edward O'Callaghanb14bf882014-11-01 09:14:58 +110015void pnp_enter_conf_mode_6767(struct device *dev)
16{
17 outb(0x67, dev->path.pnp.port);
18 outb(0x67, dev->path.pnp.port);
19}
20
21void pnp_enter_conf_mode_7777(struct device *dev)
22{
23 outb(0x77, dev->path.pnp.port);
24 outb(0x77, dev->path.pnp.port);
25}
26
Edward O'Callaghan377fd752014-10-21 07:51:24 +110027void pnp_enter_conf_mode_8787(struct device *dev)
Nico Huber1c811282013-06-15 20:33:44 +020028{
29 outb(0x87, dev->path.pnp.port);
30 outb(0x87, dev->path.pnp.port);
31}
32
Edward O'Callaghanb14bf882014-11-01 09:14:58 +110033void pnp_enter_conf_mode_a0a0(struct device *dev)
34{
35 outb(0xa0, dev->path.pnp.port);
36 outb(0xa0, dev->path.pnp.port);
37}
38
Frans Hendriks2e1fea42018-11-26 10:33:00 +010039void pnp_enter_conf_mode_a5a5(struct device *dev)
40{
41 outb(0xa5, dev->path.pnp.port);
42 outb(0xa5, dev->path.pnp.port);
43}
44
Edward O'Callaghan377fd752014-10-21 07:51:24 +110045void pnp_exit_conf_mode_aa(struct device *dev)
Nico Huber1c811282013-06-15 20:33:44 +020046{
47 outb(0xaa, dev->path.pnp.port);
48}
49
Edward O'Callaghan377fd752014-10-21 07:51:24 +110050void pnp_enter_conf_mode_870155aa(struct device *dev)
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +100051{
52 outb(0x87, dev->path.pnp.port);
53 outb(0x01, dev->path.pnp.port);
54 outb(0x55, dev->path.pnp.port);
55
56 if (dev->path.pnp.port == 0x4e)
57 outb(0xaa, dev->path.pnp.port);
58 else
59 outb(0x55, dev->path.pnp.port);
60}
61
Edward O'Callaghan377fd752014-10-21 07:51:24 +110062void pnp_exit_conf_mode_0202(struct device *dev)
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +100063{
Felix Helddacf0832019-01-21 14:50:28 +010064 pnp_write_config(dev, 0x02, (1 << 1));
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +100065}
66
Patrick Rudolph7db16dd2019-12-10 13:15:42 +010067/* Functions for ACPI */
68#if CONFIG(HAVE_ACPI_TABLES)
69static void pnp_ssdt_enter_conf_mode_55(struct device *dev, const char *idx, const char *data)
70{
71 acpigen_write_store();
72 acpigen_write_byte(0x55);
73 acpigen_emit_namestring(idx);
74}
75
76static void pnp_ssdt_enter_conf_mode_6767(struct device *dev, const char *idx, const char *data)
77{
78 acpigen_write_store();
79 acpigen_write_byte(0x67);
80 acpigen_emit_namestring(idx);
81
82 acpigen_write_store();
83 acpigen_write_byte(0x67);
84 acpigen_emit_namestring(idx);
85}
86
87static void pnp_ssdt_enter_conf_mode_7777(struct device *dev, const char *idx, const char *data)
88{
89 acpigen_write_store();
90 acpigen_write_byte(0x77);
91 acpigen_emit_namestring(idx);
92
93 acpigen_write_store();
94 acpigen_write_byte(0x77);
95 acpigen_emit_namestring(idx);
96}
97
98static void pnp_ssdt_enter_conf_mode_8787(struct device *dev, const char *idx, const char *data)
99{
100 acpigen_write_store();
101 acpigen_write_byte(0x87);
102 acpigen_emit_namestring(idx);
103
104 acpigen_write_store();
105 acpigen_write_byte(0x87);
106 acpigen_emit_namestring(idx);
107}
108
109static void pnp_ssdt_enter_conf_mode_a0a0(struct device *dev, const char *idx, const char *data)
110{
111 acpigen_write_store();
112 acpigen_write_byte(0xa0);
113 acpigen_emit_namestring(idx);
114
115 acpigen_write_store();
116 acpigen_write_byte(0xa0);
117 acpigen_emit_namestring(idx);
118
119}
120
121static void pnp_ssdt_enter_conf_mode_a5a5(struct device *dev, const char *idx, const char *data)
122{
123 acpigen_write_store();
124 acpigen_write_byte(0xa5);
125 acpigen_emit_namestring(idx);
126
127 acpigen_write_store();
128 acpigen_write_byte(0xa5);
129 acpigen_emit_namestring(idx);
130}
131
132static void pnp_ssdt_enter_conf_mode_870155aa(struct device *dev,
133 const char *idx, const char *data)
134{
135 acpigen_write_store();
136 acpigen_write_byte(0x87);
137 acpigen_emit_namestring(idx);
138
139 acpigen_write_store();
140 acpigen_write_byte(0x01);
141 acpigen_emit_namestring(idx);
142
143 acpigen_write_store();
144 acpigen_write_byte(0x55);
145 acpigen_emit_namestring(idx);
146
147 acpigen_write_store();
148 if (dev->path.pnp.port == 0x4e)
149 acpigen_write_byte(0xaa);
150 else
151 acpigen_write_byte(0x55);
152 acpigen_emit_namestring(idx);
153}
154
155static void pnp_ssdt_exit_conf_mode_aa(struct device *dev, const char *idx, const char *data)
156{
157 acpigen_write_store();
158 acpigen_write_byte(0xaa);
159 acpigen_emit_namestring(idx);
160}
161
162static void pnp_ssdt_exit_conf_mode_0202(struct device *dev, const char *idx, const char *data)
163{
164
165 acpigen_write_store();
166 acpigen_write_byte(0x02);
167 acpigen_emit_namestring(idx);
168
169 acpigen_write_store();
170 acpigen_write_byte(0x02);
171 acpigen_emit_namestring(data);
172}
173#endif
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +1000174
Nico Huber1c811282013-06-15 20:33:44 +0200175const struct pnp_mode_ops pnp_conf_mode_55_aa = {
176 .enter_conf_mode = pnp_enter_conf_mode_55,
177 .exit_conf_mode = pnp_exit_conf_mode_aa,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100178#if CONFIG(HAVE_ACPI_TABLES)
179 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_55,
180 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
181#endif
Nico Huber1c811282013-06-15 20:33:44 +0200182};
183
Edward O'Callaghanb14bf882014-11-01 09:14:58 +1100184const struct pnp_mode_ops pnp_conf_mode_6767_aa = {
185 .enter_conf_mode = pnp_enter_conf_mode_6767,
186 .exit_conf_mode = pnp_exit_conf_mode_aa,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100187#if CONFIG(HAVE_ACPI_TABLES)
188 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_6767,
189 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
190#endif
Edward O'Callaghanb14bf882014-11-01 09:14:58 +1100191};
192
193const struct pnp_mode_ops pnp_conf_mode_7777_aa = {
194 .enter_conf_mode = pnp_enter_conf_mode_7777,
195 .exit_conf_mode = pnp_exit_conf_mode_aa,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100196#if CONFIG(HAVE_ACPI_TABLES)
197 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_7777,
198 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
199#endif
Edward O'Callaghanb14bf882014-11-01 09:14:58 +1100200};
201
Nico Huber1c811282013-06-15 20:33:44 +0200202const struct pnp_mode_ops pnp_conf_mode_8787_aa = {
203 .enter_conf_mode = pnp_enter_conf_mode_8787,
204 .exit_conf_mode = pnp_exit_conf_mode_aa,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100205#if CONFIG(HAVE_ACPI_TABLES)
206 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_8787,
207 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
208#endif
Nico Huber1c811282013-06-15 20:33:44 +0200209};
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +1000210
Edward O'Callaghanb14bf882014-11-01 09:14:58 +1100211const struct pnp_mode_ops pnp_conf_mode_a0a0_aa = {
212 .enter_conf_mode = pnp_enter_conf_mode_a0a0,
213 .exit_conf_mode = pnp_exit_conf_mode_aa,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100214#if CONFIG(HAVE_ACPI_TABLES)
215 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_a0a0,
216 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
217#endif
Edward O'Callaghanb14bf882014-11-01 09:14:58 +1100218};
219
Frans Hendriks2e1fea42018-11-26 10:33:00 +0100220const struct pnp_mode_ops pnp_conf_mode_a5a5_aa = {
221 .enter_conf_mode = pnp_enter_conf_mode_a5a5,
222 .exit_conf_mode = pnp_exit_conf_mode_aa,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100223#if CONFIG(HAVE_ACPI_TABLES)
224 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_a5a5,
225 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
226#endif
Frans Hendriks2e1fea42018-11-26 10:33:00 +0100227};
228
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +1000229const struct pnp_mode_ops pnp_conf_mode_870155_aa = {
230 .enter_conf_mode = pnp_enter_conf_mode_870155aa,
231 .exit_conf_mode = pnp_exit_conf_mode_0202,
Patrick Rudolph7db16dd2019-12-10 13:15:42 +0100232#if CONFIG(HAVE_ACPI_TABLES)
233 .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_870155aa,
234 .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_0202,
235#endif
Edward O'Callaghanbf9f2432014-05-06 17:24:59 +1000236};