uboot/board/MAI/AmigaOneG3SE/smbus.c
<<
>>
Prefs
   1#include "memio.h"
   2#include "articiaS.h"
   3
   4#ifndef FALSE
   5#define FALSE 0
   6#endif
   7
   8#ifndef TRUE
   9#define TRUE 1
  10#endif
  11
  12
  13void sm_write_mode(void)
  14{
  15    out_byte(0xA539, 0x00);
  16    out_byte(0xA53A, 0x03);
  17}
  18
  19void sm_read_mode(void)
  20{
  21    out_byte(0xA53A, 0x02);
  22    out_byte(0xA539, 0x02);
  23}
  24
  25void sm_write_byte(uint8 writeme)
  26{
  27    int i;
  28    int level;
  29
  30    out_byte(0xA539, 0x00);
  31
  32    level = 0;
  33
  34    for (i=0; i<8; i++)
  35    {
  36        if ((writeme & 0x80) == (level<<7))
  37        {
  38            /* Bit did not change, rewrite strobe */
  39            out_byte(0xA539, level | 0x02);
  40            out_byte(0xA539, level);
  41        }
  42        else
  43        {
  44            /* Bit changed, set bit, then strobe */
  45            level = (writeme & 0x80) >> 7;
  46            out_byte(0xA539, level);
  47            out_byte(0xA539, level | 0x02);
  48            out_byte(0xA539, level);
  49        }
  50        writeme <<= 1;
  51    }
  52    out_byte(0xA539, 0x00);
  53}
  54
  55uint8 sm_read_byte(void)
  56{
  57    uint8 retme, r;
  58    int i;
  59
  60    retme = 0;
  61    for (i=0; i<8; i++)
  62    {
  63        retme <<= 1;
  64        out_byte(0xA539, 0x00);
  65        out_byte(0xA539, 0x02);
  66        r = in_byte(0xA538) & 0x01;
  67        retme |= r;
  68    }
  69
  70    return retme;
  71}
  72
  73int sm_get_ack(void)
  74{
  75    uint8 r;
  76    r = in_byte(0xA538);
  77    if ((r&0x01) == 0) return TRUE;
  78    else return FALSE;
  79}
  80
  81void sm_write_ack(void)
  82{
  83    out_byte(0xA539, 0x00);
  84    out_byte(0xA539, 0x02);
  85    out_byte(0xA539, 0x00);
  86}
  87
  88void sm_write_nack(void)
  89{
  90    out_byte(0xA539, 0x01);
  91    out_byte(0xA539, 0x03);
  92    out_byte(0xA539, 0x01);
  93}
  94
  95void sm_send_start(void)
  96{
  97    out_byte(0xA539, 0x03);
  98    out_byte(0xA539, 0x02);
  99}
 100
 101void sm_send_stop(void)
 102{
 103    out_byte(0xA539, 0x02);
 104    out_byte(0xA539, 0x03);
 105}
 106
 107int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage)
 108{
 109    /* S Addr Wr */
 110    sm_write_mode();
 111    sm_send_start();
 112    sm_write_byte((addr<<1));
 113
 114    /* [A] */
 115    sm_read_mode();
 116    if (sm_get_ack() == FALSE) return FALSE;
 117
 118    /* Comm */
 119    sm_write_mode();
 120    sm_write_byte(reg);
 121
 122    /* [A] */
 123    sm_read_mode();
 124    if (sm_get_ack() == FALSE) return FALSE;
 125
 126    /* S Addr Rd */
 127    sm_write_mode();
 128    sm_send_start();
 129    sm_write_byte((addr<<1)|1);
 130
 131    /* [A] */
 132    sm_read_mode();
 133    if (sm_get_ack() == FALSE) return FALSE;
 134
 135    /* [Data] */
 136    *storage = sm_read_byte();
 137
 138    /* NA */
 139    sm_write_mode();
 140    sm_write_nack();
 141    sm_send_stop();
 142
 143    return TRUE;
 144}
 145
 146void sm_init(void)
 147{
 148    /* Switch to PMC mode */
 149    pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
 150
 151    /* Set GPIO Base */
 152    pci_write_cfg_long(0, 0, 0x40, 0xa500);
 153
 154    /* Enable GPIO */
 155    pci_write_cfg_byte(0, 0, 0x44, 0x11);
 156
 157    /* Set both GPIO 0 and 1 as output */
 158    out_byte(0xA53A, 0x03);
 159}
 160
 161
 162void sm_term(void)
 163{
 164    /* Switch to normal mode */
 165    pci_write_cfg_byte(0, 0, REG_GROUP, 0);
 166}
 167
 168
 169int sm_get_data(uint8 *DataArray, int dimm_socket)
 170{
 171    int j;
 172
 173#if 0
 174    /* Switch to PMC mode */
 175    pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
 176
 177    /* Set GPIO Base */
 178    pci_write_cfg_long(0, 0, 0x40, 0xa500);
 179
 180    /* Enable GPIO */
 181    pci_write_cfg_byte(0, 0, 0x44, 0x11);
 182
 183    /* Set both GPIO 0 and 1 as output */
 184    out_byte(0xA53A, 0x03);
 185#endif
 186
 187    sm_init();
 188    /* Start reading the rom */
 189
 190    j = 0;
 191
 192    do
 193    {
 194        if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE)
 195        {
 196            sm_term();
 197            return FALSE;
 198        }
 199
 200        DataArray++;
 201        j++;
 202    } while (j < 128);
 203
 204    sm_term();
 205    return TRUE;
 206}
 207