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