diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/eeprom/at25.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 01ab3c9b4cf7..0842c2994ee2 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c | |||
@@ -50,6 +50,7 @@ struct at25_data { | |||
50 | #define AT25_SR_BP1 0x08 | 50 | #define AT25_SR_BP1 0x08 |
51 | #define AT25_SR_WPEN 0x80 /* writeprotect enable */ | 51 | #define AT25_SR_WPEN 0x80 /* writeprotect enable */ |
52 | 52 | ||
53 | #define AT25_INSTR_BIT3 0x08 /* Additional address bit in instr */ | ||
53 | 54 | ||
54 | #define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */ | 55 | #define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */ |
55 | 56 | ||
@@ -75,6 +76,7 @@ at25_ee_read( | |||
75 | ssize_t status; | 76 | ssize_t status; |
76 | struct spi_transfer t[2]; | 77 | struct spi_transfer t[2]; |
77 | struct spi_message m; | 78 | struct spi_message m; |
79 | u8 instr; | ||
78 | 80 | ||
79 | if (unlikely(offset >= at25->bin.size)) | 81 | if (unlikely(offset >= at25->bin.size)) |
80 | return 0; | 82 | return 0; |
@@ -84,7 +86,12 @@ at25_ee_read( | |||
84 | return count; | 86 | return count; |
85 | 87 | ||
86 | cp = command; | 88 | cp = command; |
87 | *cp++ = AT25_READ; | 89 | |
90 | instr = AT25_READ; | ||
91 | if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) | ||
92 | if (offset >= (1U << (at25->addrlen * 8))) | ||
93 | instr |= AT25_INSTR_BIT3; | ||
94 | *cp++ = instr; | ||
88 | 95 | ||
89 | /* 8/16/24-bit address is written MSB first */ | 96 | /* 8/16/24-bit address is written MSB first */ |
90 | switch (at25->addrlen) { | 97 | switch (at25->addrlen) { |
@@ -167,14 +174,14 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, | |||
167 | /* For write, rollover is within the page ... so we write at | 174 | /* For write, rollover is within the page ... so we write at |
168 | * most one page, then manually roll over to the next page. | 175 | * most one page, then manually roll over to the next page. |
169 | */ | 176 | */ |
170 | bounce[0] = AT25_WRITE; | ||
171 | mutex_lock(&at25->lock); | 177 | mutex_lock(&at25->lock); |
172 | do { | 178 | do { |
173 | unsigned long timeout, retries; | 179 | unsigned long timeout, retries; |
174 | unsigned segment; | 180 | unsigned segment; |
175 | unsigned offset = (unsigned) off; | 181 | unsigned offset = (unsigned) off; |
176 | u8 *cp = bounce + 1; | 182 | u8 *cp = bounce; |
177 | int sr; | 183 | int sr; |
184 | u8 instr; | ||
178 | 185 | ||
179 | *cp = AT25_WREN; | 186 | *cp = AT25_WREN; |
180 | status = spi_write(at25->spi, cp, 1); | 187 | status = spi_write(at25->spi, cp, 1); |
@@ -184,6 +191,12 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, | |||
184 | break; | 191 | break; |
185 | } | 192 | } |
186 | 193 | ||
194 | instr = AT25_WRITE; | ||
195 | if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) | ||
196 | if (offset >= (1U << (at25->addrlen * 8))) | ||
197 | instr |= AT25_INSTR_BIT3; | ||
198 | *cp++ = instr; | ||
199 | |||
187 | /* 8/16/24-bit address is written MSB first */ | 200 | /* 8/16/24-bit address is written MSB first */ |
188 | switch (at25->addrlen) { | 201 | switch (at25->addrlen) { |
189 | default: /* case 3 */ | 202 | default: /* case 3 */ |