第一种方式:遵循ACPI规范完成通信,通过LPC的62h、64h偏移/端口。
此种方式适合host对EC进行读写操作。
EC提供256字节的可被系统读写的RAM空间,EC的资源在该RAM空间映射,通过访问对应偏移(0x00~0xFF),即可操作对应的资源。实际上就是外部RAM的前256字节。EC会将键盘、触摸板、电池、温度传感器等一些设备的状态信息保存在此地址范围空间的RAM内存中,不同host的EC规范略有不同。
EC中有三个寄存器,分别为状态寄存器EC_SC、命令寄存器EC_SC和数据寄存器EC_DATA。而状态寄存器和命令寄存器同属于一个寄存器,这几个寄存器遵循着ACPI规范。host可以根据ACPI协议规范来与EC进行通信。
EC寄存器端口分配
寄存器 |
偏移/端口 |
R/W |
说明 |
EC_SC |
0x66 |
R |
EC状态寄存器 |
EC_SC |
0x66 |
W |
EC命令寄存器 |
EC_DATA |
0x62 |
R/W |
EC数据寄存器 |
以下是寄存器的详细介绍。
EC状态寄存器(EC_SC(R)),该寄存器是一个只读寄存器,它反映了此时EC接口的状态。下图为该寄存器表。
EC状态寄存器表中各位的具体含义:
OBF(Output Buffer is Full),该状态位置1时,意味着EC已经将一个字节的数据写入了命令/数据端口中,但是此时host还没有读出/取走该数据。当host读取EC的状态寄存器发现该位置1时,host将会从命令/数据端口中取走数据,取走数据后,硬件将自动为该位清零。此时表明数据已经被host取走,EC可以再次向host写入更多的数据了。
IBF(Input Buffer is Full),该状态位置1时,意味着host已经将一字节的数据写入到了EC的命令/数据端口中,但此时EC并未将此字节的数据/命令取走,当EC将测到该标志位为1时,EC将取走主机写入的命令/数据,读取完成后,已经将自动为该位清零。此时host可以向EC写入更多的数据了。
SCI_EVT(System command interrupt_event),当该位置1时,EC检测到一个需要host的控制程序注意的内部事件。
SMI_EVT(System control interrupt_event),当该位置1时,EC检测到一个需要host的管理中断服务程序注意的内部事件。
BURST位置1时,表实EC已经收到了来自host的BURST Enable命令,EC已经停止了正常的处理,等待从host发来的一系列命令。这允许host一次快速读取/写入几个字节的数据/命令而没有命令间的SCIs开销。
CMD标志位置1时,表实数据寄存器中的数据为命令字节,当该位为0时,表实数据寄存器中的数据为数据字节。
EC命令寄存器(EC_SC (W)),这是一个只写寄存器,允许host向EC发出命令。当一字节数据写入后,EC状态寄存器中的IBF和CMD位都为1,表明该数据位命令数据。
EC数据存器(EC_DATA (R/W)),这是一个读写寄存器,该寄存器允许host与EC双向通信。
Host是如何通过ACPI规范来与EC通信的呢,其实是通过0x62、0x66偏移/端口(LPC总线)来进行数据交换。数据交换的形式和步骤如下:
EC提供256字节的可被系统读写的RAM空间,EC的资源在该RAM空间映射,通过访问对应偏移(0x00~0xFF),即可操作对应的资源。
例如主机要获取电池的的电量情况,host可以通过EC命令集来获取,EC命令集如下:
EC命令集
host可以先向EC发送0x80读取EC寄存器命令,紧接在0x80后面的是一个EC的RAM资源的地址偏移,host等待EC的状态寄存器OBF置位时,host可以取走EC_DATA数据寄存器中的内容,改内容即位host请求读取的数据。
第二种方式:利用KBC完成通信,通过LPC的60h、64h偏移/端口。
host与EC通过0x62/0x66偏移/端口来进行通信,是需要遵循APCI规范的;host也可以直接通过0x60/0x64偏移/端口与KBC来进行通信,KBC收到数据后进一步将数据转移给EC。
在此方式下,不仅host可以对EC进行读写操作,而且EC同样可以对host进行读写操作
KBC寄存器端口分配
寄存器 |
偏移/端口 |
R/W |
说明 |
KBC_SC |
0x64 |
R |
键盘控制状态寄存器 |
KBC_SC |
0x64 |
W |
键盘控制命令寄存器 |
KBC_DATA |
0x60 |
R/W |
键盘控制数据寄存器 |
host可以先向EC发送0x80读取EC寄存器命令,紧接在0x80后面的是一个EC的RAM资源的地址偏移,host等待EC的状态寄存器OBF置位时,host可以取走EC_DATA数据寄存器中的内容,改内容即位host请求读取的数据。
读操作:
1.往EC的Command Port写入0x80命令
2.往EC的Data Port写入需要读取的数据的Offset
3.读取EC的Data Port,读到的数据便是结果
写操作:
1.往EC的Command Port写入0x81命令
2.往EC的Data Port写入所写数据的Offset
3.往EC的Data Port写入所写数据的值