int do_smbus_recv_byte(u32 smbus_io_base, u32 device) { u8 byte; if (smbus_wait_until_ready(smbus_io_base) < 0) { printk(BIOS_DEBUG, "SB800 - Smbus.c - do_smbus_recv_byte - smbus not ready.\n"); return -2; /* not ready */ } printk(BIOS_DEBUG, "SB800 - Smbus.c - do_smbus_recv_byte - Start.\n"); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR); byte = inb(smbus_io_base + SMBHSTCTRL); byte &= 0xe3; /* Clear [4:2] */ byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */ outb(byte, smbus_io_base + SMBHSTCTRL); /* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) { return -3; /* timeout or error */ } /* read results of transaction */ byte = inb(smbus_io_base + SMBHSTCMD); printk(BIOS_DEBUG, "SB800 - Smbus.c - do_smbus_recv_byte - End.\n"); return byte; }
static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) { if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { return; } print_debug("Unimplemented smbus_write_byte() called.\n"); #if 0 /* setup transaction */ /* disable interrupts */ outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), SMBUS_IO_BASE + SMBGCTL); /* set the device I'm talking too */ outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR); outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); /* set up for a byte data write */ /* FIXME */ outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x1), SMBUS_IO_BASE + SMBGCTL); /* 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 + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS); /* clear the data word...*/ outw(val, SMBUS_IO_BASE + SMBHSTDAT); /* start the command */ outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL); /* poll for transaction completion */ smbus_wait_until_done(SMBUS_IO_BASE); #endif return; }
int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val) { u8 byte; if (smbus_wait_until_ready(smbus_io_base) < 0) { printk(BIOS_DEBUG, "SB800 - Smbus.c - do_smbus_write_byte - smbus not ready.\n"); return -2; /* not ready */ } printk(BIOS_DEBUG, "SB800 - Smbus.c - do_smbus_write_byte - Start.\n"); /* set the command/address... */ outb(address & 0xff, smbus_io_base + SMBHSTCMD); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR); /* output value */ outb(val, smbus_io_base + SMBHSTDAT0); byte = inb(smbus_io_base + SMBHSTCTRL); byte &= 0xe3; /* Clear [4:2] */ byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */ outb(byte, smbus_io_base + SMBHSTCTRL); /* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) { return -3; /* timeout or error */ } printk(BIOS_DEBUG, "SB800 - Smbus.c - do_smbus_write_byte - End.\n"); return 0; }
int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address) { u8 byte; if (smbus_wait_until_ready(smbus_io_base) < 0) { return -2; /* not ready */ } /* set the command/address... */ outb(address & 0xff, smbus_io_base + SMBHSTCMD); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR); byte = inb(smbus_io_base + SMBHSTCTRL); byte &= 0xe3; /* Clear [4:2] */ byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */ outb(byte, smbus_io_base + SMBHSTCTRL); /* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) { return -3; /* timeout or error */ } /* read results of transaction */ byte = inb(smbus_io_base + SMBHSTDAT0); return byte; }
int do_smbus_write_byte(u32 mmio, u8 device, u8 address, u8 val) { u8 byte; if (smbus_wait_until_ready(mmio) < 0) return -2; /* not ready */ /* set the command/address... */ smbus_write8(mmio, SMBHSTCMD, address & 0xff); /* set the device I'm talking to */ smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); /* output value */ smbus_write8(mmio, SMBHSTDAT0, val); byte = smbus_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ smbus_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ return 0; }
int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val) { u8 byte; if (smbus_wait_until_ready(smbus_io_base) < 0) { return -2; /* not ready */ } /* set the command... */ outb(val, smbus_io_base + SMBHSTCMD); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR); byte = inb(smbus_io_base + SMBHSTCTRL); byte &= 0xe3; /* Clear [4:2] */ byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */ outb(byte, smbus_io_base + SMBHSTCTRL); /* poll for transaction completion */ if (smbus_wait_until_done(smbus_io_base) < 0) { return -3; /* timeout or error */ } return 0; }
static int smbus_read_byte(unsigned device, unsigned address) { unsigned char global_status_register; unsigned char byte; /* print_err("smbus_read_byte\n"); */ if (smbus_wait_until_ready() < 0) { print_err("SMBUS not ready (-2)\n"); return -2; } /* setup transaction */ /* disable interrupts */ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD); /* set the command/address... */ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); /* set up for a byte data read */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL); /* clear any lingering errors, so the transaction will run */ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); /* clear the data byte... */ outb(0, SMBUS_IO_BASE + SMBHSTDAT0); /* start a byte read, with interrupts disabled */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL); /* poll for it to start */ if (smbus_wait_until_active() < 0) { print_err("SMBUS not active (-4)\n"); return -4; } /* poll for transaction completion */ if (smbus_wait_until_done() < 0) { print_err("SMBUS not completed (-3)\n"); return -3; } global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1 << 6); /* Ignore the In Use Status... */ /* read results of transaction */ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); if (global_status_register != 2) { //print_spew("%s: no device (%02x, %02x)\n", __func__, device, address); return -1; } //print_debug("%s: %02x@%02x = %02x\n", __func__, device, address, byte); return byte; }
/* * Copied from intel/i82801dbm early smbus code - suggested by rgm. * Modifications/check against i2c-viapro driver code from linux-2.4.22 * and VT8231 Reference Docs - mw. */ static int smbus_read_byte(unsigned device, unsigned address) { unsigned char global_status_register; unsigned char byte; if (smbus_wait_until_ready() < 0) { outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); if (smbus_wait_until_ready() < 0) { return -2; } } /* setup transaction */ /* disable interrupts */ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD); /* set the command/address... */ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); /* set up for a byte data read */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL); /* clear any lingering errors, so the transaction will run */ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); /* clear the data byte... */ outb(0, SMBUS_IO_BASE + SMBHSTDAT0); /* start a byte read, with interrupts disabled */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL); /* poll for it to start */ if (smbus_wait_until_active() < 0) { return -4; } /* poll for transaction completion */ if (smbus_wait_until_done() < 0) { return -3; } /* Ignore the Host Busy & Command Complete ? */ global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~((1 << 1) | (1 << 0)); /* read results of transaction */ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); if (global_status_register != 0) { return -1; } return byte; }
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) { printk(BIOS_ERR, "SMBUS transaction timeout\n"); 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)) { printk(BIOS_ERR, "SMBUS transaction error\n"); return SMBUS_ERROR; } return 0; }
int smbus_read_byte(unsigned device, unsigned address, unsigned char *result) { unsigned char host_status_register; unsigned char byte; reset(); smbus_wait_until_ready(); /* setup transaction */ /* disable interrupts */ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD); /* set the command/address... */ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); /* set up for a byte data read */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL); /* clear any lingering errors, so the transaction will run */ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); /* clear the data byte...*/ outb(0, SMBUS_IO_BASE + SMBHSTDAT0); /* start the command */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL); /* poll for transaction completion */ smbus_wait_until_done(); host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT); /* Ignore the In Use Status... */ host_status_register &= ~(1 << 6); /* read results of transaction */ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); smbus_print_error(byte); *result = byte; return host_status_register != 0x02; }
static int smbus_block_write(u32 base, u8 dev, u8 *buffer, int offset, int len) { int i; debug("%s (%d): dev=0x%x offs=0x%x len=0x%x\n", __func__, __LINE__, dev, offset, len); if (smbus_wait_until_ready(base) < 0) return -ETIMEDOUT; /* Setup transaction */ /* Set the device I'm talking too */ outb(((dev & 0x7f) << 1) & ~0x01, base + SMBXMITADD); /* Set the command/address... */ outb(offset, base + SMBHSTCMD); /* Set up for a block write */ outb((inb(base + SMBHSTCTL) & (~(0x7) << 2)) | (0x5 << 2), (base + SMBHSTCTL)); /* Clear any lingering errors, so the transaction will run */ outb(inb(base + SMBHSTSTAT), base + SMBHSTSTAT); /* Write count in DAT0 register */ outb(len, base + SMBHSTDAT0); /* Write data bytes... */ for (i = 0; i < len; i++) outb(*buffer++, base + SMBBLKDAT); /* Start the command */ outb((inb(base + SMBHSTCTL) | SMBHSTCNT_START), base + SMBHSTCTL); /* Poll for transaction completion */ if (smbus_wait_until_done(base) < 0) { printf("SMBUS write transaction timeout (dev=0x%x)\n", dev); return -ETIMEDOUT; } /* Return results of transaction */ if (!(inb(base + SMBHSTSTAT) & SMBHSTSTS_INTR)) return -EIO; return 0; }
/** \brief generic smbus helper function to read & write to the smbus * * \details Configures the SMBus for the transaction, sets up the address * and data bytes, starts the command, waits for the command to * finish, and returns data if the command is a read. * * \param device The 8-bit device address, with the read / write bit set-up. * * \param addr_dat For full reads/writes, this contains the address within * the device of the byte being read/written. For quick writes, * this contains the data to write. * * \param data For full writes, this contains the Data to write to the * device. For all other transactions, this is ignored. * * \param command Contains the command for a full read/write (0x48) or the * command for a quick read/write (0x44) * * \return Data read from the device, or -1 if there was an error */ static s16 smbus_rw_byte(u8 device, u8 addr_dat, u8 data, u8 command) { u8 global_status_register; if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) return SMBUS_WAIT_UNTIL_READY_TIMEOUT; /*** Set up transaction ***/ /* Disable interrupts */ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); /* Set the device being talked to using supplied device address*/ outb(device, SMBUS_IO_BASE + SMBXMITADD); /* Set the address and data byte */ outb(addr_dat, SMBUS_IO_BASE + SMBHSTCMD); outb(data, SMBUS_IO_BASE + SMBHSTDAT0); /* Clear any lingering errors, so the transaction will run */ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); /* Start the command */ outb(command, SMBUS_IO_BASE + SMBHSTCTL); /* Poll for transaction completion */ if (smbus_wait_until_done(SMBUS_IO_BASE) < 0) return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT); /* Ignore the "In Use" status... */ global_status_register &= ~(HSTSTS_SMBALERT_STS | HSTSTS_INUSE_STS); /* Read results - INTR gets set when a command is completed successfully */ data = inb(SMBUS_IO_BASE + SMBHSTDAT0); if (global_status_register != HSTSTS_INTR) return SMBUS_ERROR; return data; }
int smbus_read_byte(unsigned device, unsigned address) { unsigned char host_status_register; int result; smbus_wait_until_ready(); /* setup transaction */ /* disable interrupts */ outb(inb(SMBUS_IO_HSTCTL) & (~1), SMBUS_IO_HSTCTL); /* set the device I'm talking too */ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_HSTADD); /* set the command/address... */ outb(address & 0xFF, SMBUS_IO_HSTCMD); /* set up for a byte data read */ outb((inb(SMBUS_IO_HSTCTL) & 0xE3) | 8, SMBUS_IO_HSTCTL); /* clear any lingering errors, so the transaction will run */ outb(inb(SMBUS_IO_HSTSTAT), SMBUS_IO_HSTSTAT); /* clear the data byte...*/ outb(0, SMBUS_IO_HSTDAT0); /* start the command */ outb((inb(SMBUS_IO_HSTCTL) | 0x40), SMBUS_IO_HSTCTL); /* poll for transaction completion */ smbus_wait_until_done(); host_status_register = inb(SMBUS_IO_HSTSTAT); /* read results of transaction */ result = inb(SMBUS_IO_HSTDAT0); if (host_status_register != 0x02) { result = -1; } return result; }
int smbus_read_byte(unsigned device, unsigned address, unsigned char *result) { unsigned char host_status_register; unsigned char byte; smbus_wait_until_ready(); /* setup transaction */ /* disable interrupts */ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); /* set to read from the specified device */ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD); /* set the command/address... */ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); /* set up for a byte data read */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL); /* clear any lingering errors, so the transaction will run */ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); /* clear the data byte...*/ outb(0, SMBUS_IO_BASE + SMBHSTDAT0); /* start the command */ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL); /* poll for transaction completion */ smbus_wait_until_done(); host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT); /* read results of transaction */ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); *result = byte; return host_status_register != 0x02; // return true if !SUCCESS }
int do_smbus_recv_byte(u32 mmio, u8 device) { u8 byte; if (smbus_wait_until_ready(mmio) < 0) return -2; /* not ready */ /* set the device I'm talking to */ smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); byte = smbus_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ smbus_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ /* read results of transaction */ byte = smbus_read8(mmio, SMBHSTDAT0); return byte; }
static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) { if (smbus_wait_until_ready() < 0) { return; } /* by LYH */ outb(0x37, SMBUS_IO_BASE + SMBHSTSTAT); /* set the device I'm talking too */ outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR); /* data to send */ outb(val, SMBUS_IO_BASE + SMBHSTDAT); outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); /* start the command */ outb(0xa, SMBUS_IO_BASE + SMBHSTCTL); /* poll for transaction completion */ smbus_wait_until_done(); return; }
static int smbus_block_read(u32 base, u8 dev, u8 *buffer, int offset, int len) { u8 buf_temp[32]; int count; int i; debug("%s (%d): dev=0x%x offs=0x%x len=0x%x\n", __func__, __LINE__, dev, offset, len); if (smbus_wait_until_ready(base) < 0) return -ETIMEDOUT; /* Setup transaction */ /* Reset the data buffer index */ inb(base + SMBHSTCTL); /* Set the device I'm talking too */ outb(((dev & 0x7f) << 1) | 1, base + SMBXMITADD); /* Set the command/address... */ outb(offset & 0xff, base + SMBHSTCMD); /* Set up for a block read */ outb((inb(base + SMBHSTCTL) & (~(0x7) << 2)) | (0x5 << 2), (base + SMBHSTCTL)); /* Clear any lingering errors, so the transaction will run */ outb(inb(base + SMBHSTSTAT), base + SMBHSTSTAT); /* Start the command */ outb((inb(base + SMBHSTCTL) | SMBHSTCNT_START), base + SMBHSTCTL); /* Poll for transaction completion */ if (smbus_wait_until_done(base) < 0) { printf("SMBUS read transaction timeout (dev=0x%x)\n", dev); return -ETIMEDOUT; } count = inb(base + SMBHSTDAT0); debug("%s (%d): count=%d (len=%d)\n", __func__, __LINE__, count, len); if (count == 0) { debug("ERROR: len=0 on read\n"); return -EIO; } if (count < len) { debug("ERROR: too few bytes read\n"); return -EIO; } if (count > 32) { debug("ERROR: count=%d too high\n", count); return -EIO; } /* Read all available bytes from buffer */ for (i = 0; i < count; i++) buf_temp[i] = inb(base + SMBBLKDAT); memcpy(buffer, buf_temp, len); /* Return results of transaction */ if (!(inb(base + SMBHSTSTAT) & SMBHSTSTS_INTR)) return -EIO; return 0; }