(Phil) Voodoo3 I2C bus driver works and now properly detects missed 'acks'

during a transaction.  It also can detect a 'hung' bus prior to starting
a transaction.  It seems to properly read and write to the BT869.

Todo: support for multiple voodoo3 cards.  Support for other transaction
types (fairly simple).  Use code as a start for a better algo-bit
adapter template?  Complete the bt869 driver.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@452 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Philip Edelbrock committed 1999-05-07 06:20:59 +00:00
1 parent ab1d4f5d32
commit ad7c7e2834
2 files changed
+76 -35

No files matched your search

+73 -34
View File
@@ -111,14 +111,13 @@ inline int rdat(void)
void Voodoo3_I2CStart(void)
{
dat(1);
out();
dat(0);
clkon();
out();
dat(0);
out();
clkoff();
out();
clkon();
}
void Voodoo3_I2CStop(void)
@@ -129,38 +128,41 @@ void Voodoo3_I2CStop(void)
out();
dat(1);
out();
clkoff();
out();
clkon();
out();
}
int Voodoo3_I2CAck(int ack)
int Voodoo3_I2CAck()
{
/* dat(ack);
int ack;
dat(1); /* put data line in tristate/hi */
clkon();
out();
clkon();/
out(); testing PAE */
ack=rdat();
clkoff();
out();
return ack;
}
int Voodoo3_I2CReadByte(int ack)
int Voodoo3_I2CReadByte()
{
int i,temp;
unsigned char data=0;
clkoff();
dat(1);
out();
for (i=7; i>=0; i--) {
out();
clkon();
out();
data|=(rdat()<<i);
clkoff();
out();
clkoff();
}
temp=Voodoo3_I2CAck(ack);
temp=Voodoo3_I2CAck();
#ifdef DEBUG
printk("i2c-voodoo3: ack -->0x%X!\n",temp);
printk("i2c-voodoo3: Readbyte ack -->0x%X, read result -->0x%X\n",temp,data);
#endif
if (! temp)
return data;
@@ -171,49 +173,84 @@ int Voodoo3_I2CReadByte(int ack)
int Voodoo3_I2CSendByte(unsigned char data)
{
int i;
clkoff();
dat(0);
out();
int i,temp;
for (i=7; i>=0; i--) {
dat(data&(1<<i));
dat(temp=data&(1<<i));
out();
clkon();
out();
dat(temp);
clkoff();
out();
}
return Voodoo3_I2CAck(1);
temp=Voodoo3_I2CAck();
#ifdef DEBUG
printk("i2c-voodoo3: Writebyte ack -->0x%X\n",temp);
#endif
return temp;
}
int Voodoo3_BusCheck(void) {
/* Check the bus to see if it is in use */
if (! rdat()) {
printk("i2c-voodoo3: I2C bus in use or hung! Try again later.\n");
return 1;
}
return 0;
}
/* Note, this is actually a byte read and not a byte_data read */
/* I.e., the command value is dumped. */
int Voodoo3_I2CRead(int adr,int command)
int Voodoo3_I2CRead(int addr,int command)
{
int i,j,dat;
int dat=0;
Voodoo3_I2CStart();
Voodoo3_I2CSendByte(adr);
dat=Voodoo3_I2CReadByte(1);
Voodoo3_I2CStop();
if (Voodoo3_I2CSendByte(addr)) {
#ifdef DEBUG
printk("i2c-voodoo3: Byte read at addr:0x%X (command:0x%X) result:0x%X\n",adr,command,dat);
printk("i2c-voodoo3: No Ack on addr WriteByte to addr 0x%X\n",addr);
#endif
dat=-1;
goto ENDREAD; }
dat=Voodoo3_I2CReadByte();
ENDREAD: Voodoo3_I2CStop();
#ifdef DEBUG
printk("i2c-voodoo3: Byte read at addr:0x%X (command:0x%X) result:0x%X\n",addr,command,dat);
#endif
return dat;
}
void Voodoo3_I2CWrite(int addr,int command,int data)
int Voodoo3_I2CWrite(int addr,int command,int data)
{
int temp=0;
Voodoo3_I2CStart();
Voodoo3_I2CSendByte(addr);
Voodoo3_I2CSendByte(command);
Voodoo3_I2CSendByte(data);
Voodoo3_I2CStop();
if (Voodoo3_I2CSendByte(addr)) {
#ifdef DEBUG
printk("i2c-voodoo3: No Ack on addr WriteByte to addr 0x%X\n",addr);
#endif
temp=-1;
goto ENDWRITE; }
if (Voodoo3_I2CSendByte(command)) {
#ifdef DEBUG
printk("i2c-voodoo3: No Ack on command WriteByte to addr 0x%X\n",addr);
#endif
temp=-1;
goto ENDWRITE; }
if (Voodoo3_I2CSendByte(data)) {
#ifdef DEBUG
printk("i2c-voodoo3: No Ack on data WriteByte to addr 0x%X\n",addr);
#endif
}
temp=-1;
ENDWRITE: Voodoo3_I2CStop();
#ifdef DEBUG
printk("i2c-voodoo3: Byte write at addr:0x%X command:0x%X data:0x%X\n",addr,command,data);
#endif
return temp;
}
void config_v3(struct pci_dev *dev, int num)
@@ -268,6 +305,8 @@ s32 voodoo3_access(u8 addr, char read_write,
{
int temp;
if (Voodoo3_BusCheck()) return -1;
if ((size == SMBUS_BYTE_DATA) || (size == SMBUS_BYTE)) {
addr=((addr & 0x7f) << 1) | (read_write & 0x01);
if (read_write == SMBUS_READ) {
@@ -283,7 +322,7 @@ int temp;
printk("i2c-voodoo3: access returning 0x%X\n",data->byte);
#endif
} else {
Voodoo3_I2CWrite(addr,command,data->byte);
return Voodoo3_I2CWrite(addr,command,data->byte);
}
return 0;
} else { return -1; } /* The rest isn't implemented yet */
+3 -1
View File
@@ -31,6 +31,8 @@
/* Addresses to scan */
static unsigned short normal_i2c[] = {SENSORS_I2C_END};
/* also can be on 0x45 */
static unsigned short normal_i2c_range[] = {0x44,0x45,SENSORS_I2C_END};
static unsigned int normal_isa[] = {SENSORS_ISA_END};
static unsigned int normal_isa_range[] = {SENSORS_ISA_END};
@@ -169,7 +171,7 @@ printk("bt869.o: probing address %d .\n",address);
new_client->addr,0xC4,0); /* set status bank 0 */
cur = smbus_read_byte_data(adapter,address,0);
printk("bt869.o: address 0x%X testing-->0x%X\n",address,cur);
if ((cur | 0x27) != 0x27)
if (cur != 0x22)
goto ERROR1;
/* Determine the chip type */