diff options
author | Vladimir Serbinenko <phcoder@gmail.com> | 2014-08-01 02:49:27 +0200 |
---|---|---|
committer | Vladimir Serbinenko <phcoder@gmail.com> | 2014-08-01 17:36:54 +0200 |
commit | caf1df0278ef743274b7811e0b4bfb58c122ce4e (patch) | |
tree | 6a4ce3cba90b16dfe4aa60f210303959a8800aea /src/southbridge/intel/i82801ix/smbus.h | |
parent | 2c3f94454dd29532569fd80f954e6289e7ee2fda (diff) |
i82801ix: Provide ramstage smbus functions.
Change-Id: Idc62e382a4002274abe6c23d76fe0874c62846c5
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-on: http://review.coreboot.org/6433
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Diffstat (limited to 'src/southbridge/intel/i82801ix/smbus.h')
-rw-r--r-- | src/southbridge/intel/i82801ix/smbus.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/southbridge/intel/i82801ix/smbus.h b/src/southbridge/intel/i82801ix/smbus.h index f215fb4f4d..af95c54ab8 100644 --- a/src/southbridge/intel/i82801ix/smbus.h +++ b/src/southbridge/intel/i82801ix/smbus.h @@ -97,3 +97,48 @@ static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned add } return byte; } + +#ifndef __PRE_RAM__ +static int do_smbus_write_byte(unsigned smbus_base, unsigned device, unsigned address, unsigned data) +{ + unsigned char global_status_register; + + if (smbus_wait_until_ready(smbus_base) < 0) + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + + /* Setup transaction */ + /* Disable interrupts */ + outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL); + /* Set the device I'm talking too */ + outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD); + /* Set the command/address... */ + outb(address & 0xff, smbus_base + SMBHSTCMD); + /* Set up for a byte data read */ + outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2), + (smbus_base + SMBHSTCTL)); + /* Clear any lingering errors, so the transaction will run */ + outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT); + + /* Clear the data byte... */ + outb(data, smbus_base + SMBHSTDAT0); + + /* Start the command */ + outb((inb(smbus_base + SMBHSTCTL) | 0x40), + smbus_base + SMBHSTCTL); + + /* Poll for transaction completion */ + if (smbus_wait_until_done(smbus_base) < 0) + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + + global_status_register = inb(smbus_base + SMBHSTSTAT); + + /* Ignore the "In Use" status... */ + global_status_register &= ~(3 << 5); + + /* Read results of transaction */ + if (global_status_register != (1 << 1)) + return SMBUS_ERROR; + + return 0; +} +#endif |