1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <device/pnp.h>
6 #include <device/pnp_ops.h>
7 #include <superio/conf_mode.h>
11 #include "sch5545_emi.h"
13 static uint16_t emi_bar
;
15 #ifdef __SIMPLE_DEVICE__
16 static void sch5545_enter_conf_state(pnp_devfn_t dev
)
18 unsigned int port
= dev
>> 8;
22 static void sch5545_exit_conf_state(pnp_devfn_t dev
)
24 unsigned int port
= dev
>> 8;
29 uint16_t sch5545_read_emi_bar(uint8_t sio_port
)
33 #ifdef __SIMPLE_DEVICE__
34 pnp_devfn_t lpcif
= PNP_DEV(sio_port
, SCH5545_LDN_LPC
);
35 sch5545_enter_conf_state(lpcif
);
37 struct device
*lpcif
= dev_find_slot_pnp(sio_port
, SCH5545_LDN_LPC
);
40 pnp_enter_conf_mode_55(lpcif
);
42 pnp_set_logical_device(lpcif
);
44 bar
= pnp_read_config(lpcif
, SCH5545_BAR_EM_IF
+ 2);
45 bar
|= pnp_read_config(lpcif
, SCH5545_BAR_EM_IF
+ 3) << 8;
47 #ifdef __SIMPLE_DEVICE__
48 sch5545_exit_conf_state(lpcif
);
50 pnp_exit_conf_mode_aa(lpcif
);
55 void sch5545_emi_init(uint8_t sio_port
)
57 emi_bar
= sch5545_read_emi_bar(sio_port
);
61 void sch5545_emi_ec2h_mailbox_clear(void)
63 sch5545_emi_ec2h_mbox_write(sch5545_emi_ec2h_mbox_read());
66 void sch5545_emi_disable_interrupts(void)
68 sch5545_emi_set_int_mask(0);
71 void sch5545_emi_h2ec_mbox_write(uint8_t mbox_message
)
73 outb(mbox_message
, emi_bar
+ SCH5545_EMI_HOST_TO_EC_MAILBOX
);
76 uint8_t sch5545_emi_h2ec_mbox_read(void)
78 return inb(emi_bar
+ SCH5545_EMI_HOST_TO_EC_MAILBOX
);
81 void sch5545_emi_ec2h_mbox_write(uint8_t mbox_message
)
83 outb(mbox_message
, emi_bar
+ SCH5545_EMI_EC_TO_HOST_MAILBOX
);
86 uint8_t sch5545_emi_ec2h_mbox_read(void)
88 return inb(emi_bar
+ SCH5545_EMI_EC_TO_HOST_MAILBOX
);
91 void sch5545_emi_set_int_mask(uint16_t mask
)
93 outw(mask
, emi_bar
+ SCH5545_EMI_INT_MASK
);
96 void sch5545_emi_set_int_mask_low(uint8_t mask
)
98 outb(mask
, emi_bar
+ SCH5545_EMI_INT_MASK
);
101 void sch5545_emi_set_int_mask_high(uint8_t mask
)
103 outb(mask
, emi_bar
+ SCH5545_EMI_INT_MASK
+ 1);
106 uint8_t sch5545_emi_get_int_mask_low(void)
108 return inb(emi_bar
+ SCH5545_EMI_INT_MASK
);
111 uint8_t sch5545_emi_get_int_mask_high(void)
113 return inb(emi_bar
+ SCH5545_EMI_INT_MASK
+ 1);
116 uint16_t sch5545_emi_get_int_mask(void)
118 return inw(emi_bar
+ SCH5545_EMI_INT_MASK
);
121 void sch5545_emi_set_int_src_low(uint8_t int_src
)
123 outb(int_src
, emi_bar
+ SCH5545_EMI_INT_SOURCE
);
126 void sch5545_emi_set_int_src_high(uint8_t int_src
)
128 outb(int_src
, emi_bar
+ SCH5545_EMI_INT_SOURCE
+ 1);
131 uint8_t sch5545_emi_get_int_src_low(void)
133 return inb(emi_bar
+ SCH5545_EMI_INT_SOURCE
);
136 uint8_t sch5545_emi_get_int_src_high(void)
138 return inb(emi_bar
+ SCH5545_EMI_INT_SOURCE
+ 1);
140 uint16_t sch5545_emi_get_int_src(void)
142 return inw(emi_bar
+ SCH5545_EMI_INT_SOURCE
);
145 void sch5545_emi_set_int_src(uint16_t int_src
)
147 outw(int_src
, emi_bar
+ SCH5545_EMI_INT_SOURCE
);
150 void sch5545_emi_set_ec_addr(uint16_t addr
)
152 outw(addr
, emi_bar
+ SCH5545_EMI_EC_ADDR
);
155 uint16_t sch5545_emi_read_ec_addr(void)
157 return inw(emi_bar
+ SCH5545_EMI_EC_ADDR
);
160 void sch5545_emi_ec_write8(uint16_t addr
, uint8_t data
)
162 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_8BIT_ACCESS
);
163 outb(data
, emi_bar
+ SCH5545_EMI_EC_DATA
+ (addr
& 3));
166 void sch5545_emi_ec_write16(uint16_t addr
, uint16_t data
)
168 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_16BIT_ACCESS
);
169 outw(data
, emi_bar
+ SCH5545_EMI_EC_DATA
+ (addr
& 2));
172 void sch5545_emi_ec_write32(uint16_t addr
, uint32_t data
)
174 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_32BIT_ACCESS
);
175 outl(data
, emi_bar
+ SCH5545_EMI_EC_DATA
);
178 void sch5545_emi_ec_write32_bulk(uint16_t addr
, const uint32_t *buffer
, size_t len
)
180 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_32BIT_AUTO_ACCESS
);
183 outl(*(buffer
++), emi_bar
+ SCH5545_EMI_EC_DATA
);
188 uint8_t sch5545_emi_ec_read8(uint16_t addr
)
190 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_8BIT_ACCESS
);
191 return inb(emi_bar
+ SCH5545_EMI_EC_DATA
+ (addr
& 3));
194 uint16_t sch5545_emi_ec_read16(uint16_t addr
)
196 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_16BIT_ACCESS
);
197 return inw(emi_bar
+ SCH5545_EMI_EC_DATA
+ (addr
& 2));
200 uint32_t sch5545_emi_ec_read32(uint16_t addr
)
202 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_32BIT_ACCESS
);
203 return inb(emi_bar
+ SCH5545_EMI_EC_DATA
);
206 void sch5545_emi_ec_read32_bulk(uint16_t addr
, uint32_t *buffer
, size_t len
)
208 sch5545_emi_set_ec_addr((addr
& 0xfffc) | EMI_EC_32BIT_AUTO_ACCESS
);
211 *(buffer
++) = inl(emi_bar
+ SCH5545_EMI_EC_DATA
);