0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/delay.h>
0014
0015 #include "solo6x10.h"
0016
0017
0018 #define EE_SHIFT_CLK 0x04
0019 #define EE_CS 0x08
0020 #define EE_DATA_WRITE 0x02
0021 #define EE_DATA_READ 0x01
0022 #define EE_ENB (0x80 | EE_CS)
0023
0024 #define eeprom_delay() udelay(100)
0025 #if 0
0026 #define eeprom_delay() solo_reg_read(solo_dev, SOLO_EEPROM_CTRL)
0027 #define eeprom_delay() ({ \
0028 int i, ret; \
0029 udelay(100); \
0030 for (i = ret = 0; i < 1000 && !ret; i++) \
0031 ret = solo_eeprom_reg_read(solo_dev); \
0032 })
0033 #endif
0034 #define ADDR_LEN 6
0035
0036
0037 #define EE_EWEN_CMD 4
0038 #define EE_EWDS_CMD 4
0039 #define EE_WRITE_CMD 5
0040 #define EE_READ_CMD 6
0041 #define EE_ERASE_CMD 7
0042
0043 static unsigned int solo_eeprom_reg_read(struct solo_dev *solo_dev)
0044 {
0045 return solo_reg_read(solo_dev, SOLO_EEPROM_CTRL) & EE_DATA_READ;
0046 }
0047
0048 static void solo_eeprom_reg_write(struct solo_dev *solo_dev, u32 data)
0049 {
0050 solo_reg_write(solo_dev, SOLO_EEPROM_CTRL, data);
0051 eeprom_delay();
0052 }
0053
0054 static void solo_eeprom_cmd(struct solo_dev *solo_dev, int cmd)
0055 {
0056 int i;
0057
0058 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ACCESS_EN);
0059 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0060
0061 for (i = 4 + ADDR_LEN; i >= 0; i--) {
0062 int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0;
0063
0064 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE | dataval);
0065 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
0066 EE_SHIFT_CLK | dataval);
0067 }
0068
0069 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0070 }
0071
0072 unsigned int solo_eeprom_ewen(struct solo_dev *solo_dev, int w_en)
0073 {
0074 int ewen_cmd = (w_en ? 0x3f : 0) | (EE_EWEN_CMD << ADDR_LEN);
0075 unsigned int retval = 0;
0076 int i;
0077
0078 solo_eeprom_cmd(solo_dev, ewen_cmd);
0079
0080 for (i = 0; i < 16; i++) {
0081 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
0082 EE_SHIFT_CLK);
0083 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0084 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0085 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0086 }
0087
0088 solo_eeprom_reg_write(solo_dev, ~EE_CS);
0089 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0090
0091 return retval;
0092 }
0093
0094 __be16 solo_eeprom_read(struct solo_dev *solo_dev, int loc)
0095 {
0096 int read_cmd = loc | (EE_READ_CMD << ADDR_LEN);
0097 u16 retval = 0;
0098 int i;
0099
0100 solo_eeprom_cmd(solo_dev, read_cmd);
0101
0102 for (i = 0; i < 16; i++) {
0103 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
0104 EE_SHIFT_CLK);
0105 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0106 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0107 }
0108
0109 solo_eeprom_reg_write(solo_dev, ~EE_CS);
0110
0111 return (__force __be16)retval;
0112 }
0113
0114 int solo_eeprom_write(struct solo_dev *solo_dev, int loc,
0115 __be16 data)
0116 {
0117 int write_cmd = loc | (EE_WRITE_CMD << ADDR_LEN);
0118 unsigned int retval;
0119 int i;
0120
0121 solo_eeprom_cmd(solo_dev, write_cmd);
0122
0123 for (i = 15; i >= 0; i--) {
0124 unsigned int dataval = ((__force unsigned)data >> i) & 1;
0125
0126 solo_eeprom_reg_write(solo_dev, EE_ENB);
0127 solo_eeprom_reg_write(solo_dev,
0128 EE_ENB | (dataval << 1) | EE_SHIFT_CLK);
0129 }
0130
0131 solo_eeprom_reg_write(solo_dev, EE_ENB);
0132 solo_eeprom_reg_write(solo_dev, ~EE_CS);
0133 solo_eeprom_reg_write(solo_dev, EE_ENB);
0134
0135 for (i = retval = 0; i < 10000 && !retval; i++)
0136 retval = solo_eeprom_reg_read(solo_dev);
0137
0138 solo_eeprom_reg_write(solo_dev, ~EE_CS);
0139
0140 return !retval;
0141 }