/* * Write to SMBus */ static int bcm1250_smbus_write(int smb_chan, UINT8 slave, UINT8 *buf, int len) { int err; /* * Make sure the bus is idle (ignore error here) */ bcm1250_smbus_waitready(smb_chan); /* * Depending on how many bytes we're writing, fill in the various * SMB registers and execute the command. */ switch (len) { case 1: /* "command" byte alone */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CMD), buf[0]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_WR1BYTE) | ((UINT64)slave)); break; case 2: /* "command" byte plus a data byte */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CMD), buf[0]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_DATA), buf[1]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_WR2BYTE) | ((UINT64)slave)); break; case 3: /* "command" byte plus 2 data bytes */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CMD), buf[0]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_DATA), ((UINT64)(buf[1])) | (((UINT64)buf[2]) << 8)); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_WR3BYTE) | ((UINT64)slave)); break; default: return -1; break; } /* * Wait for command to complete. */ err = bcm1250_smbus_waitready(smb_chan); if (err < 0) return err; return 0; }
/* * read from SMBus */ static int bcm1250_smbus_read(int smb_chan, UINT8 slave, UINT8 *buf, int len) { int err; while (len > 0) { err = bcm1250_smbus_waitready(smb_chan); if (err < 0) return err; SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_RD1BYTE) | ((UINT64)slave)); err = bcm1250_smbus_waitready(smb_chan); if (err < 0) return err; *buf++ = (UINT8) SBREADCSR(A_SMB_REGISTER(smb_chan, R_SMB_DATA)); len--; } return 0; }
static int temp_smbus_write(int chan,int slaveaddr,int devaddr,int data) { uintptr_t reg; int err; /* * Make sure the bus is idle (probably should * ignore error here) */ if (temp_smbus_waitready(chan) < 0) return -1; /* * Write the device address to the controller. There are two * parts, the high part goes in the "CMD" field, and the * low part is the data field. */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD)); SBWRITECSR(reg,devaddr); /* * Write the data byte */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA)); SBWRITECSR(reg,data); /* * Do the write command. */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START)); SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR2BYTE) | slaveaddr); err = temp_smbus_waitready(chan); return err; }