conf_mode.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <arch/io.h> 4 #include <device/device.h> 5 #include <superio/conf_mode.h> 6 #include <acpi/acpigen.h> 7 8 /* Common enter/exit implementations */ 9 10 void pnp_enter_conf_mode_55(struct device *dev) 11 { 12 outb(0x55, dev->path.pnp.port); 13 } 14 15 void 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 21 void 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 27 void pnp_enter_conf_mode_8787(struct device *dev) 28 { 29 outb(0x87, dev->path.pnp.port); 30 outb(0x87, dev->path.pnp.port); 31 } 32 33 void 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 39 void 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 45 void pnp_exit_conf_mode_aa(struct device *dev) 46 { 47 outb(0xaa, dev->path.pnp.port); 48 } 49 50 void pnp_enter_conf_mode_870155aa(struct device *dev) 51 { 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 62 void pnp_exit_conf_mode_0202(struct device *dev) 63 { 64 pnp_write_config(dev, 0x02, (1 << 1)); 65 } 66 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) 70 { 71 acpigen_write_store(); 72 acpigen_write_byte(0x55); 73 acpigen_emit_namestring(idx); 74 } 75 76 static 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 87 static 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 98 static 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 109 static 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 static void pnp_ssdt_enter_conf_mode_a5a5(struct device *dev, const char *idx, const char *data) 121 { 122 acpigen_write_store(); 123 acpigen_write_byte(0xa5); 124 acpigen_emit_namestring(idx); 125 126 acpigen_write_store(); 127 acpigen_write_byte(0xa5); 128 acpigen_emit_namestring(idx); 129 } 130 131 static void pnp_ssdt_enter_conf_mode_870155aa(struct device *dev, 132 const char *idx, const char *data) 133 { 134 acpigen_write_store(); 135 acpigen_write_byte(0x87); 136 acpigen_emit_namestring(idx); 137 138 acpigen_write_store(); 139 acpigen_write_byte(0x01); 140 acpigen_emit_namestring(idx); 141 142 acpigen_write_store(); 143 acpigen_write_byte(0x55); 144 acpigen_emit_namestring(idx); 145 146 acpigen_write_store(); 147 if (dev->path.pnp.port == 0x4e) 148 acpigen_write_byte(0xaa); 149 else 150 acpigen_write_byte(0x55); 151 acpigen_emit_namestring(idx); 152 } 153 154 static void pnp_ssdt_exit_conf_mode_aa(struct device *dev, const char *idx, const char *data) 155 { 156 acpigen_write_store(); 157 acpigen_write_byte(0xaa); 158 acpigen_emit_namestring(idx); 159 } 160 161 static void pnp_ssdt_exit_conf_mode_0202(struct device *dev, const char *idx, const char *data) 162 { 163 acpigen_write_store(); 164 acpigen_write_byte(0x02); 165 acpigen_emit_namestring(idx); 166 167 acpigen_write_store(); 168 acpigen_write_byte(0x02); 169 acpigen_emit_namestring(data); 170 } 171 #endif 172 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, 179 #endif 180 }; 181 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, 188 #endif 189 }; 190 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, 197 #endif 198 }; 199 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, 206 #endif 207 }; 208 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, 215 #endif 216 }; 217 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, 224 #endif 225 }; 226 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, 233 #endif 234 };