diff options
-rw-r--r-- | src/southbridge/intel/common/smbus.c | 48 | ||||
-rw-r--r-- | src/southbridge/intel/common/smbus.h | 5 |
2 files changed, 43 insertions, 10 deletions
diff --git a/src/southbridge/intel/common/smbus.c b/src/southbridge/intel/common/smbus.c index db934a3f0b..9546258b5c 100644 --- a/src/southbridge/intel/common/smbus.c +++ b/src/southbridge/intel/common/smbus.c @@ -175,22 +175,23 @@ static int complete_command(unsigned int smbus_base) return cb_err_from_stat(status); } -int do_smbus_read_byte(unsigned int smbus_base, u8 device, +static int smbus_read_cmd(unsigned int smbus_base, u8 ctrl, u8 device, unsigned int address) { int ret; - u8 byte; + u16 word; /* Set up for a byte data read. */ - ret = setup_command(smbus_base, I801_BYTE_DATA, XMIT_READ(device)); + ret = setup_command(smbus_base, ctrl, XMIT_READ(device)); if (ret < 0) return ret; /* Set the command/address... */ outb(address, smbus_base + SMBHSTCMD); - /* Clear the data byte... */ + /* Clear the data bytes... */ outb(0, smbus_base + SMBHSTDAT0); + outb(0, smbus_base + SMBHSTDAT1); /* Start the command */ ret = execute_command(smbus_base); @@ -203,25 +204,30 @@ int do_smbus_read_byte(unsigned int smbus_base, u8 device, return ret; /* Read results of transaction */ - byte = inb(smbus_base + SMBHSTDAT0); - return byte; + word = inb(smbus_base + SMBHSTDAT0); + if (ctrl == I801_WORD_DATA) + word |= inb(smbus_base + SMBHSTDAT1) << 8; + + return word; } -int do_smbus_write_byte(unsigned int smbus_base, u8 device, +static int smbus_write_cmd(unsigned int smbus_base, u8 ctrl, u8 device, unsigned int address, unsigned int data) { int ret; /* Set up for a byte data write. */ - ret = setup_command(smbus_base, I801_BYTE_DATA, XMIT_WRITE(device)); + ret = setup_command(smbus_base, ctrl, XMIT_WRITE(device)); if (ret < 0) return ret; /* Set the command/address... */ outb(address, smbus_base + SMBHSTCMD); - /* Set the data byte... */ - outb(data, smbus_base + SMBHSTDAT0); + /* Set the data bytes... */ + outb(data & 0xff, smbus_base + SMBHSTDAT0); + if (ctrl == I801_WORD_DATA) + outb(data >> 8, smbus_base + SMBHSTDAT1); /* Start the command */ ret = execute_command(smbus_base); @@ -313,6 +319,28 @@ static int block_cmd_loop(unsigned int smbus_base, return bytes; } +int do_smbus_read_byte(unsigned int smbus_base, u8 device, unsigned int address) +{ + return smbus_read_cmd(smbus_base, I801_BYTE_DATA, device, address); +} + +int do_smbus_read_word(unsigned int smbus_base, u8 device, unsigned int address) +{ + return smbus_read_cmd(smbus_base, I801_WORD_DATA, device, address); +} + +int do_smbus_write_byte(unsigned int smbus_base, u8 device, unsigned int address, + unsigned int data) +{ + return smbus_write_cmd(smbus_base, I801_BYTE_DATA, device, address, data); +} + +int do_smbus_write_word(unsigned int smbus_base, u8 device, unsigned int address, + unsigned int data) +{ + return smbus_write_cmd(smbus_base, I801_WORD_DATA, device, address, data); +} + int do_smbus_block_read(unsigned int smbus_base, u8 device, u8 cmd, unsigned int max_bytes, u8 *buf) { diff --git a/src/southbridge/intel/common/smbus.h b/src/southbridge/intel/common/smbus.h index 4875581573..c70a3ee596 100644 --- a/src/southbridge/intel/common/smbus.h +++ b/src/southbridge/intel/common/smbus.h @@ -36,6 +36,11 @@ int do_smbus_read_byte(unsigned int smbus_base, u8 device, unsigned int address); int do_smbus_write_byte(unsigned int smbus_base, u8 device, unsigned int address, unsigned int data); +int do_smbus_read_word(unsigned int smbus_base, u8 device, + unsigned int address); +int do_smbus_write_word(unsigned int smbus_base, u8 device, + unsigned int address, unsigned int data); + int do_smbus_block_read(unsigned int smbus_base, u8 device, u8 cmd, unsigned int max_bytes, u8 *buf); int do_smbus_block_write(unsigned int smbus_base, u8 device, |