1 #include "esb6300_smbus.h"
3 #define SMBUS_IO_BASE 0x0f00
5 static void enable_smbus(void)
7 device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
9 print_spew("SMBus controller enabled\n");
10 pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
11 pci_write_config8(dev, 0x40, 1);
12 pci_write_config8(dev, 0x4, 1);
14 pci_write_config8(dev, 0x11, 4);
16 /* Disable interrupt generation */
17 outb(0, SMBUS_IO_BASE + SMBHSTCTL);
20 static int smbus_read_byte(unsigned device, unsigned address)
22 return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
25 static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
27 if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
33 static int smbus_write_block(unsigned device, unsigned length, unsigned cmd,
34 unsigned data1, unsigned data2)
36 unsigned char global_control_register;
37 unsigned char global_status_register;
42 /* chear the PM timeout flags, SECOND_TO_STS */
43 outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
45 if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
49 /* setup transaction */
50 /* Obtain ownership */
51 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
52 for(stat=0;(stat&0x40)==0;) {
53 stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
55 /* clear the done bit */
56 outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
57 /* disable interrupts */
58 outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
60 /* set the device I'm talking too */
61 outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
63 /* set the command address */
64 outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
66 /* set the block length */
67 outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
69 /* try sending out the first byte of data here */
70 byte=(data1>>(0))&0x0ff;
71 outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
72 /* issue a block write command */
73 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40,
74 SMBUS_IO_BASE + SMBHSTCTL);
76 for(i=0;i<length;i++) {
78 /* poll for transaction completion */
79 if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
83 /* load the next byte */
85 byte=(data2>>(i%4))&0x0ff;
87 byte=(data1>>(i))&0x0ff;
88 outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
90 /* clear the done bit */
91 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
92 SMBUS_IO_BASE + SMBHSTSTAT);
95 print_debug("SMBUS Block complete\n");