1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/device.h>
5 #include <superio/conf_mode.h>
6 #include <acpi/acpigen.h>
8 /* Common enter/exit implementations */
10 void pnp_enter_conf_mode_55(struct device
*dev
)
12 outb(0x55, dev
->path
.pnp
.port
);
15 void pnp_enter_conf_mode_6767(struct device
*dev
)
17 outb(0x67, dev
->path
.pnp
.port
);
18 outb(0x67, dev
->path
.pnp
.port
);
21 void pnp_enter_conf_mode_7777(struct device
*dev
)
23 outb(0x77, dev
->path
.pnp
.port
);
24 outb(0x77, dev
->path
.pnp
.port
);
27 void pnp_enter_conf_mode_8787(struct device
*dev
)
29 outb(0x87, dev
->path
.pnp
.port
);
30 outb(0x87, dev
->path
.pnp
.port
);
33 void pnp_enter_conf_mode_a0a0(struct device
*dev
)
35 outb(0xa0, dev
->path
.pnp
.port
);
36 outb(0xa0, dev
->path
.pnp
.port
);
39 void pnp_enter_conf_mode_a5a5(struct device
*dev
)
41 outb(0xa5, dev
->path
.pnp
.port
);
42 outb(0xa5, dev
->path
.pnp
.port
);
45 void pnp_exit_conf_mode_aa(struct device
*dev
)
47 outb(0xaa, dev
->path
.pnp
.port
);
50 void pnp_enter_conf_mode_870155aa(struct device
*dev
)
52 outb(0x87, dev
->path
.pnp
.port
);
53 outb(0x01, dev
->path
.pnp
.port
);
54 outb(0x55, dev
->path
.pnp
.port
);
56 if (dev
->path
.pnp
.port
== 0x4e)
57 outb(0xaa, dev
->path
.pnp
.port
);
59 outb(0x55, dev
->path
.pnp
.port
);
62 void pnp_exit_conf_mode_0202(struct device
*dev
)
64 pnp_write_config(dev
, 0x02, (1 << 1));
67 /* Functions for ACPI */
68 #if CONFIG(HAVE_ACPI_TABLES)
69 static void pnp_ssdt_enter_conf_mode_55(struct device
*dev
, const char *idx
, const char *data
)
71 acpigen_write_store();
72 acpigen_write_byte(0x55);
73 acpigen_emit_namestring(idx
);
76 static void pnp_ssdt_enter_conf_mode_6767(struct device
*dev
, const char *idx
, const char *data
)
78 acpigen_write_store();
79 acpigen_write_byte(0x67);
80 acpigen_emit_namestring(idx
);
82 acpigen_write_store();
83 acpigen_write_byte(0x67);
84 acpigen_emit_namestring(idx
);
87 static void pnp_ssdt_enter_conf_mode_7777(struct device
*dev
, const char *idx
, const char *data
)
89 acpigen_write_store();
90 acpigen_write_byte(0x77);
91 acpigen_emit_namestring(idx
);
93 acpigen_write_store();
94 acpigen_write_byte(0x77);
95 acpigen_emit_namestring(idx
);
98 static void pnp_ssdt_enter_conf_mode_8787(struct device
*dev
, const char *idx
, const char *data
)
100 acpigen_write_store();
101 acpigen_write_byte(0x87);
102 acpigen_emit_namestring(idx
);
104 acpigen_write_store();
105 acpigen_write_byte(0x87);
106 acpigen_emit_namestring(idx
);
109 static void pnp_ssdt_enter_conf_mode_a0a0(struct device
*dev
, const char *idx
, const char *data
)
111 acpigen_write_store();
112 acpigen_write_byte(0xa0);
113 acpigen_emit_namestring(idx
);
115 acpigen_write_store();
116 acpigen_write_byte(0xa0);
117 acpigen_emit_namestring(idx
);
120 static void pnp_ssdt_enter_conf_mode_a5a5(struct device
*dev
, const char *idx
, const char *data
)
122 acpigen_write_store();
123 acpigen_write_byte(0xa5);
124 acpigen_emit_namestring(idx
);
126 acpigen_write_store();
127 acpigen_write_byte(0xa5);
128 acpigen_emit_namestring(idx
);
131 static void pnp_ssdt_enter_conf_mode_870155aa(struct device
*dev
,
132 const char *idx
, const char *data
)
134 acpigen_write_store();
135 acpigen_write_byte(0x87);
136 acpigen_emit_namestring(idx
);
138 acpigen_write_store();
139 acpigen_write_byte(0x01);
140 acpigen_emit_namestring(idx
);
142 acpigen_write_store();
143 acpigen_write_byte(0x55);
144 acpigen_emit_namestring(idx
);
146 acpigen_write_store();
147 if (dev
->path
.pnp
.port
== 0x4e)
148 acpigen_write_byte(0xaa);
150 acpigen_write_byte(0x55);
151 acpigen_emit_namestring(idx
);
154 static void pnp_ssdt_exit_conf_mode_aa(struct device
*dev
, const char *idx
, const char *data
)
156 acpigen_write_store();
157 acpigen_write_byte(0xaa);
158 acpigen_emit_namestring(idx
);
161 static void pnp_ssdt_exit_conf_mode_0202(struct device
*dev
, const char *idx
, const char *data
)
163 acpigen_write_store();
164 acpigen_write_byte(0x02);
165 acpigen_emit_namestring(idx
);
167 acpigen_write_store();
168 acpigen_write_byte(0x02);
169 acpigen_emit_namestring(data
);
173 const struct pnp_mode_ops pnp_conf_mode_55_aa
= {
174 .enter_conf_mode
= pnp_enter_conf_mode_55
,
175 .exit_conf_mode
= pnp_exit_conf_mode_aa
,
176 #if CONFIG(HAVE_ACPI_TABLES)
177 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_55
,
178 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_aa
,
182 const struct pnp_mode_ops pnp_conf_mode_6767_aa
= {
183 .enter_conf_mode
= pnp_enter_conf_mode_6767
,
184 .exit_conf_mode
= pnp_exit_conf_mode_aa
,
185 #if CONFIG(HAVE_ACPI_TABLES)
186 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_6767
,
187 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_aa
,
191 const struct pnp_mode_ops pnp_conf_mode_7777_aa
= {
192 .enter_conf_mode
= pnp_enter_conf_mode_7777
,
193 .exit_conf_mode
= pnp_exit_conf_mode_aa
,
194 #if CONFIG(HAVE_ACPI_TABLES)
195 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_7777
,
196 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_aa
,
200 const struct pnp_mode_ops pnp_conf_mode_8787_aa
= {
201 .enter_conf_mode
= pnp_enter_conf_mode_8787
,
202 .exit_conf_mode
= pnp_exit_conf_mode_aa
,
203 #if CONFIG(HAVE_ACPI_TABLES)
204 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_8787
,
205 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_aa
,
209 const struct pnp_mode_ops pnp_conf_mode_a0a0_aa
= {
210 .enter_conf_mode
= pnp_enter_conf_mode_a0a0
,
211 .exit_conf_mode
= pnp_exit_conf_mode_aa
,
212 #if CONFIG(HAVE_ACPI_TABLES)
213 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_a0a0
,
214 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_aa
,
218 const struct pnp_mode_ops pnp_conf_mode_a5a5_aa
= {
219 .enter_conf_mode
= pnp_enter_conf_mode_a5a5
,
220 .exit_conf_mode
= pnp_exit_conf_mode_aa
,
221 #if CONFIG(HAVE_ACPI_TABLES)
222 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_a5a5
,
223 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_aa
,
227 const struct pnp_mode_ops pnp_conf_mode_870155_aa
= {
228 .enter_conf_mode
= pnp_enter_conf_mode_870155aa
,
229 .exit_conf_mode
= pnp_exit_conf_mode_0202
,
230 #if CONFIG(HAVE_ACPI_TABLES)
231 .ssdt_enter_conf_mode
= pnp_ssdt_enter_conf_mode_870155aa
,
232 .ssdt_exit_conf_mode
= pnp_ssdt_exit_conf_mode_0202
,