前几天提到了SIO有关的,之前略有研究,不过确实实际只研究过小部分功能,也就做龙芯BIOS的时候参与过SIO的有关编程,因为这个东西笔记本是肯定不会用的,笔记本用EC,这个SIO也就相当于PC板上的EC了,某位大佬既然问了我这些,回去立马找了份SIO芯片的文档,仔细看了下,也算查漏补缺了,这篇主要记录读写逻辑设备的原理以及有关编程
咱们还是以IT8738芯片为例子(实际最新的芯片不得而知,手上就这一份SPEC)
下面的代码未曾实践过,只是我根据spec写出来的,没写对的烦请指正
逻辑设备号(LDN),LDN在芯片文档中的配置章节有提到,我们来看下,分别是1、2、3、4、5、6、7、8、A、F、10、11、12、19
之前在SIO相关知识以及Smart Fan的初步实现文章中提到过怎么操作SIO,那么读写逻辑设备,咱们先把流程理顺一下:
1、进入PNP mode
2、选择逻辑设备
3、读取该逻辑设备的寄存器
4、写该逻辑设备某个寄存器的值
5、退出PNP mode
根据这个流程,我们可以直接写5个函数:
1、进入PNP mode
void EnterPnpMode(void)
{
IoWrite8(0x2E, 0x87);
IoWrite8(0x2E, 0x01);
IoWrite8(0x2E, 0x55);
IoWrite8(0x2E, 0x55);
return;
}
2、选择逻辑设备
void SelectLDN (void)
{
//LDN Selection
unsigned int LDNumber;
scanf("%x",&LDNumber);
printf("Now LDN:%x",LDNumber);
IoWrite8(0x2E,0x07);
IoWrite8(0x2F,LDNumber);
return;
}
3、读取该逻辑设备的寄存器
void ReadLdnRegister(void)
{
unsigned int row,col;
unsigned int addr=0;
unsigned int value[16][16];
printf("--------------------------------------------------------------\n\n");
printf("00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
for(row=0;row<16;row++)
{
for(col=0;col<16;col++)
{
IoWrite8(0x2E,addr);
value[row][col]=IoRead8(0x2F);
if(value[row][col]<16){
printf("0%X ",value[row][col]);
}else
{
printf("%x ",value[row][col]);
}
addr++;
}
printf("\n");
}
return;
}
4、写该逻辑设备的某个寄存器值
void WriteLdnRegister(void)
{
char order;
unsigned int index,data;
printf("Do you need to write registers? YES please intput W NO input Q:");
scanf("%c",&order);
if(order == 'W'){
printf("Please input Index:");
scanf("%x",&index);
printf("Please input Data:");
scanf("%x",&data);
IoWrite8(0x2E,index);
Iowrite8(0x2F,data);
} else
{
printf("Exit write ld reg:");
return;
}
return;
}
5、退出Pnp mode
void ExitPnpMode (void)
{
unsigned int RegData = 0;
IoWrite8(0x2E, 0x02);
RegData = IoRead8(0x2F) | BIT1;
IoWrite8(0x2E, 0x02);
IoWrite8(0x2F, RegData);
return;
}
ok,有了上述的函数,我们就可以写main函数了,整体的不写了,很容易,怎么组合怎么写,反正得在这个逻辑内,先进PNP mode,中间选择LDN,才能读写寄存器,最后退出,总体就是这样吧。