/* SPDX-License-Identifier: GPL-2.0-only */ #define __SIMPLE_DEVICE__ #include <arch/io.h> #include <device/pnp.h> #include <device/pnp_ops.h> #include <types.h> #include "ec.h" /* 10.7.2 ENABLE CONFIG MODE */ static void pnp_enter_conf_state(const pnp_devfn_t dev) { const u16 port = dev >> 8; outb(0x55, port); } /* 10.7.3 DISABLE CONFIG MODE */ static void pnp_exit_conf_state(const pnp_devfn_t dev) { const u16 port = dev >> 8; outb(0xaa, port); } void ec_espi_io_program_iobase(const u16 port, const u8 iobase_index, const u16 base) { const pnp_devfn_t dev = PNP_DEV(port, LDN_ESPI_IO_COMPONENT); pnp_enter_conf_state(dev); pnp_set_logical_device(dev); pnp_write_config(dev, iobase_index + 2, (base & 0x00ff) >> 0); /* Addr LSB */ pnp_write_config(dev, iobase_index + 3, (base & 0xff00) >> 8); /* Addr MSB */ pnp_write_config(dev, iobase_index + 0, base != 0x0000); /* Valid bit */ pnp_exit_conf_state(dev); } /* TABLE 14-5: RUNTIME REGISTER SUMMARY */ #define HOST_EC_MBOX 0x00 #define EC_HOST_MBOX 0x01 #define EC_ADDRESS_LSB 0x02 #define EC_ADDRESS_MSB 0x03 #define EC_DATA_BYTE(n) (0x04 + (n) % sizeof(u32)) #define INTERRUPT_SOURCE_LSB 0x08 #define INTERRUPT_SOURCE_MSB 0x09 #define INTERRUPT_MASK_LSB 0x0a #define INTERRUPT_MASK_MSB 0x0b #define APPLICATION_ID 0x0c /* 14.8.3 ACCESS TYPES */ enum emi_access_type { EMI_ACCESS_8_BIT = 0, EMI_ACCESS_16_BIT = 1, EMI_ACCESS_32_BIT = 2, EMI_ACCESS_32_BIT_AUTO_INC = 3, }; void ec_emi_read(u8 *dest, const u16 base, const u8 region, const u16 offset, const u16 length) { const u16 addr = ((region & 1) << 15) | (offset & 0x7ffc) | EMI_ACCESS_32_BIT_AUTO_INC; outb((addr & 0x00ff) >> 0, base + EC_ADDRESS_LSB); outb((addr & 0xff00) >> 8, base + EC_ADDRESS_MSB); /* EC_ADDRESS auto-increment happens when accessing EC_DATA_BYTE_3 */ for (u16 i = 0; i < length; i++) dest[i] = inb(base + EC_DATA_BYTE(offset + i)); }