1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2004 by Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "ata_idle_notify.h"
38 #include "disk.h" /* for mount/unmount */
40 #define SECTOR_SIZE 512
41 #define MAX_BLOCK_SIZE 2048
43 /* Command definitions */
44 #define CMD_GO_IDLE_STATE 0x40 /* R1 */
45 #define CMD_SEND_OP_COND 0x41 /* R1 */
46 #define CMD_SEND_CSD 0x49 /* R1 */
47 #define CMD_SEND_CID 0x4a /* R1 */
48 #define CMD_STOP_TRANSMISSION 0x4c /* R1 */
49 #define CMD_SEND_STATUS 0x4d /* R2 */
50 #define CMD_SET_BLOCKLEN 0x50 /* R1 */
51 #define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */
52 #define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */
53 #define CMD_WRITE_BLOCK 0x58 /* R1b */
54 #define CMD_WRITE_MULTIPLE_BLOCK 0x59 /* R1b */
55 #define CMD_READ_OCR 0x7a /* R3 */
58 R1 = single byte, msb=0, various error flags
59 R1b = R1 + busy token(s)
60 R2 = 2 bytes (1st byte identical to R1), additional flags
61 R3 = 5 bytes (R1 + OCR register)
64 #define R1_PARAMETER_ERR 0x40
65 #define R1_ADDRESS_ERR 0x20
66 #define R1_ERASE_SEQ_ERR 0x10
67 #define R1_COM_CRC_ERR 0x08
68 #define R1_ILLEGAL_CMD 0x04
69 #define R1_ERASE_RESET 0x02
70 #define R1_IN_IDLE_STATE 0x01
72 #define R2_OUT_OF_RANGE 0x80
73 #define R2_ERASE_PARAM 0x40
74 #define R2_WP_VIOLATION 0x20
75 #define R2_CARD_ECC_FAIL 0x10
76 #define R2_CC_ERROR 0x08
78 #define R2_ERASE_SKIP 0x02
79 #define R2_CARD_LOCKED 0x01
81 /* Data start tokens */
83 #define DT_START_BLOCK 0xfe
84 #define DT_START_WRITE_MULTIPLE 0xfc
85 #define DT_STOP_TRAN 0xfd
87 /* for compatibility */
88 int ata_spinup_time
= 0;
89 long last_disk_activity
= -1;
91 /* private variables */
93 static struct mutex mmc_mutex
;
96 static bool mmc_monitor_enabled
= true;
97 static long mmc_stack
[((DEFAULT_STACK_SIZE
*2) + 0x800)/sizeof(long)];
99 static long mmc_stack
[(DEFAULT_STACK_SIZE
*2)/sizeof(long)];
101 static const char mmc_thread_name
[] = "mmc";
102 static struct event_queue mmc_queue
;
103 static bool initialized
= false;
104 static bool new_mmc_circuit
;
110 } mmc_status
= MMC_UNKNOWN
;
118 static const unsigned char dummy
[] = {
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
122 struct block_cache_entry
{
124 #ifdef HAVE_MULTIVOLUME
127 unsigned long blocknum
;
128 unsigned char data
[MAX_BLOCK_SIZE
+4];
129 /* include start token, dummy crc, and an extra byte at the start
130 * to keep the data word aligned. */
133 /* 2 buffers used alternatively for writing, and also for reading
134 * and sub-block writing if block size > sector size */
136 static struct block_cache_entry block_cache
[NUMCACHES
];
137 static int current_cache
= 0;
139 /* globals for background copy and swap */
140 static const unsigned char *bcs_src
= NULL
;
141 static unsigned char *bcs_dest
= NULL
;
142 static unsigned long bcs_len
= 0;
144 static tCardInfo card_info
[2];
145 #ifndef HAVE_MULTIVOLUME
146 static int current_card
= 0;
148 static bool last_mmc_status
= false;
149 static int countdown
; /* for mmc switch debouncing */
150 static bool usb_activity
; /* monitoring the USB bridge */
151 static long last_usb_activity
;
153 /* private function declarations */
155 static int select_card(int card_no
);
156 static void deselect_card(void);
157 static void setup_sci1(int bitrate_register
);
158 static void set_sci1_poll_read(void);
159 static void write_transfer(const unsigned char *buf
, int len
)
160 __attribute__ ((section(".icode")));
161 static void read_transfer(unsigned char *buf
, int len
)
162 __attribute__ ((section(".icode")));
163 static unsigned char poll_byte(long timeout
);
164 static unsigned char poll_busy(long timeout
);
165 static int send_cmd(int cmd
, unsigned long parameter
, unsigned char *response
);
166 static int receive_cxd(unsigned char *buf
);
167 static int initialize_card(int card_no
);
168 static void bg_copy_swap(void);
169 static int receive_block(unsigned char *inbuf
, int size
, long timeout
);
170 static int send_block(int size
, unsigned char start_token
, long timeout
);
171 static int cache_block(IF_MV2(int drive
,) unsigned long blocknum
,
172 int size
, long timeout
);
173 static void mmc_tick(void);
177 void mmc_enable_int_flash_clock(bool on
)
179 /* Internal flash clock is enabled by setting PA12 high with the new
180 * clock circuit, and by setting it low with the old clock circuit */
181 if (on
^ new_mmc_circuit
)
182 and_b(~0x10, &PADRH
); /* clear clock gate PA12 */
184 or_b(0x10, &PADRH
); /* set clock gate PA12 */
187 static int select_card(int card_no
)
189 mutex_lock(&mmc_mutex
);
191 last_disk_activity
= current_tick
;
193 if (!card_info
[card_no
].initialized
)
195 setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */
196 write_transfer(dummy
, 10); /* allow the card to synchronize */
197 while (!(SSR1
& SCI_TEND
));
200 if (card_no
== 0) /* internal */
201 and_b(~0x04, &PADRH
); /* assert CS */
203 and_b(~0x02, &PADRH
); /* assert CS */
205 if (card_info
[card_no
].initialized
)
207 setup_sci1(card_info
[card_no
].bitrate_register
);
212 return initialize_card(card_no
);
216 static void deselect_card(void)
218 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
219 or_b(0x06, &PADRH
); /* deassert CS (both cards) */
222 mutex_unlock(&mmc_mutex
);
223 last_disk_activity
= current_tick
;
226 static void setup_sci1(int bitrate_register
)
228 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
230 SCR1
= 0; /* disable serial port */
231 SMR1
= SYNC_MODE
; /* no prescale */
232 BRR1
= bitrate_register
;
235 SCR1
= SCI_TE
; /* enable transmitter */
236 serial_mode
= SER_POLL_WRITE
;
239 static void set_sci1_poll_read(void)
241 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
242 SCR1
= 0; /* disable transmitter (& receiver) */
243 SCR1
= (SCI_TE
|SCI_RE
); /* re-enable transmitter & receiver */
244 while (!(SSR1
& SCI_TEND
)); /* wait for SCI init completion (!) */
245 serial_mode
= SER_POLL_READ
;
246 TDR1
= 0xFF; /* send do-nothing while reading */
249 static void write_transfer(const unsigned char *buf
, int len
)
251 const unsigned char *buf_end
= buf
+ len
;
252 register unsigned char data
;
254 if (serial_mode
!= SER_POLL_WRITE
)
256 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
257 SCR1
= 0; /* disable transmitter & receiver */
258 SSR1
= 0; /* clear all flags */
259 SCR1
= SCI_TE
; /* enable transmitter only */
260 serial_mode
= SER_POLL_WRITE
;
263 while (buf
< buf_end
)
265 data
= fliptable
[(signed char)(*buf
++)]; /* bitswap */
266 while (!(SSR1
& SCI_TDRE
)); /* wait for end of transfer */
267 TDR1
= data
; /* write byte */
268 SSR1
= 0; /* start transmitting */
272 /* don't call this with len == 0 */
273 static void read_transfer(unsigned char *buf
, int len
)
275 unsigned char *buf_end
= buf
+ len
- 1;
276 register signed char data
;
278 if (serial_mode
!= SER_POLL_READ
)
279 set_sci1_poll_read();
281 SSR1
= 0; /* start receiving first byte */
282 while (buf
< buf_end
)
284 while (!(SSR1
& SCI_RDRF
)); /* wait for data */
285 data
= RDR1
; /* read byte */
286 SSR1
= 0; /* start receiving */
287 *buf
++ = fliptable
[data
]; /* bitswap */
289 while (!(SSR1
& SCI_RDRF
)); /* wait for last byte */
290 *buf
= fliptable
[(signed char)(RDR1
)]; /* read & bitswap */
293 /* returns 0xFF on timeout, timeout is in bytes */
294 static unsigned char poll_byte(long timeout
)
297 unsigned char data
= 0; /* stop the compiler complaining */
299 if (serial_mode
!= SER_POLL_READ
)
300 set_sci1_poll_read();
304 SSR1
= 0; /* start receiving */
305 while (!(SSR1
& SCI_RDRF
)); /* wait for data */
306 data
= RDR1
; /* read byte */
307 } while ((data
== 0xFF) && (++i
< timeout
));
309 return fliptable
[(signed char)data
];
312 /* returns 0 on timeout, timeout is in bytes */
313 static unsigned char poll_busy(long timeout
)
316 unsigned char data
, dummy
;
318 if (serial_mode
!= SER_POLL_READ
)
319 set_sci1_poll_read();
321 /* get data response */
322 SSR1
= 0; /* start receiving */
323 while (!(SSR1
& SCI_RDRF
)); /* wait for data */
324 data
= fliptable
[(signed char)(RDR1
)]; /* read byte */
326 /* wait until the card is ready again */
329 SSR1
= 0; /* start receiving */
330 while (!(SSR1
& SCI_RDRF
)); /* wait for data */
331 dummy
= RDR1
; /* read byte */
332 } while ((dummy
!= 0xFF) && (++i
< timeout
));
334 return (dummy
== 0xFF) ? data
: 0;
337 /* Send MMC command and get response */
338 static int send_cmd(int cmd
, unsigned long parameter
, unsigned char *response
)
340 unsigned char command
[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 0xFF};
346 command
[1] = (parameter
>> 24) & 0xFF;
347 command
[2] = (parameter
>> 16) & 0xFF;
348 command
[3] = (parameter
>> 8) & 0xFF;
349 command
[4] = parameter
& 0xFF;
352 write_transfer(command
, 7);
354 response
[0] = poll_byte(20);
356 if (response
[0] != 0x00)
358 write_transfer(dummy
, 1);
364 case CMD_SEND_CSD
: /* R1 response, leave open */
366 case CMD_READ_SINGLE_BLOCK
:
367 case CMD_READ_MULTIPLE_BLOCK
:
370 case CMD_SEND_STATUS
: /* R2 response, close with dummy */
371 read_transfer(response
+ 1, 1);
372 write_transfer(dummy
, 1);
375 case CMD_READ_OCR
: /* R3 response, close with dummy */
376 read_transfer(response
+ 1, 4);
377 write_transfer(dummy
, 1);
380 default: /* R1 response, close with dummy */
381 write_transfer(dummy
, 1);
382 break; /* also catches block writes */
388 /* Receive CID/ CSD data (16 bytes) */
389 static int receive_cxd(unsigned char *buf
)
391 if (poll_byte(20) != DT_START_BLOCK
)
393 write_transfer(dummy
, 1);
394 return -1; /* not start of data */
397 read_transfer(buf
, 16);
398 write_transfer(dummy
, 3); /* 2 bytes dontcare crc + 1 byte trailer */
403 static int initialize_card(int card_no
)
406 unsigned char response
[5];
407 tCardInfo
*card
= &card_info
[card_no
];
409 static const char mantissa
[] = { /* *10 */
410 0, 10, 12, 13, 15, 20, 25, 30,
411 35, 40, 45, 50, 55, 60, 70, 80
413 static const int exponent
[] = { /* use varies */
414 1, 10, 100, 1000, 10000, 100000, 1000000,
415 10000000, 100000000, 1000000000
419 mmc_status
= MMC_TOUCHED
;
420 /* switch to SPI mode */
421 send_cmd(CMD_GO_IDLE_STATE
, 0, response
);
422 if (response
[0] != 0x01)
423 return -1; /* error response */
425 /* initialize card */
426 for (i
= 0; i
< 100; i
++) /* timeout 1 sec */
429 if (send_cmd(CMD_SEND_OP_COND
, 0, response
) == 0)
432 if (response
[0] != 0x00)
433 return -2; /* not ready */
435 /* get OCR register */
436 rc
= send_cmd(CMD_READ_OCR
, 0, response
);
439 card
->ocr
= (response
[1] << 24) | (response
[2] << 16)
440 | (response
[3] << 8) | response
[4];
443 if (!(card
->ocr
& 0x00100000)) /* 3.2 .. 3.3 V */
446 /* get CSD register */
447 rc
= send_cmd(CMD_SEND_CSD
, 0, response
);
450 rc
= receive_cxd((unsigned char*)card
->csd
);
454 /* check block sizes */
455 card
->block_exp
= card_extract_bits(card
->csd
, 44, 4);
456 card
->blocksize
= 1 << card
->block_exp
;
457 if ((card_extract_bits(card
->csd
, 102, 4) != card
->block_exp
)
458 || card
->blocksize
> MAX_BLOCK_SIZE
)
463 if (card
->blocksize
!= SECTOR_SIZE
)
465 rc
= send_cmd(CMD_SET_BLOCKLEN
, card
->blocksize
, response
);
470 /* max transmission speed, clock divider */
471 temp
= card_extract_bits(card
->csd
, 29, 3);
472 temp
= (temp
> 3) ? 3 : temp
;
473 card
->speed
= mantissa
[card_extract_bits(card
->csd
, 25, 4)]
474 * exponent
[temp
+ 4];
475 card
->bitrate_register
= (FREQ
/4-1) / card
->speed
;
477 /* NSAC, TSAC, read timeout */
478 card
->nsac
= 100 * card_extract_bits(card
->csd
, 16, 8);
479 card
->tsac
= mantissa
[card_extract_bits(card
->csd
, 9, 4)];
480 temp
= card_extract_bits(card
->csd
, 13, 3);
481 card
->read_timeout
= ((FREQ
/4) / (card
->bitrate_register
+ 1)
482 * card
->tsac
/ exponent
[9 - temp
]
483 + (10 * card
->nsac
));
484 card
->read_timeout
/= 8; /* clocks -> bytes */
485 card
->tsac
= card
->tsac
* exponent
[temp
] / 10;
487 /* r2w_factor, write timeout */
488 card
->r2w_factor
= 1 << card_extract_bits(card
->csd
, 99, 3);
489 if (card
->r2w_factor
> 32) /* dirty MMC spec violation */
491 card
->read_timeout
*= 4; /* add safety factor */
492 card
->write_timeout
= card
->read_timeout
* 8;
495 card
->write_timeout
= card
->read_timeout
* card
->r2w_factor
;
498 card
->numblocks
= (card_extract_bits(card
->csd
, 54, 12) + 1)
499 * (1 << (card_extract_bits(card
->csd
, 78, 3) + 2));
500 card
->size
= card
->numblocks
* card
->blocksize
;
502 /* switch to full speed */
503 setup_sci1(card
->bitrate_register
);
505 /* get CID register */
506 rc
= send_cmd(CMD_SEND_CID
, 0, response
);
509 rc
= receive_cxd((unsigned char*)card
->cid
);
513 card
->initialized
= true;
517 tCardInfo
*mmc_card_info(int card_no
)
519 tCardInfo
*card
= &card_info
[card_no
];
521 if (!card
->initialized
&& ((card_no
== 0) || mmc_detect()))
523 select_card(card_no
);
529 /* copy and swap in the background. If destination is NULL, use the next
530 * block cache entry */
531 static void bg_copy_swap(void)
538 current_cache
= (current_cache
+ 1) % NUMCACHES
; /* next cache */
539 block_cache
[current_cache
].inuse
= false;
540 bcs_dest
= block_cache
[current_cache
].data
+ 2;
544 memcpy(bcs_dest
, bcs_src
, bcs_len
);
547 bitswap(bcs_dest
, bcs_len
);
552 /* Receive one block with dma, possibly swapping the previously received
553 * block in the background */
554 static int receive_block(unsigned char *inbuf
, int size
, long timeout
)
556 if (poll_byte(timeout
) != DT_START_BLOCK
)
558 write_transfer(dummy
, 1);
559 return -1; /* not start of data */
562 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
564 SCR1
= 0; /* disable serial */
565 SSR1
= 0; /* clear all flags */
567 /* setup DMA channel 0 */
568 CHCR0
= 0; /* disable */
570 DAR0
= (unsigned long) inbuf
;
572 CHCR0
= 0x4601; /* fixed source address, RXI1, enable */
574 SCR1
= (SCI_RE
|SCI_RIE
); /* kick off DMA */
576 /* dma receives 2 bytes more than DTCR2, but the last 2 bytes are not
577 * stored. The first extra byte is available from RDR1 after the DMA ends,
578 * the second one is lost because of the SCI overrun. However, this
579 * behaviour conveniently discards the crc. */
582 yield(); /* be nice */
584 while (!(CHCR0
& 0x0002)); /* wait for end of DMA */
585 while (!(SSR1
& SCI_ORER
)); /* wait for the trailing bytes */
587 serial_mode
= SER_DISABLED
;
589 write_transfer(dummy
, 1); /* send trailer */
590 last_disk_activity
= current_tick
;
594 /* Send one block with dma from the current block cache, possibly preparing
595 * the next block within the next block cache in the background. */
596 static int send_block(int size
, unsigned char start_token
, long timeout
)
599 unsigned char *curbuf
= block_cache
[current_cache
].data
;
601 curbuf
[1] = fliptable
[(signed char)start_token
];
602 *(unsigned short *)(curbuf
+ size
+ 2) = 0xFFFF;
604 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
606 SCR1
= 0; /* disable serial */
607 SSR1
= 0; /* clear all flags */
609 /* setup DMA channel 0 */
610 CHCR0
= 0; /* disable */
611 SAR0
= (unsigned long)(curbuf
+ 1);
613 DTCR0
= size
+ 3; /* start token + block + dummy crc */
614 CHCR0
= 0x1701; /* fixed dest. address, TXI1, enable */
616 SCR1
= (SCI_TE
|SCI_TIE
); /* kick off DMA */
619 yield(); /* be nice */
621 while (!(CHCR0
& 0x0002)); /* wait for end of DMA */
622 while (!(SSR1
& SCI_TEND
)); /* wait for end of transfer */
624 serial_mode
= SER_DISABLED
;
626 if ((poll_busy(timeout
) & 0x1F) != 0x05) /* something went wrong */
629 write_transfer(dummy
, 1);
630 last_disk_activity
= current_tick
;
635 static int cache_block(IF_MV2(int drive
,) unsigned long blocknum
,
636 int size
, long timeout
)
639 unsigned char response
;
641 /* check whether the block is already cached */
642 for (i
= 0; i
< NUMCACHES
; i
++)
644 if (block_cache
[i
].inuse
&& (block_cache
[i
].blocknum
== blocknum
)
645 #ifdef HAVE_MULTIVOLUME
646 && (block_cache
[i
].drive
== drive
)
655 /* not found: read the block */
656 current_cache
= (current_cache
+ 1) % NUMCACHES
;
657 rc
= send_cmd(CMD_READ_SINGLE_BLOCK
, blocknum
* size
, &response
);
661 block_cache
[current_cache
].inuse
= false;
662 rc
= receive_block(block_cache
[current_cache
].data
+ 2, size
, timeout
);
666 #ifdef HAVE_MULTIVOLUME
667 block_cache
[current_cache
].drive
= drive
;
669 block_cache
[current_cache
].blocknum
= blocknum
;
670 block_cache
[current_cache
].inuse
= true;
675 int ata_read_sectors(IF_MV2(int drive
,)
681 unsigned int blocksize
, offset
;
682 unsigned long c_addr
, c_end_addr
;
683 unsigned long c_block
, c_end_block
;
684 unsigned char response
;
686 #ifndef HAVE_MULTIVOLUME
687 int drive
= current_card
;
690 c_addr
= start
* SECTOR_SIZE
;
691 c_end_addr
= c_addr
+ incount
* SECTOR_SIZE
;
693 card
= &card_info
[drive
];
694 rc
= select_card(drive
);
700 if (c_end_addr
> card
->size
)
706 blocksize
= card
->blocksize
;
707 offset
= c_addr
& (blocksize
- 1);
708 c_block
= c_addr
>> card
->block_exp
;
709 c_end_block
= c_end_addr
>> card
->block_exp
;
712 if (offset
) /* first partial block */
714 unsigned long len
= MIN(c_end_addr
- c_addr
, blocksize
- offset
);
716 rc
= cache_block(IF_MV2(drive
,) c_block
, blocksize
,
723 bcs_src
= block_cache
[current_cache
].data
+ 2 + offset
;
729 /* some cards don't like reading the very last block with
730 * CMD_READ_MULTIPLE_BLOCK, so make sure this block is always
731 * read with CMD_READ_SINGLE_BLOCK. Let the 'last partial block'
732 * read catch this. */
733 if (c_end_block
== card
->numblocks
)
736 if (c_block
< c_end_block
)
738 int read_cmd
= (c_end_block
- c_block
> 1) ?
739 CMD_READ_MULTIPLE_BLOCK
: CMD_READ_SINGLE_BLOCK
;
741 rc
= send_cmd(read_cmd
, c_addr
, &response
);
747 while (c_block
< c_end_block
)
749 rc
= receive_block(inbuf
, blocksize
, card
->read_timeout
);
761 if (read_cmd
== CMD_READ_MULTIPLE_BLOCK
)
763 rc
= send_cmd(CMD_STOP_TRANSMISSION
, 0, &response
);
771 if (c_addr
< c_end_addr
) /* last partial block */
773 rc
= cache_block(IF_MV2(drive
,) c_block
, blocksize
,
780 bcs_src
= block_cache
[current_cache
].data
+ 2;
781 bcs_len
= c_end_addr
- c_addr
;
792 int ata_write_sectors(IF_MV2(int drive
,)
798 unsigned int blocksize
, offset
;
799 unsigned long c_addr
, c_end_addr
;
800 unsigned long c_block
, c_end_block
;
801 unsigned char response
;
803 #ifndef HAVE_MULTIVOLUME
804 int drive
= current_card
;
807 c_addr
= start
* SECTOR_SIZE
;
808 c_end_addr
= c_addr
+ count
* SECTOR_SIZE
;
810 card
= &card_info
[drive
];
811 rc
= select_card(drive
);
818 if (c_end_addr
> card
->size
)
819 panicf("Writing past end of card");
821 blocksize
= card
->blocksize
;
822 offset
= c_addr
& (blocksize
- 1);
823 c_block
= c_addr
>> card
->block_exp
;
824 c_end_block
= c_end_addr
>> card
->block_exp
;
827 /* Special case: first block is trimmed at both ends. May only happen
828 * if (blocksize > 2 * sectorsize), i.e. blocksize == 2048 */
829 if ((c_block
== c_end_block
) && offset
)
832 if (c_block
< c_end_block
)
835 unsigned char start_token
;
837 if (c_end_block
- c_block
> 1)
839 write_cmd
= CMD_WRITE_MULTIPLE_BLOCK
;
840 start_token
= DT_START_WRITE_MULTIPLE
;
844 write_cmd
= CMD_WRITE_BLOCK
;
845 start_token
= DT_START_BLOCK
;
850 unsigned long len
= MIN(c_end_addr
- c_addr
, blocksize
- offset
);
852 rc
= cache_block(IF_MV2(drive
,) c_block
, blocksize
,
859 bcs_dest
= block_cache
[current_cache
].data
+ 2 + offset
;
865 bcs_dest
= NULL
; /* next block cache */
869 rc
= send_cmd(write_cmd
, c_addr
, &response
);
875 c_block
++; /* early increment to simplify the loop */
877 while (c_block
< c_end_block
)
879 bcs_dest
= NULL
; /* next block cache */
881 rc
= send_block(blocksize
, start_token
, card
->write_timeout
);
890 rc
= send_block(blocksize
, start_token
, card
->write_timeout
);
897 /* c_block++ was done early */
899 if (write_cmd
== CMD_WRITE_MULTIPLE_BLOCK
)
901 response
= DT_STOP_TRAN
;
902 write_transfer(&response
, 1);
903 poll_busy(card
->write_timeout
);
907 if (c_addr
< c_end_addr
) /* last partial block */
909 rc
= cache_block(IF_MV2(drive
,) c_block
, blocksize
,
916 bcs_dest
= block_cache
[current_cache
].data
+ 2;
917 bcs_len
= c_end_addr
- c_addr
;
919 rc
= send_cmd(CMD_WRITE_BLOCK
, c_addr
, &response
);
925 rc
= send_block(blocksize
, DT_START_BLOCK
, card
->write_timeout
);
940 void ata_spindown(int seconds
)
945 bool ata_disk_is_active(void)
947 /* this is correct unless early return from write gets implemented */
948 return mmc_mutex
.locked
;
959 static void mmc_thread(void)
961 struct queue_event ev
;
962 bool idle_notified
= false;
965 queue_wait_w_tmo(&mmc_queue
, &ev
, HZ
);
968 case SYS_USB_CONNECTED
:
969 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
970 /* Wait until the USB cable is extracted again */
971 usb_wait_for_disconnect(&mmc_queue
);
975 case SYS_HOTSWAP_INSERTED
:
976 disk_mount(1); /* mount MMC */
977 queue_broadcast(SYS_FS_CHANGED
, 0);
980 case SYS_HOTSWAP_EXTRACTED
:
981 disk_unmount(1); /* release "by force" */
982 queue_broadcast(SYS_FS_CHANGED
, 0);
987 if (TIME_BEFORE(current_tick
, last_disk_activity
+(3*HZ
)))
989 idle_notified
= false;
995 call_ata_idle_notifys(false);
996 idle_notified
= true;
1005 void mmc_enable_monitoring(bool on
)
1007 mmc_monitor_enabled
= on
;
1011 bool mmc_detect(void)
1013 return adc_read(ADC_MMC_SWITCH
) < 0x200 ? true : false;
1016 bool mmc_touched(void)
1018 if (mmc_status
== MMC_UNKNOWN
) /* try to detect */
1020 unsigned char response
;
1022 mutex_lock(&mmc_mutex
);
1023 setup_sci1(7); /* safe value */
1024 and_b(~0x02, &PADRH
); /* assert CS */
1025 send_cmd(CMD_SEND_OP_COND
, 0, &response
);
1026 if (response
== 0xFF)
1027 mmc_status
= MMC_UNTOUCHED
;
1029 mmc_status
= MMC_TOUCHED
;
1033 return mmc_status
== MMC_TOUCHED
;
1036 bool mmc_usb_active(int delayticks
)
1038 /* reading "inactive" is delayed by user-supplied monoflop value */
1039 return (usb_activity
||
1040 TIME_BEFORE(current_tick
, last_usb_activity
+ delayticks
));
1043 static void mmc_tick(void)
1045 bool current_status
;
1046 #ifndef HAVE_HOTSWAP
1047 const bool mmc_monitor_enabled
= true;
1050 if (new_mmc_circuit
)
1051 /* USB bridge activity is 0 on idle, ~527 on active */
1052 current_status
= adc_read(ADC_USB_ACTIVE
) > 0x100;
1054 current_status
= adc_read(ADC_USB_ACTIVE
) < 0x190;
1056 if (!current_status
&& usb_activity
)
1057 last_usb_activity
= current_tick
;
1058 usb_activity
= current_status
;
1060 if (mmc_monitor_enabled
)
1062 current_status
= mmc_detect();
1063 /* Only report when the status has changed */
1064 if (current_status
!= last_mmc_status
)
1066 last_mmc_status
= current_status
;
1071 /* Count down until it gets negative */
1079 queue_broadcast(SYS_HOTSWAP_INSERTED
, 0);
1083 queue_broadcast(SYS_HOTSWAP_EXTRACTED
, 0);
1084 mmc_status
= MMC_UNTOUCHED
;
1085 card_info
[1].initialized
= false;
1092 int ata_soft_reset(void)
1097 void ata_enable(bool on
)
1099 PBCR1
&= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */
1100 PACR2
&= ~0x4000; /* use PA7 (bridge reset) as GPIO */
1103 PBCR1
|= 0x08A0; /* as SCK1, TxD1, RxD1 */
1104 IPRE
&= 0x0FFF; /* disable SCI1 interrupts for the CPU */
1105 mmc_enable_int_flash_clock(true); /* always enabled in SPI mode */
1107 and_b(~0x80, &PADRL
); /* assert reset */
1109 or_b(0x80, &PADRL
); /* de-assert reset */
1111 card_info
[0].initialized
= false;
1112 card_info
[1].initialized
= false;
1121 mutex_init(&mmc_mutex
);
1122 queue_init(&mmc_queue
, true);
1124 mutex_lock(&mmc_mutex
);
1128 PACR1
&= ~0x0F00; /* GPIO function for PA12, /IRQ1 for PA13 */
1130 PADR
|= 0x0680; /* set all the selects + reset high (=inactive) */
1131 PAIOR
|= 0x1680; /* make outputs for them and the PA12 clock gate */
1133 PBDR
|= 0x2C00; /* SCK1, TxD1 and RxD1 high when GPIO CHECKME: mask */
1134 PBIOR
|= 0x2000; /* SCK1 output */
1135 PBIOR
&= ~0x0C00; /* TxD1, RxD1 input */
1137 last_mmc_status
= mmc_detect();
1138 #ifndef HAVE_MULTIVOLUME
1139 if (last_mmc_status
)
1140 { /* MMC inserted */
1144 { /* no MMC, use internal memory */
1149 new_mmc_circuit
= ((HW_MASK
& MMC_CLOCK_POLARITY
) != 0);
1154 if (!last_mmc_status
)
1155 mmc_status
= MMC_UNTOUCHED
;
1157 create_thread(mmc_thread
, mmc_stack
,
1158 sizeof(mmc_stack
), 0, mmc_thread_name
1159 IF_PRIO(, PRIORITY_SYSTEM
)
1161 tick_add_task(mmc_tick
);
1165 mutex_unlock(&mmc_mutex
);