diff options
Diffstat (limited to 'board/MAI/AmigaOneG3SE/smbus.c')
-rw-r--r-- | board/MAI/AmigaOneG3SE/smbus.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/board/MAI/AmigaOneG3SE/smbus.c b/board/MAI/AmigaOneG3SE/smbus.c new file mode 100644 index 0000000..616005e --- /dev/null +++ b/board/MAI/AmigaOneG3SE/smbus.c @@ -0,0 +1,206 @@ +#include "memio.h" +#include "articiaS.h" + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + + +void sm_write_mode(void) +{ + out_byte(0xA539, 0x00); + out_byte(0xA53A, 0x03); +} + +void sm_read_mode(void) +{ + out_byte(0xA53A, 0x02); + out_byte(0xA539, 0x02); +} + +void sm_write_byte(uint8 writeme) +{ + int i; + int level; + + out_byte(0xA539, 0x00); + + level = 0; + + for (i=0; i<8; i++) + { + if ((writeme & 0x80) == (level<<7)) + { + /* Bit did not change, rewrite strobe */ + out_byte(0xA539, level | 0x02); + out_byte(0xA539, level); + } + else + { + /* Bit changed, set bit, then strobe */ + level = (writeme & 0x80) >> 7; + out_byte(0xA539, level); + out_byte(0xA539, level | 0x02); + out_byte(0xA539, level); + } + writeme <<= 1; + } + out_byte(0xA539, 0x00); +} + +uint8 sm_read_byte(void) +{ + uint8 retme, r; + int i; + + retme = 0; + for (i=0; i<8; i++) + { + retme <<= 1; + out_byte(0xA539, 0x00); + out_byte(0xA539, 0x02); + r = in_byte(0xA538) & 0x01; + retme |= r; + } + + return retme; +} + +int sm_get_ack(void) +{ + uint8 r; + r = in_byte(0xA538); + if ((r&0x01) == 0) return TRUE; + else return FALSE; +} + +void sm_write_ack(void) +{ + out_byte(0xA539, 0x00); + out_byte(0xA539, 0x02); + out_byte(0xA539, 0x00); +} + +void sm_write_nack(void) +{ + out_byte(0xA539, 0x01); + out_byte(0xA539, 0x03); + out_byte(0xA539, 0x01); +} + +void sm_send_start(void) +{ + out_byte(0xA539, 0x03); + out_byte(0xA539, 0x02); +} + +void sm_send_stop(void) +{ + out_byte(0xA539, 0x02); + out_byte(0xA539, 0x03); +} + +int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage) +{ + // S Addr Wr + sm_write_mode(); + sm_send_start(); + sm_write_byte((addr<<1)); + + // [A] + sm_read_mode(); + if (sm_get_ack() == FALSE) return FALSE; + + // Comm + sm_write_mode(); + sm_write_byte(reg); + + // [A] + sm_read_mode(); + if (sm_get_ack() == FALSE) return FALSE; + + // S Addr Rd + sm_write_mode(); + sm_send_start(); + sm_write_byte((addr<<1)|1); + + // [A] + sm_read_mode(); + if (sm_get_ack() == FALSE) return FALSE; + + // [Data] + *storage = sm_read_byte(); + + // NA + sm_write_mode(); + sm_write_nack(); + sm_send_stop(); + + return TRUE; +} + +void sm_init(void) +{ + /* Switch to PMC mode */ + pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER)); + + /* Set GPIO Base */ + pci_write_cfg_long(0, 0, 0x40, 0xa500); + + /* Enable GPIO */ + pci_write_cfg_byte(0, 0, 0x44, 0x11); + + /* Set both GPIO 0 and 1 as output */ + out_byte(0xA53A, 0x03); +} + + +void sm_term(void) +{ + /* Switch to normal mode */ + pci_write_cfg_byte(0, 0, REG_GROUP, 0); +} + + +int sm_get_data(uint8 *DataArray, int dimm_socket) +{ + int j; + +#if 0 + /* Switch to PMC mode */ + pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER)); + + /* Set GPIO Base */ + pci_write_cfg_long(0, 0, 0x40, 0xa500); + + /* Enable GPIO */ + pci_write_cfg_byte(0, 0, 0x44, 0x11); + + /* Set both GPIO 0 and 1 as output */ + out_byte(0xA53A, 0x03); +#endif + + sm_init(); + /* Start reading the rom */ + + j = 0; + + do + { + if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE) + { + sm_term(); + return FALSE; + } + + DataArray++; + j++; + } while (j < 128); + + sm_term(); + return TRUE; +} |