From a14b46895c563d7b8eb9363397f10ba3f5d656ee Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Fri, 4 Aug 2006 07:50:59 +0000 Subject: final rename orgy. sorry for the inconvenience. This should fix it again git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2363 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/southbridge/intel/i82371eb/chip.h | 10 +- .../intel/i82371eb/i82371eb_early_smbus.c | 53 +++++ src/southbridge/intel/i82371eb/i82371eb_smbus.c | 43 ++++ src/southbridge/intel/i82371eb/i82371eb_smbus.h | 239 +++++++++++++++++++++ .../intel/i82371eb/i8371eb_early_smbus.c | 53 ----- src/southbridge/intel/i82371eb/i8371eb_smbus.c | 43 ---- src/southbridge/intel/i82371eb/i8371eb_smbus.h | 239 --------------------- 7 files changed, 340 insertions(+), 340 deletions(-) create mode 100644 src/southbridge/intel/i82371eb/i82371eb_early_smbus.c create mode 100644 src/southbridge/intel/i82371eb/i82371eb_smbus.c create mode 100644 src/southbridge/intel/i82371eb/i82371eb_smbus.h delete mode 100644 src/southbridge/intel/i82371eb/i8371eb_early_smbus.c delete mode 100644 src/southbridge/intel/i82371eb/i8371eb_smbus.c delete mode 100644 src/southbridge/intel/i82371eb/i8371eb_smbus.h (limited to 'src/southbridge/intel/i82371eb') diff --git a/src/southbridge/intel/i82371eb/chip.h b/src/southbridge/intel/i82371eb/chip.h index 9516f3c73b..58efa3b66f 100644 --- a/src/southbridge/intel/i82371eb/chip.h +++ b/src/southbridge/intel/i82371eb/chip.h @@ -1,13 +1,13 @@ -#ifndef I8371EB_CHIP_H -#define I8371EB_CHIP_H +#ifndef I82371EB_CHIP_H +#define I82371EB_CHIP_H -struct southbridge_intel_i8371eb_config +struct southbridge_intel_i82371eb_config { unsigned int ide0_enable : 1; unsigned int ide1_enable : 1; }; struct chip_operations; -extern struct chip_operations southbridge_intel_i8371eb_ops; +extern struct chip_operations southbridge_intel_i82371eb_ops; -#endif /* I8371EB_CHIP_H */ +#endif /* I82371EB_CHIP_H */ diff --git a/src/southbridge/intel/i82371eb/i82371eb_early_smbus.c b/src/southbridge/intel/i82371eb/i82371eb_early_smbus.c new file mode 100644 index 0000000000..49be6a49b5 --- /dev/null +++ b/src/southbridge/intel/i82371eb/i82371eb_early_smbus.c @@ -0,0 +1,53 @@ +#include "i82371eb_smbus.h" + +#define SMBUS_IO_BASE 0x0f00 + +static void enable_smbus(void) +{ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x7113), 0); + if (dev == PCI_DEV_INVALID) { + die("SMBUS controller not found\r\n"); + } + uint8_t enable; + print_spew("SMBus controller enabled\r\n"); + pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1 ); + // Enable and set SMBBus + // 0x01 Interrupt to SMI# + // (0x4<<1)|1 set interrupt to IRQ9 + pci_write_config8(dev, 0xd2, (0x4<<1)|1); + + // Enable the IO space + pci_write_config16(dev, 0x04, 1); + + /* clear any lingering errors, so the transaction will run */ + outb(0x1e, SMBUS_IO_BASE + SMBHST_STATUS); +} + + + +static int smbus_read_byte(unsigned device, unsigned address) +{ + return do_smbus_read_byte(SMBUS_IO_BASE, device, address); +} + + +// The following functions are broken. Do no use until you +// have fixed the low level code to do the right thing. +// +#if 0 +static int smbus_write_byte(unsigned device, unsigned address, unsigned char val) +{ + return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val); +} + +static int smbus_recv_byte(unsigned device) +{ + return do_smbus_recv_byte(SMBUS_IO_BASE, device); +} + +static int smbus_send_byte(unsigned device, unsigned char val) +{ + return do_smbus_send_byte(SMBUS_IO_BASE, device, val); +} +#endif diff --git a/src/southbridge/intel/i82371eb/i82371eb_smbus.c b/src/southbridge/intel/i82371eb/i82371eb_smbus.c new file mode 100644 index 0000000000..6d640b6d56 --- /dev/null +++ b/src/southbridge/intel/i82371eb/i82371eb_smbus.c @@ -0,0 +1,43 @@ +/* + * (C) 2004 Linux Networx + * (C) 2005 Bitworks +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "i82371eb.h" + + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x44, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct smbus_bus_operations lops_smbus_bus = { +}; + +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; +static struct device_operations smbus_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = scan_static_bus, + .enable = i82371eb_enable, + .ops_pci = &lops_pci, + .ops_smbus_bus = &lops_smbus_bus, +}; + +static struct pci_driver smbus_driver __pci_driver = { + .ops = &smbus_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_INTEL_440BX_SMB, +}; diff --git a/src/southbridge/intel/i82371eb/i82371eb_smbus.h b/src/southbridge/intel/i82371eb/i82371eb_smbus.h new file mode 100644 index 0000000000..e1893c5cb1 --- /dev/null +++ b/src/southbridge/intel/i82371eb/i82371eb_smbus.h @@ -0,0 +1,239 @@ +#include + +#define SMBHST_STATUS 0x0 +#define SMBHST_CTL 0x2 +#define SMBHST_CMD 0x3 +#define SMBHST_ADDR 0x4 +#define SMBHST_DAT 0x5 + +#define SMBUS_TIMEOUT (100*1000*10) +#define SMBUS_STATUS_MASK 0x1e +#define SMBUS_ERROR_FLAG (1<<2) + +static inline void smbus_delay(void) +{ + outb(0x80, 0x80); + outb(0x80, 0x80); + outb(0x80, 0x80); + outb(0x80, 0x80); + outb(0x80, 0x80); + outb(0x80, 0x80); +} + +static int smbus_wait_until_ready(unsigned smbus_io_base) +{ + unsigned long loops; + loops = SMBUS_TIMEOUT; + do { + unsigned char val; + smbus_delay(); + val = inb(smbus_io_base + SMBHST_STATUS); + if ((val & 0x1) == 0) { + break; + } +#if 0 + if(loops == (SMBUS_TIMEOUT / 2)) { + outw(inw(smbus_io_base + SMBHST_STATUS), + smbus_io_base + SMBHST_STATUS); + } +#endif + } while(--loops); + return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT; +} + +static int smbus_wait_until_done(unsigned smbus_io_base) +{ + unsigned long loops; + loops = SMBUS_TIMEOUT; + do { + unsigned short val; + smbus_delay(); + + val = inb(smbus_io_base + SMBHST_STATUS); + // Make sure the command is done + if ((val & 0x1) != 0) { + continue; + } + // Don't break out until one of the interrupt + // flags is set. + if (val & 0xfe) { + break; + } + } while(--loops); + return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT; +} + +static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device) +{ + unsigned global_status_register; + unsigned byte; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + + /* setup transaction */ + /* disable interrupts */ + outw(inw(smbus_io_base + SMBHST_CTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBHST_CTL); + /* set the device I'm talking too */ + outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR); + /* set the command/address... */ + outb(0, smbus_io_base + SMBHST_CMD); + /* set up for a send byte */ + outw((inw(smbus_io_base + SMBHST_CTL) & ~7) | (0x1), smbus_io_base + SMBHST_CTL); + + /* clear any lingering errors, so the transaction will run */ + /* Do I need to write the bits to a 1 to clear an error? */ + outw(inw(smbus_io_base + SMBHST_STATUS), smbus_io_base + SMBHST_STATUS); + + /* set the data word...*/ + outw(0, smbus_io_base + SMBHST_DAT); + + /* start the command */ + outw((inw(smbus_io_base + SMBHST_CTL) | (1 << 3)), smbus_io_base + SMBHST_CTL); + + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + + global_status_register = inw(smbus_io_base + SMBHST_STATUS); + + /* read results of transaction */ + byte = inb(smbus_io_base + SMBHST_DAT) & 0xff; + + // Check for any result other than a command completion + if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 1)) { + return SMBUS_ERROR; + } + return byte; +} + +static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned value) +{ + unsigned global_status_register; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + + /* setup transaction */ + /* disable interrupts */ + outw(inw(smbus_io_base + SMBHST_CTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBHST_CTL); + /* set the device I'm talking too */ + outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHST_ADDR); + /* set the command/address... */ + outb(0, smbus_io_base + SMBHST_CMD); + /* set up for a send byte */ + outw((inw(smbus_io_base + SMBHST_CTL) & ~7) | (0x1), smbus_io_base + SMBHST_CTL); + + /* clear any lingering errors, so the transaction will run */ + /* Do I need to write the bits to a 1 to clear an error? */ + outw(inw(smbus_io_base + SMBHST_STATUS), smbus_io_base + SMBHST_STATUS); + + /* set the data word...*/ + outw(value, smbus_io_base + SMBHST_DAT); + + /* start the command */ + outw((inw(smbus_io_base + SMBHST_CTL) | (1 << 3)), smbus_io_base + SMBHST_CTL); + + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + global_status_register = inw(smbus_io_base + SMBHST_STATUS); + + if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) { + return SMBUS_ERROR; + } + return 0; +} + + +static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address) +{ + unsigned status_register; + unsigned byte; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + + /* setup transaction */ + + /* clear any lingering errors, so the transaction will run */ + outb(0x1e, smbus_io_base + SMBHST_STATUS); + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR); + + /* set the command/address... */ + outb(address & 0xff, smbus_io_base + SMBHST_CMD); + + /* clear the data word...*/ + outb(0, smbus_io_base + SMBHST_DAT); + + /* start a byte read with interrupts disabled */ + outb( (0x02 << 2)|(1<<6), smbus_io_base + SMBHST_CTL); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + + status_register = inw(smbus_io_base + SMBHST_STATUS); + + /* read results of transaction */ + byte = inw(smbus_io_base + SMBHST_DAT) & 0xff; + + if (status_register & 0x04) { +#if 0 + print_debug("Read fail "); + print_debug_hex16(status_register); + print_debug("\r\n"); +#endif + return SMBUS_ERROR; + } + return byte; +} + +static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val) +{ + unsigned global_status_register; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + + /* setup transaction */ + /* disable interrupts */ + outw(inw(smbus_io_base + SMBHST_CTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBHST_CTL); + /* set the device I'm talking too */ + outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHST_ADDR); + outb(address & 0xFF, smbus_io_base + SMBHST_CMD); + /* set up for a byte data write */ /* FIXME */ + outw((inw(smbus_io_base + SMBHST_CTL) & ~7) | (0x2), smbus_io_base + SMBHST_CTL); + /* clear any lingering errors, so the transaction will run */ + /* Do I need to write the bits to a 1 to clear an error? */ + outw(inw(smbus_io_base + SMBHST_STATUS), smbus_io_base + SMBHST_STATUS); + + /* write the data word...*/ + outw(val, smbus_io_base + SMBHST_DAT); + + /* start the command */ + outw((inw(smbus_io_base + SMBHST_CTL) | (1 << 3)), smbus_io_base + SMBHST_CTL); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + global_status_register = inw(smbus_io_base + SMBHST_STATUS); + + if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 1)) { + return SMBUS_ERROR; + } + return 0; +} + diff --git a/src/southbridge/intel/i82371eb/i8371eb_early_smbus.c b/src/southbridge/intel/i82371eb/i8371eb_early_smbus.c deleted file mode 100644 index 4b12048016..0000000000 --- a/src/southbridge/intel/i82371eb/i8371eb_early_smbus.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "i8371eb_smbus.h" - -#define SMBUS_IO_BASE 0x0f00 - -static void enable_smbus(void) -{ - device_t dev; - dev = pci_locate_device(PCI_ID(0x8086, 0x7113), 0); - if (dev == PCI_DEV_INVALID) { - die("SMBUS controller not found\r\n"); - } - uint8_t enable; - print_spew("SMBus controller enabled\r\n"); - pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1 ); - // Enable and set SMBBus - // 0x01 Interrupt to SMI# - // (0x4<<1)|1 set interrupt to IRQ9 - pci_write_config8(dev, 0xd2, (0x4<<1)|1); - - // Enable the IO space - pci_write_config16(dev, 0x04, 1); - - /* clear any lingering errors, so the transaction will run */ - outb(0x1e, SMBUS_IO_BASE + SMBHST_STATUS); -} - - - -static int smbus_read_byte(unsigned device, unsigned address) -{ - return do_smbus_read_byte(SMBUS_IO_BASE, device, address); -} - - -// The following functions are broken. Do no use until you -// have fixed the low level code to do the right thing. -// -#if 0 -static int smbus_write_byte(unsigned device, unsigned address, unsigned char val) -{ - return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val); -} - -static int smbus_recv_byte(unsigned device) -{ - return do_smbus_recv_byte(SMBUS_IO_BASE, device); -} - -static int smbus_send_byte(unsigned device, unsigned char val) -{ - return do_smbus_send_byte(SMBUS_IO_BASE, device, val); -} -#endif diff --git a/src/southbridge/intel/i82371eb/i8371eb_smbus.c b/src/southbridge/intel/i82371eb/i8371eb_smbus.c deleted file mode 100644 index 7a09cce555..0000000000 --- a/src/southbridge/intel/i82371eb/i8371eb_smbus.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * (C) 2004 Linux Networx - * (C) 2005 Bitworks -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "i8371eb.h" - - -static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) -{ - pci_write_config32(dev, 0x44, - ((device & 0xffff) << 16) | (vendor & 0xffff)); -} - -static struct smbus_bus_operations lops_smbus_bus = { -}; - -static struct pci_operations lops_pci = { - .set_subsystem = lpci_set_subsystem, -}; -static struct device_operations smbus_ops = { - .read_resources = pci_dev_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = 0, - .scan_bus = scan_static_bus, - .enable = i8371eb_enable, - .ops_pci = &lops_pci, - .ops_smbus_bus = &lops_smbus_bus, -}; - -static struct pci_driver smbus_driver __pci_driver = { - .ops = &smbus_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_INTEL_440BX_SMB, -}; diff --git a/src/southbridge/intel/i82371eb/i8371eb_smbus.h b/src/southbridge/intel/i82371eb/i8371eb_smbus.h deleted file mode 100644 index e1893c5cb1..0000000000 --- a/src/southbridge/intel/i82371eb/i8371eb_smbus.h +++ /dev/null @@ -1,239 +0,0 @@ -#include - -#define SMBHST_STATUS 0x0 -#define SMBHST_CTL 0x2 -#define SMBHST_CMD 0x3 -#define SMBHST_ADDR 0x4 -#define SMBHST_DAT 0x5 - -#define SMBUS_TIMEOUT (100*1000*10) -#define SMBUS_STATUS_MASK 0x1e -#define SMBUS_ERROR_FLAG (1<<2) - -static inline void smbus_delay(void) -{ - outb(0x80, 0x80); - outb(0x80, 0x80); - outb(0x80, 0x80); - outb(0x80, 0x80); - outb(0x80, 0x80); - outb(0x80, 0x80); -} - -static int smbus_wait_until_ready(unsigned smbus_io_base) -{ - unsigned long loops; - loops = SMBUS_TIMEOUT; - do { - unsigned char val; - smbus_delay(); - val = inb(smbus_io_base + SMBHST_STATUS); - if ((val & 0x1) == 0) { - break; - } -#if 0 - if(loops == (SMBUS_TIMEOUT / 2)) { - outw(inw(smbus_io_base + SMBHST_STATUS), - smbus_io_base + SMBHST_STATUS); - } -#endif - } while(--loops); - return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT; -} - -static int smbus_wait_until_done(unsigned smbus_io_base) -{ - unsigned long loops; - loops = SMBUS_TIMEOUT; - do { - unsigned short val; - smbus_delay(); - - val = inb(smbus_io_base + SMBHST_STATUS); - // Make sure the command is done - if ((val & 0x1) != 0) { - continue; - } - // Don't break out until one of the interrupt - // flags is set. - if (val & 0xfe) { - break; - } - } while(--loops); - return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT; -} - -static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device) -{ - unsigned global_status_register; - unsigned byte; - - if (smbus_wait_until_ready(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_READY_TIMEOUT; - } - - /* setup transaction */ - /* disable interrupts */ - outw(inw(smbus_io_base + SMBHST_CTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBHST_CTL); - /* set the device I'm talking too */ - outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR); - /* set the command/address... */ - outb(0, smbus_io_base + SMBHST_CMD); - /* set up for a send byte */ - outw((inw(smbus_io_base + SMBHST_CTL) & ~7) | (0x1), smbus_io_base + SMBHST_CTL); - - /* clear any lingering errors, so the transaction will run */ - /* Do I need to write the bits to a 1 to clear an error? */ - outw(inw(smbus_io_base + SMBHST_STATUS), smbus_io_base + SMBHST_STATUS); - - /* set the data word...*/ - outw(0, smbus_io_base + SMBHST_DAT); - - /* start the command */ - outw((inw(smbus_io_base + SMBHST_CTL) | (1 << 3)), smbus_io_base + SMBHST_CTL); - - - /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; - } - - global_status_register = inw(smbus_io_base + SMBHST_STATUS); - - /* read results of transaction */ - byte = inb(smbus_io_base + SMBHST_DAT) & 0xff; - - // Check for any result other than a command completion - if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 1)) { - return SMBUS_ERROR; - } - return byte; -} - -static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned value) -{ - unsigned global_status_register; - - if (smbus_wait_until_ready(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_READY_TIMEOUT; - } - - /* setup transaction */ - /* disable interrupts */ - outw(inw(smbus_io_base + SMBHST_CTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBHST_CTL); - /* set the device I'm talking too */ - outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHST_ADDR); - /* set the command/address... */ - outb(0, smbus_io_base + SMBHST_CMD); - /* set up for a send byte */ - outw((inw(smbus_io_base + SMBHST_CTL) & ~7) | (0x1), smbus_io_base + SMBHST_CTL); - - /* clear any lingering errors, so the transaction will run */ - /* Do I need to write the bits to a 1 to clear an error? */ - outw(inw(smbus_io_base + SMBHST_STATUS), smbus_io_base + SMBHST_STATUS); - - /* set the data word...*/ - outw(value, smbus_io_base + SMBHST_DAT); - - /* start the command */ - outw((inw(smbus_io_base + SMBHST_CTL) | (1 << 3)), smbus_io_base + SMBHST_CTL); - - - /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; - } - global_status_register = inw(smbus_io_base + SMBHST_STATUS); - - if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) { - return SMBUS_ERROR; - } - return 0; -} - - -static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address) -{ - unsigned status_register; - unsigned byte; - - if (smbus_wait_until_ready(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_READY_TIMEOUT; - } - - /* setup transaction */ - - /* clear any lingering errors, so the transaction will run */ - outb(0x1e, smbus_io_base + SMBHST_STATUS); - - /* set the device I'm talking too */ - outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR); - - /* set the command/address... */ - outb(address & 0xff, smbus_io_base + SMBHST_CMD); - - /* clear the data word...*/ - outb(0, smbus_io_base + SMBHST_DAT); - - /* start a byte read with interrupts disabled */ - outb( (0x02 << 2)|(1<<6), smbus_io_base + SMBHST_CTL); - - /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; - } - - status_register = inw(smbus_io_base + SMBHST_STATUS); - - /* read results of transaction */ - byte = inw(smbus_io_base + SMBHST_DAT) & 0xff; - - if (status_register & 0x04) { -#if 0 - print_debug("Read fail "); - print_debug_hex16(status_register); - print_debug("\r\n"); -#endif - return SMBUS_ERROR; - } - return byte; -} - -static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val) -{ - unsigned global_status_register; - - if (smbus_wait_until_ready(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_READY_TIMEOUT; - } - - /* setup transaction */ - /* disable interrupts */ - outw(inw(smbus_io_base + SMBHST_CTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBHST_CTL); - /* set the device I'm talking too */ - outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHST_ADDR); - outb(address & 0xFF, smbus_io_base + SMBHST_CMD); - /* set up for a byte data write */ /* FIXME */ - outw((inw(smbus_io_base + SMBHST_CTL) & ~7) | (0x2), smbus_io_base + SMBHST_CTL); - /* clear any lingering errors, so the transaction will run */ - /* Do I need to write the bits to a 1 to clear an error? */ - outw(inw(smbus_io_base + SMBHST_STATUS), smbus_io_base + SMBHST_STATUS); - - /* write the data word...*/ - outw(val, smbus_io_base + SMBHST_DAT); - - /* start the command */ - outw((inw(smbus_io_base + SMBHST_CTL) | (1 << 3)), smbus_io_base + SMBHST_CTL); - - /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) { - return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; - } - global_status_register = inw(smbus_io_base + SMBHST_STATUS); - - if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 1)) { - return SMBUS_ERROR; - } - return 0; -} - -- cgit v1.2.3