0001
0002
0003
0004
0005
0006
0007 #include <linux/export.h>
0008
0009 #include <asm/sgi/hpc3.h>
0010 #include <asm/sgi/ip22.h>
0011
0012
0013 #define EEPROM_READ 0xc000
0014 #define EEPROM_WEN 0x9800
0015 #define EEPROM_WRITE 0xa000
0016 #define EEPROM_WRALL 0x8800
0017 #define EEPROM_WDS 0x8000
0018 #define EEPROM_PRREAD 0xc000
0019 #define EEPROM_PREN 0x9800
0020 #define EEPROM_PRCLEAR 0xffff
0021 #define EEPROM_PRWRITE 0xa000
0022 #define EEPROM_PRDS 0x8000
0023
0024 #define EEPROM_EPROT 0x01
0025 #define EEPROM_CSEL 0x02
0026 #define EEPROM_ECLK 0x04
0027 #define EEPROM_DATO 0x08
0028 #define EEPROM_DATI 0x10
0029
0030
0031 #define delay() ({ \
0032 int x; \
0033 for (x=0; x<100000; x++) __asm__ __volatile__(""); })
0034
0035 #define eeprom_cs_on(ptr) ({ \
0036 __raw_writel(__raw_readl(ptr) & ~EEPROM_DATO, ptr); \
0037 __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \
0038 __raw_writel(__raw_readl(ptr) & ~EEPROM_EPROT, ptr); \
0039 delay(); \
0040 __raw_writel(__raw_readl(ptr) | EEPROM_CSEL, ptr); \
0041 __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); })
0042
0043
0044 #define eeprom_cs_off(ptr) ({ \
0045 __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \
0046 __raw_writel(__raw_readl(ptr) & ~EEPROM_CSEL, ptr); \
0047 __raw_writel(__raw_readl(ptr) | EEPROM_EPROT, ptr); \
0048 __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); })
0049
0050 #define BITS_IN_COMMAND 11
0051
0052
0053
0054
0055
0056 static inline void eeprom_cmd(unsigned int *ctrl, unsigned cmd, unsigned reg)
0057 {
0058 unsigned short ser_cmd;
0059 int i;
0060
0061 ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND));
0062 for (i = 0; i < BITS_IN_COMMAND; i++) {
0063 if (ser_cmd & (1<<15))
0064 __raw_writel(__raw_readl(ctrl) | EEPROM_DATO, ctrl);
0065 else
0066 __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl);
0067 __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl);
0068 delay();
0069 __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl);
0070 delay();
0071 ser_cmd <<= 1;
0072 }
0073
0074 __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl);
0075 }
0076
0077 unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg)
0078 {
0079 unsigned short res = 0;
0080 int i;
0081
0082 __raw_writel(__raw_readl(ctrl) & ~EEPROM_EPROT, ctrl);
0083 eeprom_cs_on(ctrl);
0084 eeprom_cmd(ctrl, EEPROM_READ, reg);
0085
0086
0087 for (i = 0; i < 16; i++) {
0088 __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl);
0089 delay();
0090 __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl);
0091 delay();
0092 res <<= 1;
0093 if (__raw_readl(ctrl) & EEPROM_DATI)
0094 res |= 1;
0095 }
0096
0097 eeprom_cs_off(ctrl);
0098
0099 return res;
0100 }
0101
0102 EXPORT_SYMBOL(ip22_eeprom_read);
0103
0104
0105
0106
0107 unsigned short ip22_nvram_read(int reg)
0108 {
0109 if (ip22_is_fullhouse())
0110
0111
0112 return ip22_eeprom_read(&hpc3c0->eeprom, reg);
0113 else {
0114 unsigned short tmp;
0115
0116 reg <<= 1;
0117 tmp = hpc3c0->bbram[reg++] & 0xff;
0118 return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff);
0119 }
0120 }
0121
0122 EXPORT_SYMBOL(ip22_nvram_read);