]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/at45.c
Ran Lindent on drivers/at45.c
[karo-tx-uboot.git] / drivers / 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) + (DataflashAddress %
52                                                     (pDataFlash->pDevice->
53                                                      pages_size));
54
55         /* fill the  command  buffer */
56         pDataFlash->pDataFlashDesc->command[0] = OpCode;
57         if (pDataFlash->pDevice->pages_number >= 16384) {
58                 pDataFlash->pDataFlashDesc->command[1] =
59                     (unsigned char)((adr & 0x0F000000) >> 24);
60                 pDataFlash->pDataFlashDesc->command[2] =
61                     (unsigned char)((adr & 0x00FF0000) >> 16);
62                 pDataFlash->pDataFlashDesc->command[3] =
63                     (unsigned char)((adr & 0x0000FF00) >> 8);
64                 pDataFlash->pDataFlashDesc->command[4] =
65                     (unsigned char)(adr & 0x000000FF);
66         } else {
67                 pDataFlash->pDataFlashDesc->command[1] =
68                     (unsigned char)((adr & 0x00FF0000) >> 16);
69                 pDataFlash->pDataFlashDesc->command[2] =
70                     (unsigned char)((adr & 0x0000FF00) >> 8);
71                 pDataFlash->pDataFlashDesc->command[3] =
72                     (unsigned char)(adr & 0x000000FF);
73                 pDataFlash->pDataFlashDesc->command[4] = 0;
74         }
75         pDataFlash->pDataFlashDesc->command[5] = 0;
76         pDataFlash->pDataFlashDesc->command[6] = 0;
77         pDataFlash->pDataFlashDesc->command[7] = 0;
78
79         /* Initialize the SpiData structure for the spi write fuction */
80         pDataFlash->pDataFlashDesc->tx_cmd_pt =
81             pDataFlash->pDataFlashDesc->command;
82         pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
83         pDataFlash->pDataFlashDesc->rx_cmd_pt =
84             pDataFlash->pDataFlashDesc->command;
85         pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;
86
87         /* send the command and read the data */
88         return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
89 }
90
91 /*----------------------------------------------------------------------*/
92 /* \fn    AT91F_DataFlashGetStatus                                      */
93 /* \brief Read the status register of the dataflash                     */
94 /*----------------------------------------------------------------------*/
95 AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
96 {
97         AT91S_DataFlashStatus status;
98
99         /* if a transfert is in progress ==> return 0 */
100         if ((pDesc->state) != IDLE)
101                 return DATAFLASH_BUSY;
102
103         /* first send the read status command (D7H) */
104         pDesc->command[0] = DB_STATUS;
105         pDesc->command[1] = 0;
106
107         pDesc->DataFlash_state = GET_STATUS;
108         pDesc->tx_data_size = 0;        /* Transmit the command */
109         /* and receive response */
110         pDesc->tx_cmd_pt = pDesc->command;
111         pDesc->rx_cmd_pt = pDesc->command;
112         pDesc->rx_cmd_size = 2;
113         pDesc->tx_cmd_size = 2;
114         status = AT91F_SpiWrite(pDesc);
115
116         pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);
117
118         return status;
119 }
120
121 /*----------------------------------------------------------------------*/
122 /* \fn    AT91F_DataFlashWaitReady                                      */
123 /* \brief wait for dataflash ready (bit7 of the status register == 1)   */
124 /*----------------------------------------------------------------------*/
125 AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
126                                                pDataFlashDesc,
127                                                unsigned int timeout)
128 {
129         pDataFlashDesc->DataFlash_state = IDLE;
130
131         do {
132                 AT91F_DataFlashGetStatus(pDataFlashDesc);
133                 timeout--;
134         } while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
135                  (timeout > 0));
136
137         if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
138                 return DATAFLASH_ERROR;
139
140         return DATAFLASH_OK;
141 }
142
143 /*--------------------------------------------------------------------------*/
144 /* Function Name       : AT91F_DataFlashContinuousRead                      */
145 /* Object              : Continuous stream Read                             */
146 /* Input Parameters    : DataFlash Service                                  */
147 /*                                              : <src> = dataflash address */
148 /*                     : <*dataBuffer> = data buffer pointer                */
149 /*                     : <sizeToRead> = data buffer size                    */
150 /* Return value         : State of the dataflash                            */
151 /*--------------------------------------------------------------------------*/
152 AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(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(pDataFlash, DB_PAGE_PGM_BUF1,
200                                            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(AT91PS_DataFlash
212                                                         pDataFlash,
213                                                         unsigned char
214                                                         BufferCommand,
215                                                         unsigned int page)
216 {
217         int cmdsize;
218         /* Test if the buffer command is legal */
219         if ((BufferCommand != DB_PAGE_2_BUF1_TRF)
220             && (BufferCommand != DB_PAGE_2_BUF2_TRF))
221                 return DATAFLASH_BAD_COMMAND;
222
223         /* no data to transmit or receive */
224         pDataFlash->pDataFlashDesc->tx_data_size = 0;
225         cmdsize = 4;
226         if (pDataFlash->pDevice->pages_number >= 16384)
227                 cmdsize = 5;
228         return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, cmdsize,
229                                            page *
230                                            pDataFlash->pDevice->pages_size));
231 }
232
233 /*-------------------------------------------------------------------------- */
234 /* Function Name       : AT91F_DataFlashWriteBuffer                          */
235 /* Object              : Write data to the internal sram buffer 1 or 2       */
236 /* Input Parameters    : DataFlash Service                                   */
237 /*                      : <BufferCommand> = command to write buffer1 or 2    */
238 /*                     : <*dataBuffer> = data buffer to write                */
239 /*                     : <bufferAddress> = address in the internal buffer    */
240 /*                     : <SizeToWrite> = data buffer size                    */
241 /* Return value         : State of the dataflash                             */
242 /*---------------------------------------------------------------------------*/
243 AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(AT91PS_DataFlash pDataFlash,
244                                                  unsigned char BufferCommand,
245                                                  unsigned char *dataBuffer,
246                                                  unsigned int bufferAddress,
247                                                  int SizeToWrite)
248 {
249         int cmdsize;
250         /* Test if the buffer command is legal */
251         if ((BufferCommand != DB_BUF1_WRITE)
252             && (BufferCommand != DB_BUF2_WRITE))
253                 return DATAFLASH_BAD_COMMAND;
254
255         /* buffer address must be lower than page size */
256         if (bufferAddress > pDataFlash->pDevice->pages_size)
257                 return DATAFLASH_BAD_ADDRESS;
258
259         if ((pDataFlash->pDataFlashDesc->state) != IDLE)
260                 return DATAFLASH_BUSY;
261
262         /* Send first Write Command */
263         pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
264         pDataFlash->pDataFlashDesc->command[1] = 0;
265         if (pDataFlash->pDevice->pages_number >= 16384) {
266                 pDataFlash->pDataFlashDesc->command[2] = 0;
267                 pDataFlash->pDataFlashDesc->command[3] =
268                     (unsigned char)(((unsigned int)(bufferAddress &
269                                                     pDataFlash->pDevice->
270                                                     byte_mask)) >> 8);
271                 pDataFlash->pDataFlashDesc->command[4] =
272                     (unsigned char)((unsigned int)bufferAddress & 0x00FF);
273                 cmdsize = 5;
274         } else {
275                 pDataFlash->pDataFlashDesc->command[2] =
276                     (unsigned char)(((unsigned int)(bufferAddress &
277                                                     pDataFlash->pDevice->
278                                                     byte_mask)) >> 8);
279                 pDataFlash->pDataFlashDesc->command[3] =
280                     (unsigned char)((unsigned int)bufferAddress & 0x00FF);
281                 pDataFlash->pDataFlashDesc->command[4] = 0;
282                 cmdsize = 4;
283         }
284
285         pDataFlash->pDataFlashDesc->tx_cmd_pt =
286             pDataFlash->pDataFlashDesc->command;
287         pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
288         pDataFlash->pDataFlashDesc->rx_cmd_pt =
289             pDataFlash->pDataFlashDesc->command;
290         pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;
291
292         pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
293         pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
294         pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
295         pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
296
297         return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
298 }
299
300 /*---------------------------------------------------------------------------*/
301 /* Function Name       : AT91F_PageErase                                     */
302 /* Object              : Erase a page                                        */
303 /* Input Parameters    : DataFlash Service                                   */
304 /*                     : Page concerned                                      */
305 /*                     :                                                     */
306 /* Return value         : State of the dataflash                             */
307 /*---------------------------------------------------------------------------*/
308 AT91S_DataFlashStatus AT91F_PageErase(AT91PS_DataFlash pDataFlash,
309                                       unsigned int page)
310 {
311         int cmdsize;
312         /* Test if the buffer command is legal */
313         /* no data to transmit or receive */
314         pDataFlash->pDataFlashDesc->tx_data_size = 0;
315
316         cmdsize = 4;
317         if (pDataFlash->pDevice->pages_number >= 16384)
318                 cmdsize = 5;
319         return (AT91F_DataFlashSendCommand(pDataFlash, DB_PAGE_ERASE, cmdsize,
320                                            page *
321                                            pDataFlash->pDevice->pages_size));
322 }
323
324 /*---------------------------------------------------------------------------*/
325 /* Function Name       : AT91F_BlockErase                                    */
326 /* Object              : Erase a Block                                       */
327 /* Input Parameters    : DataFlash Service                                   */
328 /*                     : Page concerned                                      */
329 /*                     :                                                     */
330 /* Return value         : State of the dataflash                             */
331 /*---------------------------------------------------------------------------*/
332 AT91S_DataFlashStatus AT91F_BlockErase(AT91PS_DataFlash pDataFlash,
333                                        unsigned int block)
334 {
335         int cmdsize;
336         /* Test if the buffer command is legal */
337         /* no data to transmit or receive */
338         pDataFlash->pDataFlashDesc->tx_data_size = 0;
339         cmdsize = 4;
340         if (pDataFlash->pDevice->pages_number >= 16384)
341                 cmdsize = 5;
342         return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
343                                            block * 8 *
344                                            pDataFlash->pDevice->pages_size));
345 }
346
347 /*---------------------------------------------------------------------------*/
348 /* Function Name       : AT91F_WriteBufferToMain                             */
349 /* Object              : Write buffer to the main memory                     */
350 /* Input Parameters    : DataFlash Service                                   */
351 /*              : <BufferCommand> = command to send to buffer1 or buffer2    */
352 /*                     : <dest> = main memory address                        */
353 /* Return value         : State of the dataflash                             */
354 /*---------------------------------------------------------------------------*/
355 AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
356                                               unsigned char BufferCommand,
357                                               unsigned int dest)
358 {
359         int cmdsize;
360         /* Test if the buffer command is correct */
361         if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
362             (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
363             (BufferCommand != DB_BUF2_PAGE_PGM) &&
364             (BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
365                 return DATAFLASH_BAD_COMMAND;
366
367         /* no data to transmit or receive */
368         pDataFlash->pDataFlashDesc->tx_data_size = 0;
369
370         cmdsize = 4;
371         if (pDataFlash->pDevice->pages_number >= 16384)
372                 cmdsize = 5;
373         /* Send the command to the dataflash */
374         return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, cmdsize,
375                                            dest));
376 }
377
378 /*---------------------------------------------------------------------------*/
379 /* Function Name       : AT91F_PartialPageWrite                              */
380 /* Object              : Erase partielly a page                              */
381 /* Input Parameters    : <page> = page number                                */
382 /*                      : <AdrInpage> = adr to begin the fading              */
383 /*                     : <length> = Number of bytes to erase                 */
384 /*---------------------------------------------------------------------------*/
385 AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
386                                              unsigned char *src,
387                                              unsigned int dest,
388                                              unsigned int size)
389 {
390         unsigned int page;
391         unsigned int AdrInPage;
392
393         page = dest / (pDataFlash->pDevice->pages_size);
394         AdrInPage = dest % (pDataFlash->pDevice->pages_size);
395
396         /* Read the contents of the page in the Sram Buffer */
397         AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
398         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
399                                  AT91C_TIMEOUT_WRDY);
400         /*Update the SRAM buffer */
401         AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
402                                    AdrInPage, size);
403
404         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
405                                  AT91C_TIMEOUT_WRDY);
406
407         /* Erase page if a 128 Mbits device */
408         if (pDataFlash->pDevice->pages_number >= 16384) {
409                 AT91F_PageErase(pDataFlash, page);
410                 /* Rewrite the modified Sram Buffer in the main memory */
411                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
412                                          AT91C_TIMEOUT_WRDY);
413         }
414
415         /* Rewrite the modified Sram Buffer in the main memory */
416         return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
417                                         (page *
418                                          pDataFlash->pDevice->pages_size)));
419 }
420
421 /*---------------------------------------------------------------------------*/
422 /* Function Name       : AT91F_DataFlashWrite                                */
423 /* Object              :                                                     */
424 /* Input Parameters    : <*src> = Source buffer                              */
425 /*                     : <dest> = dataflash adress                           */
426 /*                     : <size> = data buffer size                           */
427 /*---------------------------------------------------------------------------*/
428 AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
429                                            unsigned char *src,
430                                            int dest, int size)
431 {
432         unsigned int length;
433         unsigned int page;
434         unsigned int status;
435
436         AT91F_SpiEnable(pDataFlash->pDevice->cs);
437
438         if ((dest + size) > (pDataFlash->pDevice->pages_size *
439                              (pDataFlash->pDevice->pages_number)))
440                 return DATAFLASH_MEMORY_OVERFLOW;
441
442         /* If destination does not fit a page start address */
443         if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
444                 length = pDataFlash->pDevice->pages_size -
445                     (dest % ((unsigned int)
446                              (pDataFlash->pDevice->pages_size)));
447
448                 if (size < length)
449                         length = size;
450
451                 if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
452                         return DATAFLASH_ERROR;
453
454                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
455                                          AT91C_TIMEOUT_WRDY);
456
457                 /* Update size, source and destination pointers */
458                 size -= length;
459                 dest += length;
460                 src += length;
461         }
462
463         while ((size - pDataFlash->pDevice->pages_size) >= 0) {
464                 /* program dataflash page */
465                 page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
466
467                 status = AT91F_DataFlashWriteBuffer(pDataFlash,
468                                                     DB_BUF1_WRITE, src, 0,
469                                                     pDataFlash->pDevice->
470                                                     pages_size);
471                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
472                                          AT91C_TIMEOUT_WRDY);
473
474                 status = AT91F_PageErase(pDataFlash, page);
475                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
476                                          AT91C_TIMEOUT_WRDY);
477                 if (!status)
478                         return DATAFLASH_ERROR;
479
480                 status = AT91F_WriteBufferToMain(pDataFlash,
481                                                  DB_BUF1_PAGE_PGM, dest);
482                 if (!status)
483                         return DATAFLASH_ERROR;
484
485                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
486                                          AT91C_TIMEOUT_WRDY);
487
488                 /* Update size, source and destination pointers */
489                 size -= pDataFlash->pDevice->pages_size;
490                 dest += pDataFlash->pDevice->pages_size;
491                 src += pDataFlash->pDevice->pages_size;
492         }
493
494         /* If still some bytes to read */
495         if (size > 0) {
496                 /* program dataflash page */
497                 if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
498                         return DATAFLASH_ERROR;
499
500                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
501                                          AT91C_TIMEOUT_WRDY);
502         }
503         return DATAFLASH_OK;
504 }
505
506 /*---------------------------------------------------------------------------*/
507 /* Function Name       : AT91F_DataFlashRead                                 */
508 /* Object              : Read a block in dataflash                           */
509 /* Input Parameters    :                                                     */
510 /* Return value         :                                                    */
511 /*---------------------------------------------------------------------------*/
512 int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
513                         unsigned long addr, unsigned long size, char *buffer)
514 {
515         unsigned long SizeToRead;
516
517         AT91F_SpiEnable(pDataFlash->pDevice->cs);
518
519         if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
520                                      AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
521                 return -1;
522
523         while (size) {
524                 SizeToRead = (size < 0x8000) ? size : 0x8000;
525
526                 if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
527                                              AT91C_TIMEOUT_WRDY) !=
528                     DATAFLASH_OK)
529                         return -1;
530
531                 if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
532                                                   (uchar *) buffer,
533                                                   SizeToRead) != DATAFLASH_OK)
534                         return -1;
535
536                 size -= SizeToRead;
537                 addr += SizeToRead;
538                 buffer += SizeToRead;
539         }
540
541         return DATAFLASH_OK;
542 }
543
544 /*---------------------------------------------------------------------------*/
545 /* Function Name       : AT91F_DataflashProbe                                */
546 /* Object              :                                                     */
547 /* Input Parameters    :                                                     */
548 /* Return value        : Dataflash status register                           */
549 /*---------------------------------------------------------------------------*/
550 int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
551 {
552         AT91F_SpiEnable(cs);
553         AT91F_DataFlashGetStatus(pDesc);
554         return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
555 }
556 #endif