superio/nuvoton/npcd378: Switch to superio/common
Replace DSDT ACPI code and DSDT injection with a SSDT only solution. The current implementation shows some issues on current Linux, which might be due to external ACPI objects, which are then injected into DSDT or the fact that those objects only use 3 characters. Replace all the DSDT code with an SSDT generator. Tested on HP Z220: Boots into Linux with no ACPI errors. The SSDT can be disassembled. Change-Id: I41616d9bf320fd2b4d8495892b8190cd2a2d057f Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/38862 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
parent
56626cf5d8
commit
e1498ce6da
|
@ -15,6 +15,7 @@
|
|||
|
||||
Method(_WAK, 1, NotSerialized)
|
||||
{
|
||||
// Generated by SSDT
|
||||
\_SB.PCI0.LPCB.SIO0.SIOW (Arg0)
|
||||
|
||||
Return(Package(){0,0})
|
||||
|
@ -22,5 +23,6 @@ Method(_WAK, 1, NotSerialized)
|
|||
|
||||
Method(_PTS, 1, NotSerialized)
|
||||
{
|
||||
// Generated by SSDT
|
||||
\_SB.PCI0.LPCB.SIO0.SIOS (Arg0)
|
||||
}
|
||||
|
|
|
@ -13,24 +13,10 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#undef SUPERIO_DEV
|
||||
#undef SUPERIO_PNP_BASE
|
||||
#define SUPERIO_DEV SIO0
|
||||
#define SUPERIO_PNP_BASE 0x2e
|
||||
|
||||
#define SUPERIO_SHOW_SP2
|
||||
#define SUPERIO_SHOW_KBC
|
||||
|
||||
#include <superio/nuvoton/npcd378/acpi/superio.asl>
|
||||
|
||||
Scope (\_GPE)
|
||||
{
|
||||
Method (_L08, 0, NotSerialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.SIO0.SIOH ()
|
||||
}
|
||||
|
||||
Method (_L0D, 0, NotSerialized)
|
||||
{
|
||||
Notify (\_SB.PCI0.EHC1, 0x02)
|
||||
|
|
|
@ -75,6 +75,8 @@ chip northbridge/intel/sandybridge
|
|||
device pci 1d.0 on end # USB2 EHCI #1
|
||||
device pci 1e.0 on end # PCI bridge
|
||||
device pci 1f.0 on # LPC bridge PCI-LPC bridge
|
||||
chip superio/common
|
||||
device pnp 2e.ff on # passes SIO base addr to SSDT gen
|
||||
chip superio/nuvoton/npcd378
|
||||
device pnp 2e.0 off end # Floppy
|
||||
device pnp 2e.1 on # Parallel port
|
||||
|
@ -88,8 +90,8 @@ chip northbridge/intel/sandybridge
|
|||
irq 0x1a = 0xb0
|
||||
# dumped from superiotool:
|
||||
irq 0x1b = 0x1e
|
||||
irq 0x27 = 0x04
|
||||
irq 0x2a = 0x00
|
||||
irq 0x27 = 0x08
|
||||
irq 0x2a = 0x20
|
||||
irq 0x2d = 0x01
|
||||
# parallel port
|
||||
io 0x60 = 0x378
|
||||
|
@ -171,6 +173,8 @@ chip northbridge/intel/sandybridge
|
|||
#drq 0xfe = 0x03
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
chip drivers/pc80/tpm
|
||||
device pnp 4e.0 on end # TPM module
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
Method(_WAK, 1, NotSerialized)
|
||||
{
|
||||
// Generated by SSDT
|
||||
\_SB.PCI0.LPCB.SIO0.SIOW (Arg0)
|
||||
|
||||
Return(Package(){0,0})
|
||||
|
@ -22,5 +23,6 @@ Method(_WAK, 1, NotSerialized)
|
|||
|
||||
Method(_PTS, 1, NotSerialized)
|
||||
{
|
||||
// Generated by SSDT
|
||||
\_SB.PCI0.LPCB.SIO0.SIOS (Arg0)
|
||||
}
|
||||
|
|
|
@ -13,24 +13,10 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#undef SUPERIO_DEV
|
||||
#undef SUPERIO_PNP_BASE
|
||||
#define SUPERIO_DEV SIO0
|
||||
#define SUPERIO_PNP_BASE 0x2e
|
||||
|
||||
#define SUPERIO_SHOW_SP2
|
||||
#define SUPERIO_SHOW_KBC
|
||||
|
||||
#include <superio/nuvoton/npcd378/acpi/superio.asl>
|
||||
|
||||
Scope (\_GPE)
|
||||
{
|
||||
Method (_L08, 0, NotSerialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.SIO0.SIOH ()
|
||||
}
|
||||
|
||||
Method (_L0D, 0, NotSerialized)
|
||||
{
|
||||
Notify (\_SB.PCI0.EHC1, 0x02)
|
||||
|
|
|
@ -76,6 +76,8 @@ chip northbridge/intel/sandybridge
|
|||
device pci 1d.0 on end # USB2 EHCI #1
|
||||
device pci 1e.0 on end # PCI bridge
|
||||
device pci 1f.0 on # LPC bridge PCI-LPC bridge
|
||||
chip superio/common
|
||||
device pnp 2e.ff on # passes SIO base addr to SSDT gen
|
||||
chip superio/nuvoton/npcd378
|
||||
device pnp 2e.0 off end # Floppy
|
||||
device pnp 2e.1 on # Parallel port
|
||||
|
@ -172,6 +174,8 @@ chip northbridge/intel/sandybridge
|
|||
#drq 0xfe = 0x03
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
chip drivers/pc80/tpm
|
||||
device pnp 4e.0 on end # TPM module
|
||||
end
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
# This file is part of the coreboot project.
|
||||
|
||||
ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += superio.c
|
||||
ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += ../../common/ssdt.c
|
||||
ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += ../../common/generic.c
|
||||
|
|
|
@ -1,321 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* This file is part of the coreboot project. */
|
||||
|
||||
/*
|
||||
* Include this file into a mainboard's DSDT _SB device tree and it will
|
||||
* expose the NPCD378 SuperIO and some of its functionality.
|
||||
*
|
||||
* It allows the change of IO ports, IRQs and DMA settings on logical
|
||||
* devices, disabling and reenabling logical devices.
|
||||
*
|
||||
* LDN State
|
||||
* 0x2 SP1 Implemented, untested
|
||||
* 0x5 KBCK Implemented, untested
|
||||
*/
|
||||
|
||||
#undef SUPERIO_CHIP_NAME
|
||||
#define SUPERIO_CHIP_NAME NPCD378
|
||||
#include <superio/acpi/pnp.asl>
|
||||
|
||||
#undef PNP_DEFAULT_PSC
|
||||
#define PNP_DEFAULT_PSC Return (0) /* no power management */
|
||||
|
||||
Device(SUPERIO_DEV) {
|
||||
Name (_HID, EisaId("PNP0A05"))
|
||||
Name (_STR, Unicode("Nuvoton NPCD378 Super I/O"))
|
||||
Name (_UID, SUPERIO_UID(SUPERIO_DEV,))
|
||||
|
||||
/* SuperIO configuration ports */
|
||||
OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02)
|
||||
Field (CREG, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
PNP_ADDR_REG, 8,
|
||||
PNP_DATA_REG, 8,
|
||||
}
|
||||
IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
Offset (0x07),
|
||||
PNP_LOGICAL_DEVICE, 8, /* Logical device selector */
|
||||
|
||||
Offset (0x30),
|
||||
PNP_DEVICE_ACTIVE, 1, /* Logical device activation */
|
||||
ACT1, 1, /* Logical device activation */
|
||||
ACT2, 1, /* Logical device activation */
|
||||
ACT3, 1, /* Logical device activation */
|
||||
ACT4, 1, /* Logical device activation */
|
||||
ACT5, 1, /* Logical device activation */
|
||||
ACT6, 1, /* Logical device activation */
|
||||
ACT7, 1, /* Logical device activation */
|
||||
|
||||
Offset (0x60),
|
||||
PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */
|
||||
PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */
|
||||
Offset (0x62),
|
||||
PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */
|
||||
PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */
|
||||
Offset (0x64),
|
||||
PNP_IO2_HIGH_BYTE, 8, /* Third I/O port base - high byte */
|
||||
PNP_IO2_LOW_BYTE, 8, /* Third I/O port base - low byte */
|
||||
|
||||
Offset (0x70),
|
||||
PNP_IRQ0, 8, /* First IRQ */
|
||||
Offset (0x72),
|
||||
PNP_IRQ1, 8, /* Second IRQ */
|
||||
}
|
||||
|
||||
#undef PNP_ENTER_MAGIC_1ST
|
||||
#undef PNP_ENTER_MAGIC_2ND
|
||||
#undef PNP_ENTER_MAGIC_3RD
|
||||
#undef PNP_ENTER_MAGIC_4TH
|
||||
#undef PNP_EXIT_MAGIC_1ST
|
||||
#undef PNP_EXIT_SPECIAL_REG
|
||||
#undef PNP_EXIT_SPECIAL_VAL
|
||||
#define PNP_ENTER_MAGIC_1ST 0x87
|
||||
#define PNP_ENTER_MAGIC_2ND 0x87
|
||||
#define PNP_EXIT_MAGIC_1ST 0xaa
|
||||
#include <superio/acpi/pnp_config.asl>
|
||||
|
||||
#ifdef SUPERIO_SHOW_LPT
|
||||
#undef SUPERIO_PNP_HID
|
||||
#undef SUPERIO_PNP_LDN
|
||||
#undef SUPERIO_PNP_DDN
|
||||
#undef SUPERIO_PNP_PM_REG
|
||||
#undef SUPERIO_PNP_PM_VAL
|
||||
#undef SUPERIO_PNP_PM_LDN
|
||||
#undef SUPERIO_PNP_IO0
|
||||
#undef SUPERIO_PNP_IO1
|
||||
#undef SUPERIO_PNP_IRQ0
|
||||
#undef SUPERIO_PNP_IRQ1
|
||||
#undef SUPERIO_PNP_DMA
|
||||
#undef PNP_DEVICE_ACTIVE
|
||||
#define PNP_DEVICE_ACTIVE ACT3
|
||||
#define SUPERIO_PNP_LDN 1
|
||||
#define SUPERIO_PNP_IO0 0x08, 0x08
|
||||
#include <superio/acpi/pnp_generic.asl>
|
||||
#endif
|
||||
|
||||
#ifdef SUPERIO_SHOW_SP1
|
||||
#undef SUPERIO_UART_LDN
|
||||
#undef SUPERIO_UART_DDN
|
||||
#undef SUPERIO_UART_PM_REG
|
||||
#undef SUPERIO_UART_PM_VAL
|
||||
#undef SUPERIO_UART_PM_LDN
|
||||
#define SUPERIO_UART_LDN 2
|
||||
#include <superio/acpi/pnp_uart.asl>
|
||||
#endif
|
||||
|
||||
#ifdef SUPERIO_SHOW_SP2
|
||||
#undef SUPERIO_UART_LDN
|
||||
#undef SUPERIO_UART_DDN
|
||||
#undef SUPERIO_UART_PM_REG
|
||||
#undef SUPERIO_UART_PM_VAL
|
||||
#undef SUPERIO_UART_PM_LDN
|
||||
#define SUPERIO_UART_LDN 3
|
||||
#include <superio/acpi/pnp_uart.asl>
|
||||
#endif
|
||||
|
||||
#ifdef SUPERIO_SHOW_KBC
|
||||
#undef SUPERIO_KBC_LDN
|
||||
#undef SUPERIO_KBC_PS2M
|
||||
#undef SUPERIO_KBC_PS2LDN
|
||||
#define SUPERIO_KBC_PS2LDN 5
|
||||
#define SUPERIO_KBC_LDN 6
|
||||
#include <superio/acpi/pnp_kbc.asl>
|
||||
#endif
|
||||
|
||||
#ifdef SUPERIO_SHOW_GPIO
|
||||
#undef SUPERIO_PNP_HID
|
||||
#undef SUPERIO_PNP_LDN
|
||||
#undef SUPERIO_PNP_DDN
|
||||
#undef SUPERIO_PNP_PM_REG
|
||||
#undef SUPERIO_PNP_PM_VAL
|
||||
#undef SUPERIO_PNP_PM_LDN
|
||||
#undef SUPERIO_PNP_IO0
|
||||
#undef SUPERIO_PNP_IO1
|
||||
#undef SUPERIO_PNP_IO2
|
||||
#undef SUPERIO_PNP_IRQ0
|
||||
#undef SUPERIO_PNP_IRQ1
|
||||
#undef SUPERIO_PNP_DMA
|
||||
#undef PNP_DEVICE_ACTIVE
|
||||
#define PNP_DEVICE_ACTIVE ACT3
|
||||
#define SUPERIO_PNP_LDN 8
|
||||
#define SUPERIO_PNP_IO0 0x08, 0x08
|
||||
#include <superio/acpi/pnp_generic.asl>
|
||||
#endif
|
||||
|
||||
// generated by SSDT
|
||||
External(SWB, IntObj)
|
||||
External(SWL, IntObj)
|
||||
OperationRegion (SWCR, SystemIO, SWB, SWL)
|
||||
Field (SWCR, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
LEDC, 8,
|
||||
SWCC, 8
|
||||
}
|
||||
|
||||
// generated by SSDT
|
||||
External(RNB, IntObj)
|
||||
External(RNL, IntObj)
|
||||
OperationRegion (RNTR, SystemIO, RNB, RNL)
|
||||
Field (RNTR, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
GPES, 8,
|
||||
GPEE, 8,
|
||||
Offset (0x08),
|
||||
GPS0, 8,
|
||||
GPS1, 8,
|
||||
GPS2, 8,
|
||||
GPS3, 8,
|
||||
GPE0, 8,
|
||||
GPE1, 8,
|
||||
GPE2, 8,
|
||||
GPE3, 8
|
||||
}
|
||||
|
||||
Name (MSFG, One)
|
||||
Name (KBFG, One)
|
||||
Name (PMFG, Zero) // Wake event backup
|
||||
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (CRS, ResourceTemplate ()
|
||||
{
|
||||
FixedIO (SUPERIO_PNP_BASE, 0x02)
|
||||
// filled below
|
||||
FixedIO (0, 0, CRS1)
|
||||
FixedIO (0, 0, CRS2)
|
||||
})
|
||||
|
||||
CreateWordField (CRS, CRS1._BAS, TMP1)
|
||||
Store(SWB, TMP1)
|
||||
CreateByteField (CRS, CRS1._LEN, TMP2)
|
||||
Store(SWL, TMP2)
|
||||
|
||||
CreateWordField (CRS, CRS2._BAS, TMP3)
|
||||
Store(RNB, TMP3)
|
||||
CreateByteField (CRS, CRS2._LEN, TMP4)
|
||||
Store(RNL, TMP4)
|
||||
|
||||
/* Announce the used I/O ports to the OS */
|
||||
Return (CRS)
|
||||
}
|
||||
|
||||
#ifdef SUPERIO_SHOW_KBC
|
||||
|
||||
#if defined(SUPERIO_KBC_LDN)
|
||||
#define _PS2_KB SUPERIO_ID(KBD, SUPERIO_KBC_LDN)
|
||||
#else
|
||||
#define _PS2_KB PS2K
|
||||
#endif
|
||||
Scope (_PS2_KB)
|
||||
{
|
||||
Method (_PSW, 1, NotSerialized)
|
||||
{
|
||||
KBFG = Arg0
|
||||
}
|
||||
|
||||
Method (_PRW, 0, NotSerialized)
|
||||
{
|
||||
Return (Package (0x02) {0x08, 0x03})
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SUPERIO_KBC_PS2M)
|
||||
#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2M)
|
||||
#elif defined(SUPERIO_KBC_PS2LDN)
|
||||
#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN)
|
||||
#else
|
||||
#define _PS2_M PS2M
|
||||
#endif
|
||||
Scope (_PS2_M)
|
||||
{
|
||||
Method (_PSW, 1, NotSerialized)
|
||||
{
|
||||
MSFG = Arg0
|
||||
}
|
||||
|
||||
Method (_PRW, 0, NotSerialized)
|
||||
{
|
||||
Return (Package (0x02) {0x08, 0x03})
|
||||
}
|
||||
}
|
||||
|
||||
Method (SIOH, 0, NotSerialized)
|
||||
{
|
||||
If ((PMFG & 0xE8))
|
||||
{
|
||||
Notify (_PS2_KB, 0x02)
|
||||
}
|
||||
|
||||
If ((PMFG & 0x10))
|
||||
{
|
||||
Notify (_PS2_M, 0x02)
|
||||
}
|
||||
}
|
||||
#else
|
||||
Method (SIOH, 0, NotSerialized)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SuperIO sleep method */
|
||||
Method (SIOS, 1, NotSerialized)
|
||||
{
|
||||
If ((0x05 != Arg0))
|
||||
{
|
||||
/* Set PS/2 powerstate in S3 */
|
||||
If (KBFG)
|
||||
{
|
||||
GPE2 |= 0xE8
|
||||
}
|
||||
Else
|
||||
{
|
||||
GPE2 &= 0x17
|
||||
}
|
||||
|
||||
If (MSFG)
|
||||
{
|
||||
GPE2 |= 0x10
|
||||
}
|
||||
Else
|
||||
{
|
||||
GPE2 &= 0xEF
|
||||
}
|
||||
|
||||
/* Enable wake on GPE */
|
||||
GPEE = One
|
||||
If ((0x03 == Arg0))
|
||||
{
|
||||
/* green LED fading */
|
||||
Local1 = LEDC
|
||||
Local1 &= 0xE0
|
||||
LEDC = (Local1 | 0x1C)
|
||||
Local1 = SWCC
|
||||
Local1 &= 0xBF
|
||||
SWCC = (Local1 | 0x40)
|
||||
}
|
||||
}
|
||||
|
||||
GPE0 = 0x10
|
||||
GPE1 = 0x20
|
||||
}
|
||||
|
||||
/* SuperIO wake method */
|
||||
Method (SIOW, 1, NotSerialized)
|
||||
{
|
||||
/* Store wake status */
|
||||
PMFG = GPS2
|
||||
|
||||
/* Disable wake on GPE */
|
||||
GPEE = Zero
|
||||
GPE0 = Zero
|
||||
GPE1 = Zero
|
||||
|
||||
/* green LED normal */
|
||||
Local1 = LEDC
|
||||
Local1 &= 0xE0
|
||||
LEDC = (Local1 | 0x1E)
|
||||
Local1 = SWCC
|
||||
SWCC = (Local1 & 0xBF)
|
||||
}
|
||||
}
|
||||
External (\_SB.PCI0.LPCB.SIO0, DeviceObj)
|
||||
External (\_SB.PCI0.LPCB.SIO0.SIOS, MethodObj)
|
||||
External (\_SB.PCI0.LPCB.SIO0.SIOW, MethodObj)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <superio/conf_mode.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <arch/acpigen.h>
|
||||
#include <superio/common/ssdt.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "npcd378.h"
|
||||
|
||||
|
@ -87,49 +89,337 @@ static void npcd378_init(struct device *dev)
|
|||
}
|
||||
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
static void npcd378_ssdt(struct device *dev)
|
||||
/* Provide ACPI HIDs for generic Super I/O SSDT */
|
||||
static const char *npcd378_acpi_hid(const struct device *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
/* Sanity checks */
|
||||
if (dev->path.type != DEVICE_PATH_PNP)
|
||||
return NULL;
|
||||
if (dev->path.pnp.port == 0)
|
||||
return NULL;
|
||||
if ((dev->path.pnp.device & 0xff) > NPCD378_GPIOA)
|
||||
return NULL;
|
||||
|
||||
const char *scope = acpi_device_path(dev);
|
||||
if (!scope) {
|
||||
printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(dev));
|
||||
return;
|
||||
switch (dev->path.pnp.device & 0xff) {
|
||||
case NPCD378_FDC:
|
||||
return ACPI_HID_FDC;
|
||||
case NPCD378_PP:
|
||||
return ACPI_HID_LPT;
|
||||
case NPCD378_SP1: /* fallthrough */
|
||||
case NPCD378_SP2:
|
||||
return ACPI_HID_COM;
|
||||
case NPCD378_AUX:
|
||||
return ACPI_HID_MOUSE;
|
||||
case NPCD378_KBC:
|
||||
return ACPI_HID_KEYBOARD;
|
||||
default:
|
||||
return ACPI_HID_PNP;
|
||||
}
|
||||
}
|
||||
|
||||
static void npcd378_ssdt_aux(struct device *dev)
|
||||
{
|
||||
/* Scope */
|
||||
acpigen_write_scope(acpi_device_path(dev));
|
||||
|
||||
acpigen_write_method("_PSW", 1);
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(ARG0_OP);
|
||||
acpigen_emit_namestring("^^MSFG");
|
||||
acpigen_pop_len(); /* Pop Method */
|
||||
|
||||
acpigen_write_PRW(8, 3);
|
||||
|
||||
acpigen_pop_len(); /* Pop Scope */
|
||||
}
|
||||
|
||||
static void npcd378_ssdt_kbc(struct device *dev)
|
||||
{
|
||||
/* Scope */
|
||||
acpigen_write_scope(acpi_device_path(dev));
|
||||
|
||||
acpigen_write_method("_PSW", 1);
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(ARG0_OP);
|
||||
acpigen_emit_namestring("^^KBFG");
|
||||
acpigen_pop_len(); /* Pop Method */
|
||||
|
||||
acpigen_write_PRW(8, 3);
|
||||
|
||||
acpigen_pop_len(); /* Pop Scope */
|
||||
}
|
||||
|
||||
static void npcd378_ssdt_pwr(struct device *dev)
|
||||
{
|
||||
const char *name = acpi_device_path(dev);
|
||||
const char *scope = acpi_device_scope(dev);
|
||||
char *tmp_name;
|
||||
|
||||
/* Scope */
|
||||
acpigen_write_scope(name);
|
||||
|
||||
acpigen_emit_ext_op(OPREGION_OP);
|
||||
acpigen_emit_namestring("SWCR");
|
||||
acpigen_emit_byte(SYSTEMIO);
|
||||
acpigen_emit_namestring("IO0B");
|
||||
acpigen_emit_namestring("IO0S");
|
||||
|
||||
struct fieldlist l1[] = {
|
||||
FIELDLIST_OFFSET(0),
|
||||
FIELDLIST_NAMESTR("LEDC", 8),
|
||||
FIELDLIST_NAMESTR("SWCC", 8),
|
||||
};
|
||||
|
||||
acpigen_write_field("SWCR", l1, ARRAY_SIZE(l1), FIELD_BYTEACC |
|
||||
FIELD_NOLOCK | FIELD_PRESERVE);
|
||||
|
||||
acpigen_emit_ext_op(OPREGION_OP);
|
||||
acpigen_emit_namestring("RNTR");
|
||||
acpigen_emit_byte(SYSTEMIO);
|
||||
acpigen_emit_namestring("IO1B");
|
||||
acpigen_emit_namestring("IO1S");
|
||||
|
||||
struct fieldlist l2[] = {
|
||||
FIELDLIST_OFFSET(0),
|
||||
FIELDLIST_NAMESTR("GPES", 8),
|
||||
FIELDLIST_NAMESTR("GPEE", 8),
|
||||
FIELDLIST_OFFSET(8),
|
||||
FIELDLIST_NAMESTR("GPS0", 8),
|
||||
FIELDLIST_NAMESTR("GPS1", 8),
|
||||
FIELDLIST_NAMESTR("GPS2", 8),
|
||||
FIELDLIST_NAMESTR("GPS3", 8),
|
||||
FIELDLIST_NAMESTR("GPE0", 8),
|
||||
FIELDLIST_NAMESTR("GPE1", 8),
|
||||
FIELDLIST_NAMESTR("GPE2", 8),
|
||||
FIELDLIST_NAMESTR("GPE3", 8),
|
||||
};
|
||||
|
||||
acpigen_write_field("RNTR", l2, ARRAY_SIZE(l2), FIELD_BYTEACC |
|
||||
FIELD_NOLOCK | FIELD_PRESERVE);
|
||||
|
||||
/* Method (SIOW, 1, NotSerialized) */
|
||||
acpigen_write_method("SIOW", 1);
|
||||
acpigen_write_store();
|
||||
acpigen_emit_namestring("^GPS2");
|
||||
acpigen_emit_namestring("^^PMFG");
|
||||
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(ZERO_OP);
|
||||
acpigen_emit_namestring("^GPEE");
|
||||
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(ZERO_OP);
|
||||
acpigen_emit_namestring("^GPE0");
|
||||
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(ZERO_OP);
|
||||
acpigen_emit_namestring("^GPE1");
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
acpigen_emit_namestring("^LEDC");
|
||||
acpigen_write_integer(0xE0);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
|
||||
acpigen_emit_byte(OR_OP);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
acpigen_write_integer(0x1E);
|
||||
acpigen_emit_namestring("^LEDC");
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
acpigen_emit_namestring("^SWCC");
|
||||
acpigen_write_integer(0xBF);
|
||||
acpigen_emit_namestring("^SWCC");
|
||||
|
||||
acpigen_pop_len(); /* SIOW method */
|
||||
|
||||
/* Method (SIOS, 1, NotSerialized) */
|
||||
acpigen_write_method("SIOS", 1);
|
||||
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LNOT_OP);
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_byte(ARG0_OP);
|
||||
acpigen_write_integer(5);
|
||||
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_namestring("^^KBFG");
|
||||
acpigen_emit_byte(ONE_OP);
|
||||
|
||||
acpigen_emit_byte(OR_OP);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
acpigen_write_integer(0xE8);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
|
||||
acpigen_pop_len(); /* Pop If */
|
||||
acpigen_write_else();
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
acpigen_write_integer(0x17);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
|
||||
acpigen_pop_len(); /* Pop Else */
|
||||
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_namestring("^^MSFG");
|
||||
acpigen_emit_byte(ONE_OP);
|
||||
|
||||
acpigen_emit_byte(OR_OP);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
acpigen_write_integer(0x10);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
|
||||
acpigen_pop_len(); /* Pop If */
|
||||
acpigen_write_else();
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
acpigen_write_integer(0xEF);
|
||||
acpigen_emit_namestring("^GPE2");
|
||||
|
||||
acpigen_pop_len(); /* Pop Else */
|
||||
|
||||
/* Enable wake on GPE */
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(ONE_OP);
|
||||
acpigen_emit_namestring("^GPEE");
|
||||
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_byte(ARG0_OP);
|
||||
acpigen_write_integer(3);
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
acpigen_emit_namestring("^LEDC");
|
||||
acpigen_write_integer(0xE0);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
|
||||
acpigen_emit_byte(OR_OP);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
acpigen_write_integer(0x1C);
|
||||
acpigen_emit_namestring("^LEDC");
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
acpigen_emit_namestring("^SWCC");
|
||||
acpigen_write_integer(0xBF);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
|
||||
acpigen_emit_byte(OR_OP);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
acpigen_write_integer(0x40);
|
||||
acpigen_emit_namestring("^SWCC");
|
||||
|
||||
acpigen_pop_len(); /* Pop If */
|
||||
|
||||
acpigen_pop_len(); /* Pop If */
|
||||
|
||||
acpigen_write_store();
|
||||
acpigen_write_integer(0x10);
|
||||
acpigen_emit_namestring("^GPE0");
|
||||
|
||||
acpigen_write_store();
|
||||
acpigen_write_integer(0x20);
|
||||
acpigen_emit_namestring("^GPE1");
|
||||
|
||||
acpigen_pop_len(); /* Pop SIOS method */
|
||||
|
||||
acpigen_pop_len(); /* Pop Scope */
|
||||
|
||||
/* Inject into parent: */
|
||||
acpigen_write_scope(acpi_device_scope(dev));
|
||||
|
||||
acpigen_write_name_integer("MSFG", 1);
|
||||
acpigen_write_name_integer("KBFG", 1);
|
||||
acpigen_write_name_integer("PMFG", 0);
|
||||
|
||||
/* DSDT must call SIOW on _WAK */
|
||||
/* Method (SIOW, 1, NotSerialized) */
|
||||
acpigen_write_method("SIOW", 1);
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
tmp_name = strconcat(name, ".SIOW");
|
||||
acpigen_emit_namestring(tmp_name);
|
||||
free(tmp_name);
|
||||
|
||||
acpigen_emit_byte(ARG0_OP);
|
||||
acpigen_pop_len();
|
||||
|
||||
/* DSDT must call SIOS on _PTS */
|
||||
/* Method (SIOS, 1, NotSerialized) */
|
||||
acpigen_write_method("SIOS", 1);
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
tmp_name = strconcat(name, ".SIOS");
|
||||
acpigen_emit_namestring(tmp_name);
|
||||
free(tmp_name);
|
||||
acpigen_emit_byte(ARG0_OP);
|
||||
acpigen_pop_len(); /* Pop Method */
|
||||
|
||||
acpigen_pop_len(); /* Scope */
|
||||
|
||||
acpigen_write_scope("\\_GPE");
|
||||
|
||||
/* Method (SIOH, 0, NotSerialized) */
|
||||
acpigen_write_method("_L08", 0);
|
||||
acpigen_emit_byte(AND_OP);
|
||||
tmp_name = strconcat(scope, ".PMFG");
|
||||
acpigen_emit_namestring(tmp_name);
|
||||
free(tmp_name);
|
||||
acpigen_write_integer(0xE8);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LGREATER_OP);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
acpigen_emit_byte(ZERO_OP);
|
||||
|
||||
acpigen_emit_byte(NOTIFY_OP);
|
||||
tmp_name = strconcat(scope, ".L060");
|
||||
acpigen_emit_namestring(tmp_name);
|
||||
free(tmp_name);
|
||||
acpigen_write_integer(2);
|
||||
|
||||
acpigen_pop_len(); /* Pop If */
|
||||
|
||||
acpigen_emit_byte(AND_OP);
|
||||
tmp_name = strconcat(scope, ".PMFG");
|
||||
acpigen_emit_namestring(tmp_name);
|
||||
free(tmp_name);
|
||||
acpigen_write_integer(0x10);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LGREATER_OP);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
acpigen_emit_byte(ZERO_OP);
|
||||
|
||||
acpigen_emit_byte(NOTIFY_OP);
|
||||
tmp_name = strconcat(scope, ".L050");
|
||||
acpigen_emit_namestring(tmp_name);
|
||||
free(tmp_name);
|
||||
acpigen_write_integer(2);
|
||||
acpigen_pop_len(); /* Pop If */
|
||||
|
||||
acpigen_pop_len(); /* Pop Method */
|
||||
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
static void npcd378_fill_ssdt_generator(struct device *dev)
|
||||
{
|
||||
superio_common_fill_ssdt_generator(dev);
|
||||
|
||||
switch (dev->path.pnp.device) {
|
||||
case NPCD378_PWR: {
|
||||
res = find_resource(dev, PNP_IDX_IO0);
|
||||
if (!res || !res->base) {
|
||||
printk(BIOS_ERR, "NPCD378: LDN%u IOBASE not set.\n",
|
||||
NPCD378_PWR);
|
||||
case NPCD378_PWR:
|
||||
npcd378_ssdt_pwr(dev);
|
||||
break;
|
||||
case NPCD378_AUX:
|
||||
npcd378_ssdt_aux(dev);
|
||||
break;
|
||||
case NPCD378_KBC:
|
||||
npcd378_ssdt_kbc(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
acpigen_write_scope(scope);
|
||||
acpigen_write_name_integer("SWB", res->base);
|
||||
acpigen_write_name_integer("SWL", res->size);
|
||||
acpigen_pop_len(); /* pop scope */
|
||||
|
||||
res = find_resource(dev, PNP_IDX_IO1);
|
||||
if (!res || !res->base) {
|
||||
printk(BIOS_ERR, "NPCD378: LDN%u IOBASE2 not set.\n",
|
||||
NPCD378_PWR);
|
||||
break;
|
||||
}
|
||||
|
||||
acpigen_write_scope(scope);
|
||||
acpigen_write_name_integer("RNB", res->base);
|
||||
acpigen_write_name_integer("RNL", res->size);
|
||||
acpigen_pop_len(); /* pop scope */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *npcd378_acpi_name(const struct device *dev)
|
||||
{
|
||||
return "SIO0";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -141,8 +431,9 @@ static struct device_operations ops = {
|
|||
.init = npcd378_init,
|
||||
.ops_pnp_mode = &pnp_conf_mode_8787_aa,
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
.acpi_fill_ssdt_generator = npcd378_ssdt,
|
||||
.acpi_name = npcd378_acpi_name,
|
||||
.acpi_fill_ssdt_generator = npcd378_fill_ssdt_generator,
|
||||
.acpi_name = superio_common_ldn_acpi_name,
|
||||
.acpi_hid = npcd378_acpi_hid,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue