summaryrefslogtreecommitdiff
path: root/firmware/target/sh/archos/ondio/ata_mmc.c
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-07-15 19:40:55 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-07-24 21:20:13 +0000
commit092c340a2062fa98b7387fc5fd63578ddae7d0b6 (patch)
tree98ec96946eeb2ae709cb0528cc6998e21bb9b290 /firmware/target/sh/archos/ondio/ata_mmc.c
parent17f7cc92c258bc456a27c3e7c5a19c9409851879 (diff)
downloadrockbox-092c340a2062fa98b7387fc5fd63578ddae7d0b6.tar.gz
rockbox-092c340a2062fa98b7387fc5fd63578ddae7d0b6.zip
[1/4] Remove SH support and all archos targets
This removes all code specific to SH targets Change-Id: I7980523785d2596e65c06430f4638eec74a06061
Diffstat (limited to 'firmware/target/sh/archos/ondio/ata_mmc.c')
-rw-r--r--firmware/target/sh/archos/ondio/ata_mmc.c978
1 files changed, 0 insertions, 978 deletions
diff --git a/firmware/target/sh/archos/ondio/ata_mmc.c b/firmware/target/sh/archos/ondio/ata_mmc.c
deleted file mode 100644
index f252e1c4ce..0000000000
--- a/firmware/target/sh/archos/ondio/ata_mmc.c
+++ /dev/null
@@ -1,978 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2004 by Jens Arnold
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "ata_mmc.h"
23#include "sdmmc.h"
24#include "kernel.h"
25#include "led.h"
26#include "sh7034.h"
27#include "system.h"
28#include "debug.h"
29#include "panic.h"
30#include "power.h"
31#include "string.h"
32#include "hwcompat.h"
33#include "adc.h"
34#include "bitswap.h"
35#include "storage.h"
36
37
38#ifdef HAVE_MULTIDRIVE
39#define MMC_NUM_DRIVES 2
40#else
41#define MMC_NUM_DRIVES 1
42#endif
43
44#define BLOCK_SIZE 512 /* fixed */
45
46/* Command definitions */
47#define CMD_GO_IDLE_STATE 0x40 /* R1 */
48#define CMD_SEND_OP_COND 0x41 /* R1 */
49#define CMD_SEND_CSD 0x49 /* R1 */
50#define CMD_SEND_CID 0x4a /* R1 */
51#define CMD_STOP_TRANSMISSION 0x4c /* R1 */
52#define CMD_SEND_STATUS 0x4d /* R2 */
53#define CMD_SET_BLOCKLEN 0x50 /* R1 */
54#define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */
55#define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */
56#define CMD_WRITE_BLOCK 0x58 /* R1b */
57#define CMD_WRITE_MULTIPLE_BLOCK 0x59 /* R1b */
58#define CMD_READ_OCR 0x7a /* R3 */
59
60/* Response formats:
61 R1 = single byte, msb=0, various error flags
62 R1b = R1 + busy token(s)
63 R2 = 2 bytes (1st byte identical to R1), additional flags
64 R3 = 5 bytes (R1 + OCR register)
65*/
66
67#define R1_PARAMETER_ERR 0x40
68#define R1_ADDRESS_ERR 0x20
69#define R1_ERASE_SEQ_ERR 0x10
70#define R1_COM_CRC_ERR 0x08
71#define R1_ILLEGAL_CMD 0x04
72#define R1_ERASE_RESET 0x02
73#define R1_IN_IDLE_STATE 0x01
74
75#define R2_OUT_OF_RANGE 0x80
76#define R2_ERASE_PARAM 0x40
77#define R2_WP_VIOLATION 0x20
78#define R2_CARD_ECC_FAIL 0x10
79#define R2_CC_ERROR 0x08
80#define R2_ERROR 0x04
81#define R2_ERASE_SKIP 0x02
82#define R2_CARD_LOCKED 0x01
83
84/* Data start tokens */
85
86#define DT_START_BLOCK 0xfe
87#define DT_START_WRITE_MULTIPLE 0xfc
88#define DT_STOP_TRAN 0xfd
89
90/* for compatibility */
91static long last_disk_activity = -1;
92
93/* private variables */
94
95#ifdef CONFIG_STORAGE_MULTI
96static int mmc_first_drive = 0;
97#else
98#define mmc_first_drive 0
99#endif
100
101static struct mutex mmc_mutex SHAREDBSS_ATTR;
102
103static bool initialized = false;
104static bool new_mmc_circuit;
105
106static enum {
107 MMC_UNKNOWN,
108 MMC_UNTOUCHED,
109 MMC_TOUCHED
110} mmc_status = MMC_UNKNOWN;
111
112static enum {
113 SER_POLL_WRITE,
114 SER_POLL_READ,
115 SER_DISABLED
116} serial_mode;
117
118static const unsigned char dummy[] = {
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
120};
121
122/* 2 buffers used alternatively for writing, including start token,
123 * dummy CRC and an extra byte to keep word alignment. */
124static unsigned char write_buffer[2][BLOCK_SIZE+4];
125static int current_buffer = 0;
126static const unsigned char *send_block_addr = NULL;
127
128static tCardInfo card_info[2];
129#ifndef HAVE_MULTIDRIVE
130static int current_card = 0;
131#endif
132static bool last_mmc_status = false;
133static int countdown = -1; /* for mmc switch debouncing. -1 because the
134 countdown should not happen if the card
135 is inserted at boot */
136static bool usb_activity; /* monitoring the USB bridge */
137static long last_usb_activity;
138
139/* private function declarations */
140
141static int select_card(int card_no);
142static void deselect_card(void);
143static void setup_sci1(int bitrate_register);
144static void set_sci1_poll_read(void);
145static void write_transfer(const unsigned char *buf, int len)
146 __attribute__ ((section(".icode")));
147static void read_transfer(unsigned char *buf, int len)
148 __attribute__ ((section(".icode")));
149static unsigned char poll_byte(long timeout);
150static unsigned char poll_busy(long timeout);
151static unsigned char send_cmd(int cmd, unsigned long parameter, void *data);
152static int receive_cxd(unsigned char *buf);
153static int initialize_card(int card_no);
154static int receive_block(unsigned char *inbuf, long timeout);
155static void send_block_prepare(void);
156static int send_block_send(unsigned char start_token, long timeout,
157 bool prepare_next);
158static void mmc_tick(void);
159
160/* implementation */
161
162static void enable_controller(bool on)
163{
164 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
165 * if not modified below */
166 if (on)
167 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
168
169 and_b(~0x80, &PADRL); /* assert flash reset */
170 sleep(HZ/100);
171 or_b(0x80, &PADRL); /* de-assert flash reset */
172 sleep(HZ/100);
173 card_info[0].initialized = false;
174 card_info[1].initialized = false;
175}
176
177void mmc_enable_int_flash_clock(bool on)
178{
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 */
183 else
184 or_b(0x10, &PADRH); /* set clock gate PA12 */
185}
186
187static int select_card(int card_no)
188{
189 mutex_lock(&mmc_mutex);
190 led(true);
191 last_disk_activity = current_tick;
192
193 mmc_enable_int_flash_clock(card_no == 0);
194
195 if (!card_info[card_no].initialized)
196 {
197 setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */
198 write_transfer(dummy, 10); /* allow the card to synchronize */
199 while (!(SSR1 & SCI_TEND));
200 }
201
202 if (card_no == 0) /* internal */
203 and_b(~0x04, &PADRH); /* assert CS */
204 else /* external */
205 and_b(~0x02, &PADRH); /* assert CS */
206
207 if (card_info[card_no].initialized)
208 {
209 setup_sci1(card_info[card_no].bitrate_register);
210 return 0;
211 }
212 else
213 {
214 return initialize_card(card_no);
215 }
216}
217
218static void deselect_card(void)
219{
220 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
221 or_b(0x06, &PADRH); /* deassert CS (both cards) */
222
223 led(false);
224 mutex_unlock(&mmc_mutex);
225 last_disk_activity = current_tick;
226}
227
228static void setup_sci1(int bitrate_register)
229{
230 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
231
232 SCR1 = 0; /* disable serial port */
233 SMR1 = SYNC_MODE; /* no prescale */
234 BRR1 = bitrate_register;
235 SSR1 = 0;
236
237 SCR1 = SCI_TE; /* enable transmitter */
238 serial_mode = SER_POLL_WRITE;
239}
240
241static void set_sci1_poll_read(void)
242{
243 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
244 SCR1 = 0; /* disable transmitter (& receiver) */
245 SCR1 = (SCI_TE|SCI_RE); /* re-enable transmitter & receiver */
246 while (!(SSR1 & SCI_TEND)); /* wait for SCI init completion (!) */
247 serial_mode = SER_POLL_READ;
248 TDR1 = 0xFF; /* send do-nothing while reading */
249}
250
251static void write_transfer(const unsigned char *buf, int len)
252{
253 const unsigned char *buf_end = buf + len;
254 register unsigned char data;
255
256 if (serial_mode != SER_POLL_WRITE)
257 {
258 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
259 SCR1 = 0; /* disable transmitter & receiver */
260 SSR1 = 0; /* clear all flags */
261 SCR1 = SCI_TE; /* enable transmitter only */
262 serial_mode = SER_POLL_WRITE;
263 }
264
265 while (buf < buf_end)
266 {
267 data = fliptable[(signed char)(*buf++)]; /* bitswap */
268 while (!(SSR1 & SCI_TDRE)); /* wait for end of transfer */
269 TDR1 = data; /* write byte */
270 SSR1 = 0; /* start transmitting */
271 }
272}
273
274/* don't call this with len == 0 */
275static void read_transfer(unsigned char *buf, int len)
276{
277 unsigned char *buf_end = buf + len - 1;
278 register signed char data;
279
280 if (serial_mode != SER_POLL_READ)
281 set_sci1_poll_read();
282
283 SSR1 = 0; /* start receiving first byte */
284 while (buf < buf_end)
285 {
286 while (!(SSR1 & SCI_RDRF)); /* wait for data */
287 data = RDR1; /* read byte */
288 SSR1 = 0; /* start receiving */
289 *buf++ = fliptable[data]; /* bitswap */
290 }
291 while (!(SSR1 & SCI_RDRF)); /* wait for last byte */
292 *buf = fliptable[(signed char)(RDR1)]; /* read & bitswap */
293}
294
295/* returns 0xFF on timeout, timeout is in bytes */
296static unsigned char poll_byte(long timeout)
297{
298 long i;
299 unsigned char data = 0; /* stop the compiler complaining */
300
301 if (serial_mode != SER_POLL_READ)
302 set_sci1_poll_read();
303
304 i = 0;
305 do {
306 SSR1 = 0; /* start receiving */
307 while (!(SSR1 & SCI_RDRF)); /* wait for data */
308 data = RDR1; /* read byte */
309 } while ((data == 0xFF) && (++i < timeout));
310
311 return fliptable[(signed char)data];
312}
313
314/* returns 0 on timeout, timeout is in bytes */
315static unsigned char poll_busy(long timeout)
316{
317 long i;
318 unsigned char data, dummy;
319
320 if (serial_mode != SER_POLL_READ)
321 set_sci1_poll_read();
322
323 /* get data response */
324 SSR1 = 0; /* start receiving */
325 while (!(SSR1 & SCI_RDRF)); /* wait for data */
326 data = fliptable[(signed char)(RDR1)]; /* read byte */
327
328 /* wait until the card is ready again */
329 i = 0;
330 do {
331 SSR1 = 0; /* start receiving */
332 while (!(SSR1 & SCI_RDRF)); /* wait for data */
333 dummy = RDR1; /* read byte */
334 } while ((dummy != 0xFF) && (++i < timeout));
335
336 return (dummy == 0xFF) ? data : 0;
337}
338
339/* Send MMC command and get response. Returns R1 byte directly.
340 * Returns further R2 or R3 bytes in *data (can be NULL for other commands) */
341static unsigned char send_cmd(int cmd, unsigned long parameter, void *data)
342{
343 static struct {
344 unsigned char cmd;
345 unsigned long parameter;
346 const unsigned char crc7; /* fixed, valid for CMD0 only */
347 const unsigned char trailer;
348 } __attribute__((packed)) command = {0x40, 0, 0x95, 0xFF};
349
350 unsigned char ret;
351
352 command.cmd = cmd;
353 command.parameter = htobe32(parameter);
354
355 write_transfer((unsigned char *)&command, sizeof(command));
356
357 ret = poll_byte(20);
358
359 switch (cmd)
360 {
361 case CMD_SEND_CSD: /* R1 response, leave open */
362 case CMD_SEND_CID:
363 case CMD_READ_SINGLE_BLOCK:
364 case CMD_READ_MULTIPLE_BLOCK:
365 return ret;
366
367 case CMD_SEND_STATUS: /* R2 response, close with dummy */
368 read_transfer(data, 1);
369 break;
370
371 case CMD_READ_OCR: /* R3 response, close with dummy */
372 read_transfer(data, 4);
373 break;
374
375 default: /* R1 response, close with dummy */
376 break; /* also catches block writes */
377 }
378 write_transfer(dummy, 1);
379 return ret;
380}
381
382/* Receive CID/ CSD data (16 bytes) */
383static int receive_cxd(unsigned char *buf)
384{
385 if (poll_byte(20) != DT_START_BLOCK)
386 {
387 write_transfer(dummy, 1);
388 return -1; /* not start of data */
389 }
390
391 read_transfer(buf, 16);
392 write_transfer(dummy, 3); /* 2 bytes dontcare crc + 1 byte trailer */
393 return 0;
394}
395
396
397static int initialize_card(int card_no)
398{
399 int rc, i;
400 int blk_exp, ts_exp, taac_exp;
401 tCardInfo *card = &card_info[card_no];
402
403 static const char mantissa[] = { /* *10 */
404 0, 10, 12, 13, 15, 20, 25, 30,
405 35, 40, 45, 50, 55, 60, 70, 80
406 };
407 static const int exponent[] = { /* use varies */
408 1, 10, 100, 1000, 10000, 100000, 1000000,
409 10000000, 100000000, 1000000000
410 };
411
412 if (card_no == 1)
413 mmc_status = MMC_TOUCHED;
414
415 /* switch to SPI mode */
416 if (send_cmd(CMD_GO_IDLE_STATE, 0, NULL) != 0x01)
417 return -1; /* error or no response */
418
419 /* initialize card */
420 for (i = HZ;;) /* try for 1 second*/
421 {
422 sleep(1);
423 if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0)
424 break;
425 if (--i <= 0)
426 return -2; /* timeout */
427 }
428
429 /* get OCR register */
430 if (send_cmd(CMD_READ_OCR, 0, &card->ocr))
431 return -3;
432 card->ocr = betoh32(card->ocr); /* no-op on big endian */
433
434 /* check voltage */
435 if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */
436 return -4;
437
438 /* get CSD register */
439 if (send_cmd(CMD_SEND_CSD, 0, NULL))
440 return -5;
441 rc = receive_cxd((unsigned char*)card->csd);
442 if (rc)
443 return rc * 10 - 5;
444
445 blk_exp = card_extract_bits(card->csd, 83, 4);
446 if (blk_exp < 9) /* block size < 512 bytes not supported */
447 return -6;
448
449 card->numblocks = (card_extract_bits(card->csd, 73, 12) + 1)
450 << (card_extract_bits(card->csd, 49, 3) + 2 + blk_exp - 9);
451 card->blocksize = BLOCK_SIZE;
452
453 /* max transmission speed, clock divider */
454 ts_exp = card_extract_bits(card->csd, 98, 3);
455 ts_exp = (ts_exp > 3) ? 3 : ts_exp;
456 card->speed = mantissa[card_extract_bits(card->csd, 102, 4)]
457 * exponent[ts_exp + 4];
458 card->bitrate_register = (FREQ/4-1) / card->speed;
459
460 /* NSAC, TAAC, read timeout */
461 card->nsac = 100 * card_extract_bits(card->csd, 111, 8);
462 card->taac = mantissa[card_extract_bits(card->csd, 118, 4)];
463 taac_exp = card_extract_bits(card->csd, 114, 3);
464 card->read_timeout = ((FREQ/4) / (card->bitrate_register + 1)
465 * card->taac / exponent[9 - taac_exp]
466 + (10 * card->nsac));
467 card->read_timeout /= 8; /* clocks -> bytes */
468 card->taac = card->taac * exponent[taac_exp] / 10;
469
470 /* r2w_factor, write timeout */
471 card->r2w_factor = BIT_N(card_extract_bits(card->csd, 28, 3));
472 card->write_timeout = card->read_timeout * card->r2w_factor;
473
474 if (card->r2w_factor > 32) /* Such cards often need extra read delay */
475 card->read_timeout *= 4;
476
477 /* switch to full speed */
478 setup_sci1(card->bitrate_register);
479
480 /* always use 512 byte blocks */
481 if (send_cmd(CMD_SET_BLOCKLEN, BLOCK_SIZE, NULL))
482 return -7;
483
484 /* get CID register */
485 if (send_cmd(CMD_SEND_CID, 0, NULL))
486 return -8;
487 rc = receive_cxd((unsigned char*)card->cid);
488 if (rc)
489 return rc * 10 - 8;
490
491 card->initialized = true;
492 return 0;
493}
494
495tCardInfo *mmc_card_info(int card_no)
496{
497 tCardInfo *card = &card_info[card_no];
498
499 if (!card->initialized && ((card_no == 0) || mmc_detect()))
500 {
501 select_card(card_no);
502 deselect_card();
503 }
504 return card;
505}
506
507/* Receive one block with DMA and bitswap it (chasing bitswap). */
508static int receive_block(unsigned char *inbuf, long timeout)
509{
510 unsigned long buf_end;
511
512 if (poll_byte(timeout) != DT_START_BLOCK)
513 {
514 write_transfer(dummy, 1);
515 return -1; /* not start of data */
516 }
517
518 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
519
520 SCR1 = 0; /* disable serial */
521 SSR1 = 0; /* clear all flags */
522
523 /* setup DMA channel 0 */
524 CHCR0 = 0; /* disable */
525 SAR0 = RDR1_ADDR;
526 DAR0 = (unsigned long) inbuf;
527 DTCR0 = BLOCK_SIZE;
528 CHCR0 = 0x4601; /* fixed source address, RXI1, enable */
529 DMAOR = 0x0001;
530 SCR1 = (SCI_RE|SCI_RIE); /* kick off DMA */
531
532 /* DMA receives 2 bytes more than DTCR2, but the last 2 bytes are not
533 * stored. The first extra byte is available from RDR1 after the DMA ends,
534 * the second one is lost because of the SCI overrun. However, this
535 * behaviour conveniently discards the crc. */
536
537 yield(); /* be nice */
538
539 /* Bitswap received data, chasing the DMA pointer */
540 buf_end = (unsigned long)inbuf + BLOCK_SIZE;
541 do
542 {
543 /* Call bitswap whenever (a multiple of) 8 bytes are
544 * available (value optimised by experimentation). */
545 int swap_now = (DAR0 - (unsigned long)inbuf) & ~0x00000007;
546 if (swap_now)
547 {
548 bitswap(inbuf, swap_now);
549 inbuf += swap_now;
550 }
551 }
552 while ((unsigned long)inbuf < buf_end);
553
554 while (!(CHCR0 & 0x0002)); /* wait for end of DMA */
555 while (!(SSR1 & SCI_ORER)); /* wait for the trailing bytes */
556 SCR1 = 0;
557 serial_mode = SER_DISABLED;
558
559 write_transfer(dummy, 1); /* send trailer */
560 last_disk_activity = current_tick;
561 return 0;
562}
563
564/* Prepare a block for sending by copying it to the next write buffer
565 * and bitswapping it. */
566static void send_block_prepare(void)
567{
568 unsigned char *dest;
569
570 current_buffer ^= 1; /* toggle buffer */
571 dest = write_buffer[current_buffer] + 2;
572
573 memcpy(dest, send_block_addr, BLOCK_SIZE);
574 bitswap(dest, BLOCK_SIZE);
575
576 send_block_addr += BLOCK_SIZE;
577}
578
579/* Send one block with DMA from the current write buffer, possibly preparing
580 * the next block within the next write buffer in the background. */
581static int send_block_send(unsigned char start_token, long timeout,
582 bool prepare_next)
583{
584 int rc = 0;
585 unsigned char *curbuf = write_buffer[current_buffer];
586
587 curbuf[1] = fliptable[(signed char)start_token];
588 *(unsigned short *)(curbuf + BLOCK_SIZE + 2) = 0xFFFF;
589
590 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
591
592 SCR1 = 0; /* disable serial */
593 SSR1 = 0; /* clear all flags */
594
595 /* setup DMA channel 0 */
596 CHCR0 = 0; /* disable */
597 SAR0 = (unsigned long)(curbuf + 1);
598 DAR0 = TDR1_ADDR;
599 DTCR0 = BLOCK_SIZE + 3; /* start token + block + dummy crc */
600 CHCR0 = 0x1701; /* fixed dest. address, TXI1, enable */
601 DMAOR = 0x0001;
602 SCR1 = (SCI_TE|SCI_TIE); /* kick off DMA */
603
604 if (prepare_next)
605 send_block_prepare();
606 yield(); /* be nice */
607
608 while (!(CHCR0 & 0x0002)); /* wait for end of DMA */
609 while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
610 SCR1 = 0;
611 serial_mode = SER_DISABLED;
612
613 if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */
614 rc = -1;
615
616 write_transfer(dummy, 1);
617 last_disk_activity = current_tick;
618
619 return rc;
620}
621
622int mmc_read_sectors(IF_MD(int drive,)
623 unsigned long start,
624 int incount,
625 void* inbuf)
626{
627 int rc = 0;
628 int lastblock = 0;
629 unsigned long end_block;
630 tCardInfo *card;
631#ifndef HAVE_MULTIDRIVE
632 int drive = current_card;
633#endif
634
635 card = &card_info[drive];
636 rc = select_card(drive);
637 if (rc)
638 {
639 rc = rc * 10 - 1;
640 goto error;
641 }
642
643 end_block = start + incount;
644 if (end_block > card->numblocks)
645 {
646 rc = -2;
647 goto error;
648 }
649
650 /* Some cards don't like reading the very last block with
651 * CMD_READ_MULTIPLE_BLOCK, so make sure this block is always
652 * read with CMD_READ_SINGLE_BLOCK. */
653 if (end_block == card->numblocks)
654 lastblock = 1;
655
656 if (incount > 1)
657 {
658 /* MMC4.2: make multiplication conditional */
659 if (send_cmd(CMD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL))
660 {
661 rc = -3;
662 goto error;
663 }
664 while (--incount >= lastblock)
665 {
666 rc = receive_block(inbuf, card->read_timeout);
667 if (rc)
668 {
669 /* If an error occurs during multiple block reading, the
670 * host still needs to send CMD_STOP_TRANSMISSION */
671 send_cmd(CMD_STOP_TRANSMISSION, 0, NULL);
672 rc = rc * 10 - 4;
673 goto error;
674 }
675 inbuf += BLOCK_SIZE;
676 start++;
677 /* ^^ necessary for the abovementioned last block special case */
678 }
679 if (send_cmd(CMD_STOP_TRANSMISSION, 0, NULL))
680 {
681 rc = -5;
682 goto error;
683 }
684 }
685 if (incount > 0)
686 {
687 /* MMC4.2: make multiplication conditional */
688 if (send_cmd(CMD_READ_SINGLE_BLOCK, start * BLOCK_SIZE, NULL))
689 {
690 rc = -6;
691 goto error;
692 }
693 rc = receive_block(inbuf, card->read_timeout);
694 if (rc)
695 {
696 rc = rc * 10 - 7;
697 goto error;
698 }
699 }
700
701 error:
702
703 deselect_card();
704
705 return rc;
706}
707
708int mmc_write_sectors(IF_MD(int drive,)
709 unsigned long start,
710 int count,
711 const void* buf)
712{
713 int rc = 0;
714 int write_cmd;
715 unsigned char start_token;
716 tCardInfo *card;
717#ifndef HAVE_MULTIDRIVE
718 int drive = current_card;
719#endif
720
721 card = &card_info[drive];
722 rc = select_card(drive);
723 if (rc)
724 {
725 rc = rc * 10 - 1;
726 goto error;
727 }
728
729 if (start + count > card->numblocks)
730 panicf("Writing past end of card");
731
732 send_block_addr = buf;
733 send_block_prepare();
734
735 if (count > 1)
736 {
737 write_cmd = CMD_WRITE_MULTIPLE_BLOCK;
738 start_token = DT_START_WRITE_MULTIPLE;
739 }
740 else
741 {
742 write_cmd = CMD_WRITE_BLOCK;
743 start_token = DT_START_BLOCK;
744 }
745 /* MMC4.2: make multiplication conditional */
746 if (send_cmd(write_cmd, start * BLOCK_SIZE, NULL))
747 {
748 rc = -2;
749 goto error;
750 }
751 while (--count >= 0)
752 {
753 rc = send_block_send(start_token, card->write_timeout, count > 0);
754 if (rc)
755 {
756 rc = rc * 10 - 3;
757 break;
758 /* If an error occurs during multiple block writing,
759 * the STOP_TRAN token still needs to be sent. */
760 }
761 }
762 if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK)
763 {
764 static const unsigned char stop_tran = DT_STOP_TRAN;
765 write_transfer(&stop_tran, 1);
766 poll_busy(card->write_timeout);
767 }
768
769 error:
770
771 deselect_card();
772
773 return rc;
774}
775
776bool mmc_disk_is_active(void)
777{
778 /* this is correct unless early return from write gets implemented */
779 return mutex_test(&mmc_mutex);
780}
781
782bool mmc_detect(void)
783{
784 return (adc_read(ADC_MMC_SWITCH) < 0x200);
785}
786
787bool mmc_touched(void)
788{
789 if (mmc_status == MMC_UNKNOWN) /* try to detect */
790 {
791 mutex_lock(&mmc_mutex);
792 setup_sci1(7); /* safe value */
793 and_b(~0x02, &PADRH); /* assert CS */
794 if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0xFF)
795 mmc_status = MMC_UNTOUCHED;
796 else
797 mmc_status = MMC_TOUCHED;
798
799 deselect_card();
800 }
801 return mmc_status == MMC_TOUCHED;
802}
803
804bool mmc_usb_active(int delayticks)
805{
806 /* reading "inactive" is delayed by user-supplied monoflop value */
807 return (usb_activity ||
808 TIME_BEFORE(current_tick, last_usb_activity + delayticks));
809}
810
811static void mmc_tick(void)
812{
813 bool current_status;
814
815 if (new_mmc_circuit)
816 /* USB bridge activity is 0 on idle, ~527 on active */
817 current_status = adc_read(ADC_USB_ACTIVE) > 0x100;
818 else
819 current_status = adc_read(ADC_USB_ACTIVE) < 0x190;
820
821 if (!current_status && usb_activity)
822 last_usb_activity = current_tick;
823 usb_activity = current_status;
824
825 current_status = mmc_detect();
826 /* Only report when the status has changed */
827 if (current_status != last_mmc_status)
828 {
829 last_mmc_status = current_status;
830 countdown = HZ/3;
831 }
832 else
833 {
834 /* Count down until it gets negative */
835 if (countdown >= 0)
836 countdown--;
837
838 if (countdown == 0)
839 {
840 if (current_status)
841 {
842 queue_broadcast(SYS_HOTSWAP_INSERTED, mmc_first_drive + 1);
843 }
844 else
845 {
846 queue_broadcast(SYS_HOTSWAP_EXTRACTED, mmc_first_drive + 1);
847 mmc_status = MMC_UNTOUCHED;
848 card_info[1].initialized = false;
849 }
850 }
851 }
852}
853
854void mmc_enable(bool on)
855{
856 mutex_lock(&mmc_mutex);
857 enable_controller(on);
858 mutex_unlock(&mmc_mutex);
859}
860
861int mmc_init(void)
862{
863 int rc = 0;
864
865 if (!initialized)
866 mutex_init(&mmc_mutex);
867
868 mutex_lock(&mmc_mutex);
869 led(false);
870
871 last_mmc_status = mmc_detect();
872#ifndef HAVE_MULTIDRIVE
873 /* Use MMC if inserted, internal flash otherwise */
874 current_card = last_mmc_status ? 1 : 0;
875#endif
876
877 if (!initialized)
878 {
879 if (!last_mmc_status)
880 mmc_status = MMC_UNTOUCHED;
881
882 /* Port setup */
883 PACR1 &= ~0x0F3C; /* GPIO function for PA13 (flash busy), PA12
884 * (clk gate), PA10 (flash CS), PA9 (MMC CS) */
885 PACR2 &= ~0x4000; /* GPIO for PA7 (flash reset) */
886 PADR |= 0x0680; /* set all the selects + reset high (=inactive) */
887 PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */
888
889 PBCR1 &= ~0x0CF0; /* GPIO function for PB13, PB11 and PB10 */
890 PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high in GPIO */
891 PBIOR |= 0x2000; /* SCK1 output */
892 PBIOR &= ~0x0C00; /* TxD1, RxD1 input */
893
894 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
895
896 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
897 tick_add_task(mmc_tick);
898 initialized = true;
899 }
900 enable_controller(true);
901
902 mutex_unlock(&mmc_mutex);
903 return rc;
904}
905
906long mmc_last_disk_activity(void)
907{
908 return last_disk_activity;
909}
910
911#ifdef STORAGE_GET_INFO
912void mmc_get_info(IF_MD(int drive,) struct storage_info *info)
913{
914#ifndef HAVE_MULTIDRIVE
915 const int drive=0;
916#endif
917 info->sector_size=card_info[drive].blocksize;
918 info->num_sectors=card_info[drive].numblocks;
919 info->vendor="Rockbox";
920 if(drive==0)
921 {
922 info->product="Internal Storage";
923 }
924 else
925 {
926 info->product="MMC Card Slot";
927 }
928 info->revision="0.00";
929}
930#endif
931
932#ifdef HAVE_HOTSWAP
933bool mmc_removable(IF_MD_NONVOID(int drive))
934{
935#ifndef HAVE_MULTIDRIVE
936 const int drive=0;
937#endif
938 return (drive==1);
939}
940
941bool mmc_present(IF_MD_NONVOID(int drive))
942{
943#ifndef HAVE_MULTIDRIVE
944 const int drive=0;
945#endif
946 if(drive==0)
947 {
948 return true;
949 }
950 else
951 {
952 return mmc_detect();
953 }
954}
955#endif
956
957void mmc_spin(void)
958{
959}
960
961void mmc_spindown(int seconds)
962{
963 (void)seconds;
964}
965
966#ifdef CONFIG_STORAGE_MULTI
967int mmc_num_drives(int first_drive)
968{
969 mmc_first_drive = first_drive;
970 return MMC_NUM_DRIVES;
971}
972#endif /* CONFIG_STORAGE_MULTI */
973
974int mmc_event(long id, intptr_t data)
975{
976 return storage_event_default_handler(id, data, last_disk_activity,
977 STORAGE_MMC);
978}