2 //#define SMBUS_IO_BASE 0x1000
3 #define SMBUS_IO_BASE 0x0f00
10 #define SMBHSTDAT1 0x6
12 #define SMBTRNSADD 0x9
13 #define SMBSLVDATA 0xa
14 #define SMLINK_PIN_CTL 0xe
15 #define SMBUS_PIN_CTL 0xf
17 /* Between 1-10 seconds, We should never timeout normally
18 * Longer than this is just painful when a timeout condition occurs.
20 #define SMBUS_TIMEOUT (100*1000*10)
22 static void enable_smbus(void)
25 dev = pci_locate_device(PCI_ID(0x8086, 0x24d3), 0);
26 if (dev == PCI_DEV_INVALID) {
27 die("SMBUS controller not found\r\n");
30 print_debug("SMBus controller enabled\r\n");
31 /* set smbus iobase */
32 pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
33 /* Set smbus enable */
34 pci_write_config8(dev, 0x40, 0x01);
35 /* Set smbus iospace enable */
36 pci_write_config16(dev, 0x4, 0x01);
37 /* Disable interrupt generation */
38 outb(0, SMBUS_IO_BASE + SMBHSTCTL);
39 /* clear any lingering errors, so the transaction will run */
40 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
44 static inline void smbus_delay(void)
49 static int smbus_wait_until_active(void)
52 loops = SMBUS_TIMEOUT;
56 val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
64 static int smbus_wait_until_ready(void)
67 loops = SMBUS_TIMEOUT;
71 val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
75 if(loops == (SMBUS_TIMEOUT / 2)) {
76 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
77 SMBUS_IO_BASE + SMBHSTSTAT);
83 static int smbus_wait_until_done(void)
86 loops = SMBUS_TIMEOUT;
91 val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
92 if ( (val & 1) == 0) {
95 if ((val & ~((1<<6)|(1<<0)) ) != 0 ) {
102 static int smbus_read_byte(unsigned device, unsigned address)
104 unsigned char global_control_register;
105 unsigned char global_status_register;
108 if (smbus_wait_until_ready() < 0) {
112 /* setup transaction */
113 /* disable interrupts */
114 outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
115 /* set the device I'm talking too */
116 outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
117 /* set the command/address... */
118 outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
119 /* set up for a byte data read */
120 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2<<2), SMBUS_IO_BASE + SMBHSTCTL);
122 /* clear any lingering errors, so the transaction will run */
123 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
125 /* clear the data byte...*/
126 outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
128 /* start a byte read, with interrupts disabled */
129 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
131 /* poll for it to start */
132 if (smbus_wait_until_active() < 0) {
136 /* poll for transaction completion */
137 if (smbus_wait_until_done() < 0) {
141 global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1<<6); /* Ignore the In Use Status... */
143 /* read results of transaction */
144 byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
146 if (global_status_register != 2) {
152 static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
154 if (smbus_wait_until_ready() < 0) {
159 outb(0x37,SMBUS_IO_BASE + SMBHSTSTAT);
160 /* set the device I'm talking too */
161 outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR);
164 outb(val, SMBUS_IO_BASE + SMBHSTDAT);
166 outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
168 /* start the command */
169 outb(0xa, SMBUS_IO_BASE + SMBHSTCTL);
171 /* poll for transaction completion */
172 smbus_wait_until_done();