Merge branch 'master' of /home/stefan/git/u-boot/u-boot
[platform/kernel/u-boot.git] / drivers / mtd / at45.c
1 /* Driver for ATMEL DataFlash support
2  * Author : Hamid Ikdoumi (Atmel)
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307 USA
18  *
19  */
20
21 #include <config.h>
22 #include <common.h>
23
24 #ifdef CONFIG_HAS_DATAFLASH
25 #include <dataflash.h>
26
27 /*
28  * spi.c API
29  */
30 extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc);
31 extern void AT91F_SpiEnable(int cs);
32
33 #define AT91C_TIMEOUT_WRDY                      200000
34
35 /*----------------------------------------------------------------------*/
36 /* \fn    AT91F_DataFlashSendCommand                                    */
37 /* \brief Generic function to send a command to the dataflash           */
38 /*----------------------------------------------------------------------*/
39 AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash,
40                                                  unsigned char OpCode,
41                                                  unsigned int CmdSize,
42                                                  unsigned int DataflashAddress)
43 {
44         unsigned int adr;
45
46         if ((pDataFlash->pDataFlashDesc->state) != IDLE)
47                 return DATAFLASH_BUSY;
48
49         /* process the address to obtain page address and byte address */
50         adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) <<
51                 pDataFlash->pDevice->page_offset) +
52                         (DataflashAddress % (pDataFlash->pDevice->pages_size));
53
54         /* fill the command buffer */
55         pDataFlash->pDataFlashDesc->command[0] = OpCode;
56         if (pDataFlash->pDevice->pages_number >= 16384) {
57                 pDataFlash->pDataFlashDesc->command[1] =
58                         (unsigned char)((adr & 0x0F000000) >> 24);
59                 pDataFlash->pDataFlashDesc->command[2] =
60                         (unsigned char)((adr & 0x00FF0000) >> 16);
61                 pDataFlash->pDataFlashDesc->command[3] =
62                         (unsigned char)((adr & 0x0000FF00) >> 8);
63                 pDataFlash->pDataFlashDesc->command[4] =
64                         (unsigned char)(adr & 0x000000FF);
65         } else {
66                 pDataFlash->pDataFlashDesc->command[1] =
67                         (unsigned char)((adr & 0x00FF0000) >> 16);
68                 pDataFlash->pDataFlashDesc->command[2] =
69                         (unsigned char)((adr & 0x0000FF00) >> 8);
70                 pDataFlash->pDataFlashDesc->command[3] =
71                         (unsigned char)(adr & 0x000000FF);
72                 pDataFlash->pDataFlashDesc->command[4] = 0;
73         }
74         pDataFlash->pDataFlashDesc->command[5] = 0;
75         pDataFlash->pDataFlashDesc->command[6] = 0;
76         pDataFlash->pDataFlashDesc->command[7] = 0;
77
78         /* Initialize the SpiData structure for the spi write fuction */
79         pDataFlash->pDataFlashDesc->tx_cmd_pt =
80                 pDataFlash->pDataFlashDesc->command;
81         pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
82         pDataFlash->pDataFlashDesc->rx_cmd_pt =
83                 pDataFlash->pDataFlashDesc->command;
84         pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;
85
86         /* send the command and read the data */
87         return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
88 }
89
90 /*----------------------------------------------------------------------*/
91 /* \fn    AT91F_DataFlashGetStatus                                      */
92 /* \brief Read the status register of the dataflash                     */
93 /*----------------------------------------------------------------------*/
94 AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
95 {
96         AT91S_DataFlashStatus status;
97
98         /* if a transfert is in progress ==> return 0 */
99         if ((pDesc->state) != IDLE)
100                 return DATAFLASH_BUSY;
101
102         /* first send the read status command (D7H) */
103         pDesc->command[0] = DB_STATUS;
104         pDesc->command[1] = 0;
105
106         pDesc->DataFlash_state = GET_STATUS;
107         pDesc->tx_data_size = 0;        /* Transmit the command */
108         /* and receive response */
109         pDesc->tx_cmd_pt = pDesc->command;
110         pDesc->rx_cmd_pt = pDesc->command;
111         pDesc->rx_cmd_size = 2;
112         pDesc->tx_cmd_size = 2;
113         status = AT91F_SpiWrite(pDesc);
114
115         pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);
116
117         return status;
118 }
119
120 /*----------------------------------------------------------------------*/
121 /* \fn    AT91F_DataFlashWaitReady                                      */
122 /* \brief wait for dataflash ready (bit7 of the status register == 1)   */
123 /*----------------------------------------------------------------------*/
124 AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
125                                                 pDataFlashDesc,
126                                                 unsigned int timeout)
127 {
128         pDataFlashDesc->DataFlash_state = IDLE;
129
130         do {
131                 AT91F_DataFlashGetStatus(pDataFlashDesc);
132                 timeout--;
133         } while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
134                  (timeout > 0));
135
136         if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
137                 return DATAFLASH_ERROR;
138
139         return DATAFLASH_OK;
140 }
141
142 /*--------------------------------------------------------------------------*/
143 /* Function Name       : AT91F_DataFlashContinuousRead                      */
144 /* Object              : Continuous stream Read                             */
145 /* Input Parameters    : DataFlash Service                                  */
146 /*                                              : <src> = dataflash address */
147 /*                     : <*dataBuffer> = data buffer pointer                */
148 /*                     : <sizeToRead> = data buffer size                    */
149 /* Return value         : State of the dataflash                            */
150 /*--------------------------------------------------------------------------*/
151 AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
152                                 AT91PS_DataFlash pDataFlash,
153                                 int src,
154                                 unsigned char *dataBuffer,
155                                 int sizeToRead)
156 {
157         AT91S_DataFlashStatus status;
158         /* Test the size to read in the device */
159         if ((src + sizeToRead) >
160                         (pDataFlash->pDevice->pages_size *
161                                 (pDataFlash->pDevice->pages_number)))
162                 return DATAFLASH_MEMORY_OVERFLOW;
163
164         pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
165         pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
166         pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
167         pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
168
169         status = AT91F_DataFlashSendCommand(
170                         pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
171         /* Send the command to the dataflash */
172         return (status);
173 }
174
175 /*---------------------------------------------------------------------------*/
176 /* Function Name       : AT91F_DataFlashPagePgmBuf                           */
177 /* Object              : Main memory page program thru buffer 1 or buffer 2  */
178 /* Input Parameters    : DataFlash Service                                   */
179 /*                                              : <*src> = Source buffer     */
180 /*                     : <dest> = dataflash destination address              */
181 /*                     : <SizeToWrite> = data buffer size                    */
182 /* Return value         : State of the dataflash                             */
183 /*---------------------------------------------------------------------------*/
184 AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash,
185                                                 unsigned char *src,
186                                                 unsigned int dest,
187                                                 unsigned int SizeToWrite)
188 {
189         int cmdsize;
190         pDataFlash->pDataFlashDesc->tx_data_pt = src;
191         pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
192         pDataFlash->pDataFlashDesc->rx_data_pt = src;
193         pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
194
195         cmdsize = 4;
196         /* Send the command to the dataflash */
197         if (pDataFlash->pDevice->pages_number >= 16384)
198                 cmdsize = 5;
199         return (AT91F_DataFlashSendCommand(
200                         pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
201 }
202
203 /*---------------------------------------------------------------------------*/
204 /* Function Name       : AT91F_MainMemoryToBufferTransfert                   */
205 /* Object              : Read a page in the SRAM Buffer 1 or 2               */
206 /* Input Parameters    : DataFlash Service                                   */
207 /*                     : Page concerned                                      */
208 /*                     :                                                     */
209 /* Return value         : State of the dataflash                             */
210 /*---------------------------------------------------------------------------*/
211 AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
212                                         AT91PS_DataFlash
213                                         pDataFlash,
214                                         unsigned char
215                                         BufferCommand,
216                                         unsigned int page)
217 {
218         int cmdsize;
219         /* Test if the buffer command is legal */
220         if ((BufferCommand != DB_PAGE_2_BUF1_TRF) &&
221                         (BufferCommand != DB_PAGE_2_BUF2_TRF)) {
222                 return DATAFLASH_BAD_COMMAND;
223         }
224
225         /* no data to transmit or receive */
226         pDataFlash->pDataFlashDesc->tx_data_size = 0;
227         cmdsize = 4;
228         if (pDataFlash->pDevice->pages_number >= 16384)
229                 cmdsize = 5;
230         return (AT91F_DataFlashSendCommand(
231                         pDataFlash, BufferCommand, cmdsize,
232                         page * pDataFlash->pDevice->pages_size));
233 }
234
235 /*-------------------------------------------------------------------------- */
236 /* Function Name       : AT91F_DataFlashWriteBuffer                          */
237 /* Object              : Write data to the internal sram buffer 1 or 2       */
238 /* Input Parameters    : DataFlash Service                                   */
239 /*                      : <BufferCommand> = command to write buffer1 or 2    */
240 /*                     : <*dataBuffer> = data buffer to write                */
241 /*                     : <bufferAddress> = address in the internal buffer    */
242 /*                     : <SizeToWrite> = data buffer size                    */
243 /* Return value         : State of the dataflash                             */
244 /*---------------------------------------------------------------------------*/
245 AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
246                                         AT91PS_DataFlash pDataFlash,
247                                         unsigned char BufferCommand,
248                                         unsigned char *dataBuffer,
249                                         unsigned int bufferAddress,
250                                         int SizeToWrite)
251 {
252         int cmdsize;
253         /* Test if the buffer command is legal */
254         if ((BufferCommand != DB_BUF1_WRITE) &&
255                         (BufferCommand != DB_BUF2_WRITE)) {
256                 return DATAFLASH_BAD_COMMAND;
257         }
258
259         /* buffer address must be lower than page size */
260         if (bufferAddress > pDataFlash->pDevice->pages_size)
261                 return DATAFLASH_BAD_ADDRESS;
262
263         if ((pDataFlash->pDataFlashDesc->state) != IDLE)
264                 return DATAFLASH_BUSY;
265
266         /* Send first Write Command */
267         pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
268         pDataFlash->pDataFlashDesc->command[1] = 0;
269         if (pDataFlash->pDevice->pages_number >= 16384) {
270                 pDataFlash->pDataFlashDesc->command[2] = 0;
271                 pDataFlash->pDataFlashDesc->command[3] =
272                         (unsigned char)(((unsigned int)(bufferAddress &
273                                                         pDataFlash->pDevice->
274                                                         byte_mask)) >> 8);
275                 pDataFlash->pDataFlashDesc->command[4] =
276                         (unsigned char)((unsigned int)bufferAddress & 0x00FF);
277                 cmdsize = 5;
278         } else {
279                 pDataFlash->pDataFlashDesc->command[2] =
280                         (unsigned char)(((unsigned int)(bufferAddress &
281                                                         pDataFlash->pDevice->
282                                                         byte_mask)) >> 8);
283                 pDataFlash->pDataFlashDesc->command[3] =
284                         (unsigned char)((unsigned int)bufferAddress & 0x00FF);
285                 pDataFlash->pDataFlashDesc->command[4] = 0;
286                 cmdsize = 4;
287         }
288
289         pDataFlash->pDataFlashDesc->tx_cmd_pt =
290                 pDataFlash->pDataFlashDesc->command;
291         pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
292         pDataFlash->pDataFlashDesc->rx_cmd_pt =
293                 pDataFlash->pDataFlashDesc->command;
294         pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;
295
296         pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
297         pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
298         pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
299         pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
300
301         return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
302 }
303
304 /*---------------------------------------------------------------------------*/
305 /* Function Name       : AT91F_PageErase                                     */
306 /* Object              : Erase a page                                        */
307 /* Input Parameters    : DataFlash Service                                   */
308 /*                     : Page concerned                                      */
309 /*                     :                                                     */
310 /* Return value         : State of the dataflash                             */
311 /*---------------------------------------------------------------------------*/
312 AT91S_DataFlashStatus AT91F_PageErase(
313                                         AT91PS_DataFlash pDataFlash,
314                                         unsigned int page)
315 {
316         int cmdsize;
317         /* Test if the buffer command is legal */
318         /* no data to transmit or receive */
319         pDataFlash->pDataFlashDesc->tx_data_size = 0;
320
321         cmdsize = 4;
322         if (pDataFlash->pDevice->pages_number >= 16384)
323                 cmdsize = 5;
324         return (AT91F_DataFlashSendCommand(pDataFlash,
325                                 DB_PAGE_ERASE, cmdsize,
326                                 page * pDataFlash->pDevice->pages_size));
327 }
328
329 /*---------------------------------------------------------------------------*/
330 /* Function Name       : AT91F_BlockErase                                    */
331 /* Object              : Erase a Block                                       */
332 /* Input Parameters    : DataFlash Service                                   */
333 /*                     : Page concerned                                      */
334 /*                     :                                                     */
335 /* Return value         : State of the dataflash                             */
336 /*---------------------------------------------------------------------------*/
337 AT91S_DataFlashStatus AT91F_BlockErase(
338                                 AT91PS_DataFlash pDataFlash,
339                                 unsigned int block)
340 {
341         int cmdsize;
342         /* Test if the buffer command is legal */
343         /* no data to transmit or receive */
344         pDataFlash->pDataFlashDesc->tx_data_size = 0;
345         cmdsize = 4;
346         if (pDataFlash->pDevice->pages_number >= 16384)
347                 cmdsize = 5;
348         return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
349                                         block * 8 *
350                                         pDataFlash->pDevice->pages_size));
351 }
352
353 /*---------------------------------------------------------------------------*/
354 /* Function Name       : AT91F_WriteBufferToMain                             */
355 /* Object              : Write buffer to the main memory                     */
356 /* Input Parameters    : DataFlash Service                                   */
357 /*              : <BufferCommand> = command to send to buffer1 or buffer2    */
358 /*                     : <dest> = main memory address                        */
359 /* Return value         : State of the dataflash                             */
360 /*---------------------------------------------------------------------------*/
361 AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
362                                         unsigned char BufferCommand,
363                                         unsigned int dest)
364 {
365         int cmdsize;
366         /* Test if the buffer command is correct */
367         if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
368                         (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
369                         (BufferCommand != DB_BUF2_PAGE_PGM) &&
370                         (BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
371                 return DATAFLASH_BAD_COMMAND;
372
373         /* no data to transmit or receive */
374         pDataFlash->pDataFlashDesc->tx_data_size = 0;
375
376         cmdsize = 4;
377         if (pDataFlash->pDevice->pages_number >= 16384)
378                 cmdsize = 5;
379         /* Send the command to the dataflash */
380         return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand,
381                                                 cmdsize, dest));
382 }
383
384 /*---------------------------------------------------------------------------*/
385 /* Function Name       : AT91F_PartialPageWrite                              */
386 /* Object              : Erase partielly a page                              */
387 /* Input Parameters    : <page> = page number                                */
388 /*                      : <AdrInpage> = adr to begin the fading              */
389 /*                     : <length> = Number of bytes to erase                 */
390 /*---------------------------------------------------------------------------*/
391 AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
392                                         unsigned char *src,
393                                         unsigned int dest,
394                                         unsigned int size)
395 {
396         unsigned int page;
397         unsigned int AdrInPage;
398
399         page = dest / (pDataFlash->pDevice->pages_size);
400         AdrInPage = dest % (pDataFlash->pDevice->pages_size);
401
402         /* Read the contents of the page in the Sram Buffer */
403         AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
404         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
405                                  AT91C_TIMEOUT_WRDY);
406         /*Update the SRAM buffer */
407         AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
408                                         AdrInPage, size);
409
410         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
411                                         AT91C_TIMEOUT_WRDY);
412
413         /* Erase page if a 128 Mbits device */
414         if (pDataFlash->pDevice->pages_number >= 16384) {
415                 AT91F_PageErase(pDataFlash, page);
416                 /* Rewrite the modified Sram Buffer in the main memory */
417                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
418                                          AT91C_TIMEOUT_WRDY);
419         }
420
421         /* Rewrite the modified Sram Buffer in the main memory */
422         return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
423                                         (page *
424                                          pDataFlash->pDevice->pages_size)));
425 }
426
427 /*---------------------------------------------------------------------------*/
428 /* Function Name       : AT91F_DataFlashWrite                                */
429 /* Object              :                                                     */
430 /* Input Parameters    : <*src> = Source buffer                              */
431 /*                     : <dest> = dataflash adress                           */
432 /*                     : <size> = data buffer size                           */
433 /*---------------------------------------------------------------------------*/
434 AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
435                                                 unsigned char *src,
436                                                 int dest, int size)
437 {
438         unsigned int length;
439         unsigned int page;
440         unsigned int status;
441
442         AT91F_SpiEnable(pDataFlash->pDevice->cs);
443
444         if ((dest + size) > (pDataFlash->pDevice->pages_size *
445                         (pDataFlash->pDevice->pages_number)))
446                 return DATAFLASH_MEMORY_OVERFLOW;
447
448         /* If destination does not fit a page start address */
449         if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
450                 length =
451                         pDataFlash->pDevice->pages_size -
452                         (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
453
454                 if (size < length)
455                         length = size;
456
457                 if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
458                         return DATAFLASH_ERROR;
459
460                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
461                                          AT91C_TIMEOUT_WRDY);
462
463                 /* Update size, source and destination pointers */
464                 size -= length;
465                 dest += length;
466                 src += length;
467         }
468
469         while ((size - pDataFlash->pDevice->pages_size) >= 0) {
470                 /* program dataflash page */
471                 page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
472
473                 status = AT91F_DataFlashWriteBuffer(pDataFlash,
474                                         DB_BUF1_WRITE, src, 0,
475                                         pDataFlash->pDevice->
476                                         pages_size);
477                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
478                                          AT91C_TIMEOUT_WRDY);
479
480                 status = AT91F_PageErase(pDataFlash, page);
481                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
482                                          AT91C_TIMEOUT_WRDY);
483                 if (!status)
484                         return DATAFLASH_ERROR;
485
486                 status = AT91F_WriteBufferToMain(pDataFlash,
487                                          DB_BUF1_PAGE_PGM, dest);
488                 if (!status)
489                         return DATAFLASH_ERROR;
490
491                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
492                                          AT91C_TIMEOUT_WRDY);
493
494                 /* Update size, source and destination pointers */
495                 size -= pDataFlash->pDevice->pages_size;
496                 dest += pDataFlash->pDevice->pages_size;
497                 src += pDataFlash->pDevice->pages_size;
498         }
499
500         /* If still some bytes to read */
501         if (size > 0) {
502                 /* program dataflash page */
503                 if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
504                         return DATAFLASH_ERROR;
505
506                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
507                                          AT91C_TIMEOUT_WRDY);
508         }
509         return DATAFLASH_OK;
510 }
511
512 /*---------------------------------------------------------------------------*/
513 /* Function Name       : AT91F_DataFlashRead                                 */
514 /* Object              : Read a block in dataflash                           */
515 /* Input Parameters    :                                                     */
516 /* Return value         :                                                    */
517 /*---------------------------------------------------------------------------*/
518 int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
519                         unsigned long addr, unsigned long size, char *buffer)
520 {
521         unsigned long SizeToRead;
522
523         AT91F_SpiEnable(pDataFlash->pDevice->cs);
524
525         if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
526                                         AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
527                 return -1;
528
529         while (size) {
530                 SizeToRead = (size < 0x8000) ? size : 0x8000;
531
532                 if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
533                                         AT91C_TIMEOUT_WRDY) !=
534                                                 DATAFLASH_OK)
535                         return -1;
536
537                 if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
538                                                 (uchar *) buffer,
539                                                 SizeToRead) != DATAFLASH_OK)
540                         return -1;
541
542                 size -= SizeToRead;
543                 addr += SizeToRead;
544                 buffer += SizeToRead;
545         }
546
547         return DATAFLASH_OK;
548 }
549
550 /*---------------------------------------------------------------------------*/
551 /* Function Name       : AT91F_DataflashProbe                                */
552 /* Object              :                                                     */
553 /* Input Parameters    :                                                     */
554 /* Return value        : Dataflash status register                           */
555 /*---------------------------------------------------------------------------*/
556 int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
557 {
558         AT91F_SpiEnable(cs);
559         AT91F_DataFlashGetStatus(pDesc);
560         return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
561 }
562 #endif