aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/eeprom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/eeprom')
-rw-r--r--drivers/misc/eeprom/at25.c19
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 */