You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
2.6 KiB
129 lines
2.6 KiB
/*
|
|
* 0 single
|
|
* 1 smb block
|
|
*/
|
|
int tgt_i2cread(int type,unsigned char *addr,int addrlen,unsigned char reg,unsigned char *buf,int count)
|
|
{
|
|
int i;
|
|
int device,offset;
|
|
char c;
|
|
device=addr[0];
|
|
offset=reg;
|
|
device |= 1;
|
|
memset(buf,-1,count);
|
|
switch(type&0xff)
|
|
{
|
|
case I2C_SINGLE:
|
|
for(i=0;i<count;i++)
|
|
{
|
|
linux_outb(device,SMBUS_HOST_ADDRESS);
|
|
linux_outb(offset+i,SMBUS_HOST_COMMAND);
|
|
linux_outb(0x8,SMBUS_HOST_CONTROL);
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
linux_outb(linux_inb(SMBUS_HOST_CONTROL)|0x40,SMBUS_HOST_CONTROL);
|
|
|
|
while(linux_inb(SMBUS_HOST_STATUS)&SMBUS_HOST_STATUS_BUSY);
|
|
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
buf[i]=linux_inb(SMBUS_HOST_DATA0);
|
|
}
|
|
break;
|
|
case I2C_SMB_BLOCK:
|
|
linux_outb(device,SMBUS_HOST_ADDRESS); //0xd3
|
|
linux_outb(offset,SMBUS_HOST_COMMAND);
|
|
linux_outb(count,SMBUS_HOST_DATA0);
|
|
linux_outb(0x14,SMBUS_HOST_CONTROL); //0x14
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
linux_outb(linux_inb(SMBUS_HOST_CONTROL)|0x40,SMBUS_HOST_CONTROL);
|
|
|
|
while(linux_inb(SMBUS_HOST_STATUS)&SMBUS_HOST_STATUS_BUSY);
|
|
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
for(i=0;i<count;i++)
|
|
{
|
|
buf[i]=linux_inb(SMBUS_HOST_DATA1+1);
|
|
}
|
|
break;
|
|
|
|
default: return 0;break;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int tgt_i2cwrite(int type,unsigned char *addr,int addrlen,unsigned char reg,unsigned char *buf,int count)
|
|
{
|
|
int i;
|
|
int device,offset;
|
|
char c;
|
|
device=addr[0];
|
|
offset=reg;
|
|
device &= ~1;
|
|
switch(type)
|
|
{
|
|
case I2C_SINGLE:
|
|
for(i=0;i<count;i++)
|
|
{
|
|
linux_outb(device,SMBUS_HOST_ADDRESS);
|
|
linux_outb(offset+i,SMBUS_HOST_COMMAND);
|
|
linux_outb(0x8,SMBUS_HOST_CONTROL);
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
linux_outb(buf[i],SMBUS_HOST_DATA0);
|
|
|
|
linux_outb(linux_inb(SMBUS_HOST_CONTROL)|0x40,SMBUS_HOST_CONTROL);
|
|
|
|
while(linux_inb(SMBUS_HOST_STATUS)&SMBUS_HOST_STATUS_BUSY);
|
|
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
}
|
|
break;
|
|
case I2C_SMB_BLOCK:
|
|
linux_outb(device,SMBUS_HOST_ADDRESS); //0xd3
|
|
linux_outb(offset,SMBUS_HOST_COMMAND);
|
|
linux_outb(count,SMBUS_HOST_DATA0);
|
|
linux_outb(0x14,SMBUS_HOST_CONTROL); //0x14
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
|
|
for(i=0;i<count;i++)
|
|
linux_outb(buf[i],SMBUS_HOST_DATA1+1);
|
|
c=linux_inb(SMBUS_HOST_CONTROL);
|
|
linux_outb(c|0x40,SMBUS_HOST_CONTROL);
|
|
|
|
while(linux_inb(SMBUS_HOST_STATUS)&SMBUS_HOST_STATUS_BUSY);
|
|
|
|
if((c=linux_inb(SMBUS_HOST_STATUS))&0x1f)
|
|
{
|
|
linux_outb(c,SMBUS_HOST_STATUS);
|
|
}
|
|
break;
|
|
default:return -1;break;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
|