7 #define PM_DEVFN PCI_DEVFN(0x1f,3)
9 void smbus_enable(void)
12 pcibios_write_config_dword(PM_BUS, PM_DEVFN, SMB_BASE,
13 SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
15 pcibios_write_config_byte(PM_BUS, PM_DEVFN, HOSTC, HST_EN);
17 pcibios_write_config_word(PM_BUS, PM_DEVFN, PCI_COMMAND, PCI_COMMAND_IO);
19 /* Disable interrupt generation */
20 outb(0, SMBUS_IO_BASE + SMBHSTCTL);
23 static void smbus_wait_until_ready(void)
25 // Loop while HOST_BUSY
26 while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
31 static void smbus_wait_until_done(void)
35 // Loop while HOST_BUSY
37 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
39 while((byte &1) == 1);
41 // Wait for SUCCESS or error or BYTE_DONE
42 while( (byte & ~1) == 0) {
43 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
47 int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
49 unsigned char host_status_register;
52 smbus_wait_until_ready();
54 /* setup transaction */
55 /* disable interrupts */
56 outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
57 /* set to read from the specified device */
58 outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
59 /* set the command/address... */
60 outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
61 /* set up for a byte data read */
62 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
64 /* clear any lingering errors, so the transaction will run */
65 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
67 /* clear the data byte...*/
68 outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
70 /* start the command */
71 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
73 /* poll for transaction completion */
74 smbus_wait_until_done();
76 host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
78 /* read results of transaction */
79 byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
82 return host_status_register != 0x02; // return true if !SUCCESS