summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pp/ata-sd-pp.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pp/ata-sd-pp.c')
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c1387
1 files changed, 1387 insertions, 0 deletions
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
new file mode 100644
index 0000000000..f83bb60566
--- /dev/null
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -0,0 +1,1387 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Daniel Ankers
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" /* for HAVE_MULTIDRIVE */
22#include "fat.h"
23#include "sdmmc.h"
24#include "gcc_extensions.h"
25#ifdef HAVE_HOTSWAP
26#include "sd-pp-target.h"
27#endif
28#include "ata_idle_notify.h"
29#include "system.h"
30#include <string.h>
31#include "thread.h"
32#include "led.h"
33#include "disk.h"
34#include "cpu.h"
35#include "panic.h"
36#include "usb.h"
37#include "sd.h"
38#include "storage.h"
39
40#define SECTOR_SIZE 512
41#define BLOCKS_PER_BANK 0x7a7800
42
43/* Comparing documentations of various MMC/SD controllers revealed, */
44/* that this controller seems to be a mix of PXA27x, PXA255 and */
45/* some PP specific stuff. The register and bit definitions are */
46/* taken from the 'PXA27x Developers Manual', as it appears to be */
47/* the closest match. Known differences and obscurities are commented.*/
48
49#define MMC_STRPCL (*(volatile unsigned int *)(0x70008200))
50#define MMC_STAT (*(volatile unsigned int *)(0x70008204))
51#define MMC_CLKRT (*(volatile unsigned int *)(0x70008208))
52#define MMC_SPI (*(volatile unsigned int *)(0x7000820c))
53#define MMC_CMDAT (*(volatile unsigned int *)(0x70008210))
54#define MMC_RESTO (*(volatile unsigned int *)(0x70008214))
55#define MMC_RDTO (*(volatile unsigned int *)(0x70008218))
56#define MMC_BLKLEN (*(volatile unsigned int *)(0x7000821c))
57#define MMC_NUMBLK (*(volatile unsigned int *)(0x70008220))
58#define MMC_I_MASK (*(volatile unsigned int *)(0x70008224))
59#define MMC_CMD (*(volatile unsigned int *)(0x70008228))
60#define MMC_ARGH (*(volatile unsigned int *)(0x7000822c))
61#define MMC_ARGL (*(volatile unsigned int *)(0x70008230))
62#define MMC_RES (*(volatile unsigned int *)(0x70008234))
63
64/* PXA255/27x have separate RX/TX FIFOs with 32x8 bit */
65/* PP502x has a combined Data FIFO with 16x16 bit */
66#define MMC_DATA_FIFO (*(volatile unsigned int *)(0x70008280))
67
68/* PP specific registers, no other controller seem to have such. */
69#define MMC_SD_STATE (*(volatile unsigned int *)(0x70008238))
70#define MMC_INIT_1 (*(volatile unsigned int *)(0x70008240))
71#define MMC_INIT_2 (*(volatile unsigned int *)(0x70008244))
72
73/* MMC_STAT bits */
74#define STAT_SDIO_SUSPEND_ACK (1 << 16)
75#define STAT_SDIO_INT (1 << 15)
76#define STAT_RD_STALLED (1 << 14)
77#define STAT_END_CMD_RES (1 << 13)
78#define STAT_PRG_DONE (1 << 12)
79#define STAT_DATA_TRAN_DONE (1 << 11)
80#define STAT_SPI_WR_ERR (1 << 10)
81#define STAT_FLASH_ERR (1 << 9)
82#define STAT_CLK_EN (1 << 8)
83#define STAT_RECV_FIFO_FULL (1 << 7) /* taken from PXA255 */
84#define STAT_XMIT_FIFO_EMPTY (1 << 6) /* taken from PXA255 */
85#define STAT_RES_CRC_ERR (1 << 5)
86#define STAT_DAT_ERR_TOKEN (1 << 4)
87#define STAT_CRC_RD_ERR (1 << 3)
88#define STAT_CRC_WR_ERR (1 << 2)
89#define STAT_TIME_OUT_RES (1 << 1)
90#define STAT_TIME_OUT_READ (1)
91#define STAT_ERROR_BITS (0x3f)
92
93/* MMC_CMDAT bits */
94/* Some of the bits used by the OF don't make much sense with these */
95/* definitions. So they're probably different between PXA and PP502x */
96/* Bits 0-5 appear to match though. */
97#define CMDAT_SDIO_RESUME (1 << 13)
98#define CMDAT_SDIO_SUSPEND (1 << 12)
99#define CMDAT_SDIO_INT_EN (1 << 11)
100#define CMDAT_STOP_TRAN (1 << 10)
101#define CMDAT_SD_4DAT (1 << 8)
102#define CMDAT_DMA_EN (1 << 7)
103#define CMDAT_INIT (1 << 6)
104#define CMDAT_BUSY (1 << 5)
105#define CMDAT_STRM_BLK (1 << 4)
106#define CMDAT_WR_RD (1 << 3)
107#define CMDAT_DATA_EN (1 << 2)
108#define CMDAT_RES_TYPE3 (3)
109#define CMDAT_RES_TYPE2 (2)
110#define CMDAT_RES_TYPE1 (1)
111
112/* MMC_I_MASK bits */
113/* PP502x apparently only has bits 0-3 */
114#define I_MASK_SDIO_SUSPEND_ACK (1 << 12)
115#define I_MASK_SDIO_INT (1 << 11)
116#define I_MASK_RD_STALLED (1 << 10)
117#define I_MASK_RES_ERR (1 << 9)
118#define I_MASK_DAT_ERR (1 << 8)
119#define I_MASK_TINT (1 << 7)
120#define I_MASK_TXFIFO_WR_REQ (1 << 6)
121#define I_MASK_RXFIFO_RD_REQ (1 << 5)
122#define I_MASK_CLK_IS_OFF (1 << 4)
123#define I_MASK_STOP_CMD (1 << 3)
124#define I_MASK_END_CMD_RES (1 << 2)
125#define I_MASK_PRG_DONE (1 << 1)
126#define I_MASK_DATA_TRAN_DONE (1 << 0)
127
128#define FIFO_LEN 16 /* FIFO is 16 words deep */
129
130#define EC_OK 0
131#define EC_FAILED 1
132#define EC_NOCARD 2
133#define EC_WAIT_STATE_FAILED 3
134#define EC_CHECK_TIMEOUT_FAILED 4
135#define EC_POWER_UP 5
136#define EC_READ_TIMEOUT 6
137#define EC_WRITE_TIMEOUT 7
138#define EC_TRAN_SEL_BANK 8
139#define EC_TRAN_READ_ENTRY 9
140#define EC_TRAN_READ_EXIT 10
141#define EC_TRAN_WRITE_ENTRY 11
142#define EC_TRAN_WRITE_EXIT 12
143#define EC_FIFO_SEL_BANK_EMPTY 13
144#define EC_FIFO_SEL_BANK_DONE 14
145#define EC_FIFO_ENA_BANK_EMPTY 15
146#define EC_FIFO_READ_FULL 16
147#define EC_FIFO_WR_EMPTY 17
148#define EC_FIFO_WR_DONE 18
149#define EC_COMMAND 19
150#define NUM_EC 20
151
152/* for compatibility */
153static long last_disk_activity = -1;
154
155/** static, private data **/
156static bool initialized = false;
157static unsigned int sd_thread_id = 0;
158
159#define Q_CLOSE 1
160
161static long next_yield = 0;
162#define MIN_YIELD_PERIOD 1000
163
164static tCardInfo card_info[2];
165static tCardInfo *currcard = NULL; /* current active card */
166
167struct sd_card_status
168{
169 int retry;
170 int retry_max;
171};
172
173static struct sd_card_status sd_status[NUM_DRIVES] =
174{
175 { 0, 1 },
176#ifdef HAVE_MULTIDRIVE
177 { 0, 10 }
178#endif
179};
180
181/* Shoot for around 75% usage */
182static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
183static const char sd_thread_name[] = "ata/sd";
184static struct mutex sd_mtx SHAREDBSS_ATTR;
185static struct event_queue sd_queue SHAREDBSS_ATTR;
186
187#ifdef HAVE_HOTSWAP
188static int sd_first_drive = 0;
189#endif
190
191/* Posted when card plugged status has changed */
192#define SD_HOTSWAP 1
193/* Actions taken by sd_thread when card status has changed */
194enum sd_thread_actions
195{
196 SDA_NONE = 0x0,
197 SDA_UNMOUNTED = 0x1,
198 SDA_MOUNTED = 0x2
199};
200
201/* Private Functions */
202
203static unsigned int check_time[NUM_EC];
204
205static inline bool sd_check_timeout(long timeout, int id)
206{
207 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
208}
209
210static bool sd_poll_status(unsigned int trigger, long timeout)
211{
212 long t = USEC_TIMER;
213
214 while ((MMC_STAT & trigger) == 0)
215 {
216 long time = USEC_TIMER;
217
218 if (TIME_AFTER(time, next_yield))
219 {
220 long ty = USEC_TIMER;
221 yield();
222 timeout += USEC_TIMER - ty;
223 next_yield = ty + MIN_YIELD_PERIOD;
224 }
225
226 if (TIME_AFTER(time, t + timeout))
227 return false;
228 }
229
230 return true;
231}
232
233static int sd_command(unsigned int cmd, unsigned long arg1,
234 unsigned long *response, unsigned int cmdat)
235{
236 int i, words; /* Number of 16 bit words to read from MMC_RES */
237 unsigned int data[9];
238
239 MMC_CMD = cmd;
240 MMC_ARGH = (unsigned int)((arg1 & 0xffff0000) >> 16);
241 MMC_ARGL = (unsigned int)((arg1 & 0xffff));
242 MMC_CMDAT = cmdat;
243
244 if (!sd_poll_status(STAT_END_CMD_RES, 100000))
245 return -EC_COMMAND;
246
247 if ((MMC_STAT & STAT_ERROR_BITS) != 0)
248 /* Error sending command */
249 return -EC_COMMAND - (MMC_STAT & STAT_ERROR_BITS)*100;
250
251 if (cmd == SD_GO_IDLE_STATE)
252 return 0; /* no response here */
253
254 words = (cmdat == CMDAT_RES_TYPE2) ? 9 : 3;
255
256 for (i = 0; i < words; i++) /* MMC_RES is read MSB first */
257 data[i] = MMC_RES; /* Read most significant 16-bit word */
258
259 if (response == NULL)
260 {
261 /* response discarded */
262 }
263 else if (cmdat == CMDAT_RES_TYPE2)
264 {
265 /* Response type 2 has the following structure:
266 * [135:135] Start Bit - '0'
267 * [134:134] Transmission bit - '0'
268 * [133:128] Reserved - '111111'
269 * [127:001] CID or CSD register including internal CRC7
270 * [000:000] End Bit - '1'
271 */
272 response[3] = (data[0]<<24) + (data[1]<<8) + (data[2]>>8);
273 response[2] = (data[2]<<24) + (data[3]<<8) + (data[4]>>8);
274 response[1] = (data[4]<<24) + (data[5]<<8) + (data[6]>>8);
275 response[0] = (data[6]<<24) + (data[7]<<8) + (data[8]>>8);
276 }
277 else
278 {
279 /* Response types 1, 1b, 3, 6, 7 have the following structure:
280 * Types 4 and 5 are not supported.
281 *
282 * [47] Start bit - '0'
283 * [46] Transmission bit - '0'
284 * [45:40] R1, R1b, R6, R7: Command index
285 * R3: Reserved - '111111'
286 * [39:8] R1, R1b: Card Status
287 * R3: OCR Register
288 * R6: [31:16] RCA
289 * [15: 0] Card Status Bits 23, 22, 19, 12:0
290 * [23] COM_CRC_ERROR
291 * [22] ILLEGAL_COMMAND
292 * [19] ERROR
293 * [12:9] CURRENT_STATE
294 * [8] READY_FOR_DATA
295 * [7:6]
296 * [5] SD_APP_CMD
297 * [4]
298 * [3] AKE_SEQ_ERROR
299 * [2] Reserved
300 * [1:0] Reserved for test mode
301 * R7: [19:16] Voltage accepted
302 * [15:8] echo-back of check pattern
303 * [7:1] R1, R1b: CRC7
304 * R3: Reserved - '1111111'
305 * [0] End Bit - '1'
306 */
307 response[0] = (data[0]<<24) + (data[1]<<8) + (data[2]>>8);
308 }
309
310 return 0;
311}
312
313static int sd_wait_for_state(unsigned int state, int id)
314{
315 unsigned long response = 0;
316 unsigned int timeout = 0x80000;
317
318 check_time[id] = USEC_TIMER;
319
320 while (1)
321 {
322 int ret = sd_command(SD_SEND_STATUS, currcard->rca, &response, CMDAT_RES_TYPE1);
323 long us;
324
325 if (ret < 0)
326 return ret*100 - id;
327
328 if (((response >> 9) & 0xf) == state)
329 {
330 MMC_SD_STATE = state;
331 return 0;
332 }
333
334 if (!sd_check_timeout(timeout, id))
335 return -EC_WAIT_STATE_FAILED*100 - id;
336
337 us = USEC_TIMER;
338 if (TIME_AFTER(us, next_yield))
339 {
340 yield();
341 timeout += USEC_TIMER - us;
342 next_yield = us + MIN_YIELD_PERIOD;
343 }
344 }
345}
346
347
348static inline bool card_detect_target(void)
349{
350#ifdef HAVE_HOTSWAP
351#ifdef SANSA_E200
352 return (GPIOA_INPUT_VAL & 0x80) == 0; /* low active */
353#elif defined SANSA_C200
354 return (GPIOL_INPUT_VAL & 0x08) != 0; /* high active */
355#endif
356#else
357 return false;
358#endif
359}
360
361
362static inline void copy_read_sectors_fast(unsigned char **buf)
363{
364 /* Copy one chunk of 16 words using best method for start alignment */
365 switch ( (intptr_t)*buf & 3 )
366 {
367 case 0:
368 asm volatile (
369 "ldmia %[data], { r2-r9 } \r\n"
370 "orr r2, r2, r3, lsl #16 \r\n"
371 "orr r4, r4, r5, lsl #16 \r\n"
372 "orr r6, r6, r7, lsl #16 \r\n"
373 "orr r8, r8, r9, lsl #16 \r\n"
374 "stmia %[buf]!, { r2, r4, r6, r8 } \r\n"
375 "ldmia %[data], { r2-r9 } \r\n"
376 "orr r2, r2, r3, lsl #16 \r\n"
377 "orr r4, r4, r5, lsl #16 \r\n"
378 "orr r6, r6, r7, lsl #16 \r\n"
379 "orr r8, r8, r9, lsl #16 \r\n"
380 "stmia %[buf]!, { r2, r4, r6, r8 } \r\n"
381 : [buf]"+&r"(*buf)
382 : [data]"r"(&MMC_DATA_FIFO)
383 : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9"
384 );
385 break;
386 case 1:
387 asm volatile (
388 "ldmia %[data], { r2-r9 } \r\n"
389 "orr r3, r2, r3, lsl #16 \r\n"
390 "strb r3, [%[buf]], #1 \r\n"
391 "mov r3, r3, lsr #8 \r\n"
392 "strh r3, [%[buf]], #2 \r\n"
393 "mov r3, r3, lsr #16 \r\n"
394 "orr r3, r3, r4, lsl #8 \r\n"
395 "orr r3, r3, r5, lsl #24 \r\n"
396 "mov r5, r5, lsr #8 \r\n"
397 "orr r5, r5, r6, lsl #8 \r\n"
398 "orr r5, r5, r7, lsl #24 \r\n"
399 "mov r7, r7, lsr #8 \r\n"
400 "orr r7, r7, r8, lsl #8 \r\n"
401 "orr r7, r7, r9, lsl #24 \r\n"
402 "mov r2, r9, lsr #8 \r\n"
403 "stmia %[buf]!, { r3, r5, r7 } \r\n"
404 "ldmia %[data], { r3-r10 } \r\n"
405 "orr r2, r2, r3, lsl #8 \r\n"
406 "orr r2, r2, r4, lsl #24 \r\n"
407 "mov r4, r4, lsr #8 \r\n"
408 "orr r4, r4, r5, lsl #8 \r\n"
409 "orr r4, r4, r6, lsl #24 \r\n"
410 "mov r6, r6, lsr #8 \r\n"
411 "orr r6, r6, r7, lsl #8 \r\n"
412 "orr r6, r6, r8, lsl #24 \r\n"
413 "mov r8, r8, lsr #8 \r\n"
414 "orr r8, r8, r9, lsl #8 \r\n"
415 "orr r8, r8, r10, lsl #24 \r\n"
416 "mov r10, r10, lsr #8 \r\n"
417 "stmia %[buf]!, { r2, r4, r6, r8 } \r\n"
418 "strb r10, [%[buf]], #1 \r\n"
419 : [buf]"+&r"(*buf)
420 : [data]"r"(&MMC_DATA_FIFO)
421 : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
422 );
423 break;
424 case 2:
425 asm volatile (
426 "ldmia %[data], { r2-r9 } \r\n"
427 "strh r2, [%[buf]], #2 \r\n"
428 "orr r3, r3, r4, lsl #16 \r\n"
429 "orr r5, r5, r6, lsl #16 \r\n"
430 "orr r7, r7, r8, lsl #16 \r\n"
431 "stmia %[buf]!, { r3, r5, r7 } \r\n"
432 "ldmia %[data], { r2-r8, r10 } \r\n"
433 "orr r2, r9, r2, lsl #16 \r\n"
434 "orr r3, r3, r4, lsl #16 \r\n"
435 "orr r5, r5, r6, lsl #16 \r\n"
436 "orr r7, r7, r8, lsl #16 \r\n"
437 "stmia %[buf]!, { r2, r3, r5, r7 } \r\n"
438 "strh r10, [%[buf]], #2 \r\n"
439 : [buf]"+&r"(*buf)
440 : [data]"r"(&MMC_DATA_FIFO)
441 : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
442 );
443 break;
444 case 3:
445 asm volatile (
446 "ldmia %[data], { r2-r9 } \r\n"
447 "orr r3, r2, r3, lsl #16 \r\n"
448 "strb r3, [%[buf]], #1 \r\n"
449 "mov r3, r3, lsr #8 \r\n"
450 "orr r3, r3, r4, lsl #24 \r\n"
451 "mov r4, r4, lsr #8 \r\n"
452 "orr r5, r4, r5, lsl #8 \r\n"
453 "orr r5, r5, r6, lsl #24 \r\n"
454 "mov r6, r6, lsr #8 \r\n"
455 "orr r7, r6, r7, lsl #8 \r\n"
456 "orr r7, r7, r8, lsl #24 \r\n"
457 "mov r8, r8, lsr #8 \r\n"
458 "orr r2, r8, r9, lsl #8 \r\n"
459 "stmia %[buf]!, { r3, r5, r7 } \r\n"
460 "ldmia %[data], { r3-r10 } \r\n"
461 "orr r2, r2, r3, lsl #24 \r\n"
462 "mov r3, r3, lsr #8 \r\n"
463 "orr r4, r3, r4, lsl #8 \r\n"
464 "orr r4, r4, r5, lsl #24 \r\n"
465 "mov r5, r5, lsr #8 \r\n"
466 "orr r6, r5, r6, lsl #8 \r\n"
467 "orr r6, r6, r7, lsl #24 \r\n"
468 "mov r7, r7, lsr #8 \r\n"
469 "orr r8, r7, r8, lsl #8 \r\n"
470 "orr r8, r8, r9, lsl #24 \r\n"
471 "mov r9, r9, lsr #8 \r\n"
472 "orr r10, r9, r10, lsl #8 \r\n"
473 "stmia %[buf]!, { r2, r4, r6, r8 } \r\n"
474 "strh r10, [%[buf]], #2 \r\n"
475 "mov r10, r10, lsr #16 \r\n"
476 "strb r10, [%[buf]], #1 \r\n"
477 : [buf]"+&r"(*buf)
478 : [data]"r"(&MMC_DATA_FIFO)
479 : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
480 );
481 break;
482 }
483}
484
485static inline void copy_read_sectors_slow(unsigned char** buf)
486{
487 int cnt = FIFO_LEN;
488 int t;
489
490 /* Copy one chunk of 16 words */
491 asm volatile (
492 "1: \r\n"
493 "ldrh %[t], [%[data]] \r\n"
494 "strb %[t], [%[buf]], #1 \r\n"
495 "mov %[t], %[t], lsr #8 \r\n"
496 "strb %[t], [%[buf]], #1 \r\n"
497 "subs %[cnt], %[cnt], #1 \r\n"
498 "bgt 1b \r\n"
499 : [cnt]"+&r"(cnt), [buf]"+&r"(*buf),
500 [t]"=&r"(t)
501 : [data]"r"(&MMC_DATA_FIFO)
502 );
503}
504
505/* Writes have to be kept slow for now */
506static inline void copy_write_sectors(const unsigned char** buf)
507{
508 int cnt = FIFO_LEN - 1;
509 unsigned t;
510 long time;
511
512 time = USEC_TIMER + 3;
513 if (((intptr_t)*buf & 3) == 0)
514 {
515 asm volatile (
516 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
517 "mov r4, r3, lsr #16 \r\n"
518 "mov r6, r5, lsr #16 \r\n"
519 "mov r8, r7, lsr #16 \r\n"
520 "mov r10, r9, lsr #16 \r\n"
521 "stmia %[data], { r3-r10 } \r\n"
522 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
523 "mov r4, r3, lsr #16 \r\n"
524 "mov r6, r5, lsr #16 \r\n"
525 "mov r8, r7, lsr #16 \r\n"
526 "mov %[t], r9, lsr #16 \r\n"
527 "stmia %[data], { r3-r9 } \r\n"
528 : [buf]"+&r"(*buf), [t]"=&r"(t)
529 : [data]"r"(&MMC_DATA_FIFO)
530 : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
531 );
532 }
533 else
534 {
535 do
536 {
537 t = *(*buf)++;
538 t |= *(*buf)++ << 8;
539 MMC_DATA_FIFO = t;
540 } while (--cnt > 0); /* tail loop is faster */
541 t = *(*buf)++;
542 t |= *(*buf)++ << 8;
543 }
544 /* Don't write the last word before at least 3 usec have elapsed since FIFO_EMPTY */
545 /* This prevents the 'two bytes inserted' bug. */
546
547 while (!TIME_AFTER(USEC_TIMER, time));
548 MMC_DATA_FIFO = t;
549}
550
551static int sd_select_bank(unsigned char bank)
552{
553 unsigned char card_data[FIFO_LEN*2];// FIFO_LEN words=FIFO_LEN*2 bytes
554 const unsigned char* write_buf;
555 int i, ret;
556
557 memset(card_data, 0, sizeof card_data);
558
559 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_SEL_BANK);
560 if (ret < 0)
561 return ret;
562
563 MMC_BLKLEN = 512;
564 MMC_NUMBLK = 1;
565
566 ret = sd_command(35, 0, NULL, /* CMD35 is vendor specific */
567 0x1c00 | CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
568 if (ret < 0)
569 return ret;
570
571 MMC_SD_STATE = SD_PRG;
572
573 card_data[0] = bank;
574
575 /* Write the card data */
576 for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN)
577 {
578 write_buf = card_data;
579 /* Wait for the FIFO to empty */
580 if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 10000))
581 {
582 copy_write_sectors(&write_buf); /* Copy one chunk of 16 words */
583 /* clear buffer: only the first chunk contains interesting data (bank), the remaining is zero filling */
584 memset(card_data, 0, sizeof card_data);
585 continue;
586 }
587
588 return -EC_FIFO_SEL_BANK_EMPTY;
589 }
590
591 if (!sd_poll_status(STAT_PRG_DONE, 10000))
592 return -EC_FIFO_SEL_BANK_DONE;
593
594 currcard->current_bank = bank;
595
596 return 0;
597}
598
599static void sd_card_mux(int card_no)
600{
601/* Set the current card mux */
602#if defined(SANSA_E200)
603 if (card_no == 0)
604 {
605 GPO32_VAL |= 0x4;
606
607 GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
608 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
609 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x1f);
610 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1f);
611 GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
612
613 outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014);
614 }
615 else
616 {
617 GPO32_VAL &= ~0x4;
618
619 GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x1f);
620 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
621 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x7a);
622 GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x7a);
623 GPIO_SET_BITWISE( GPIOA_OUTPUT_EN, 0x7a);
624
625 outl(inl(0x70000014) & ~(0x3ffff), 0x70000014);
626 }
627#elif defined(SANSA_C200)
628 if (card_no == 0)
629 {
630 GPO32_VAL |= 0x4;
631
632 GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x1f);
633 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
634 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x7a);
635 GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x7a);
636 GPIO_SET_BITWISE( GPIOA_OUTPUT_EN, 0x7a);
637
638 outl(inl(0x70000014) & ~(0x3ffff), 0x70000014);
639 }
640 else
641 {
642 GPO32_VAL &= ~0x4;
643
644 GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
645 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
646 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x1f);
647 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1f);
648 GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
649
650 outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014);
651 }
652#elif defined(PHILIPS_SA9200)
653 /* only 1 "card" (no external memory card) */
654 (void)card_no;
655
656 GPIO_SET_BITWISE(GPIOH_ENABLE, 0x80);
657 GPIO_SET_BITWISE(GPIOH_OUTPUT_EN, 0x80);
658
659 outl(0x255aa, 0x70000014);
660
661 GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x04);
662 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x04);
663
664 GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
665 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
666
667 GPIO_SET_BITWISE(GPIOH_OUTPUT_VAL, 0x80);
668 GPIO_SET_BITWISE(GPIOH_OUTPUT_EN, 0x80);
669#endif
670}
671
672static void sd_init_device(int card_no)
673{
674/* SD Protocol registers */
675#ifdef HAVE_HOTSWAP
676 unsigned long response = 0;
677#endif
678 unsigned int i;
679 unsigned char carddata[512];
680 unsigned char *dataptr;
681 unsigned long temp_reg[4];
682 int ret;
683
684/* Enable and initialise controller */
685 MMC_CLKRT = 6; /* switch to lowest clock rate */
686
687/* Initialise card data as blank */
688 memset(currcard, 0, sizeof(*currcard));
689
690/* Switch card mux to card to initialize */
691 sd_card_mux(card_no);
692
693/* Init NAND */
694 MMC_INIT_1 |= (1 << 15);
695 MMC_INIT_2 |= (1 << 15);
696 MMC_INIT_2 &= ~(3 << 12);
697 MMC_INIT_2 |= (1 << 13);
698 MMC_INIT_1 &= ~(3 << 12);
699 MMC_INIT_1 |= (1 << 13);
700
701 DEV_EN |= DEV_ATA; /* Enable controller */
702 DEV_RS |= DEV_ATA; /* Reset controller */
703 DEV_RS &=~DEV_ATA; /* Clear Reset */
704
705 MMC_SD_STATE = SD_TRAN;
706
707 MMC_I_MASK = 0xf; /* disable interrupts */
708
709 ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, 0x100);
710 if (ret < 0)
711 goto card_init_error;
712
713 check_time[EC_POWER_UP] = USEC_TIMER;
714
715#ifdef HAVE_HOTSWAP
716 /* Check for SDHC:
717 - non-SDHC cards simply ignore SD_SEND_IF_COND (CMD8) and we get error -219,
718 which we can just ignore and assume we're dealing with standard SD.
719 - SDHC cards echo back the argument into the response. This is how we
720 tell if the card is SDHC.
721 */
722 ret = sd_command(SD_SEND_IF_COND,0x1aa, &response,
723 CMDAT_DATA_EN | CMDAT_RES_TYPE3);
724 if ( (ret < 0) && (ret!=-219) )
725 goto card_init_error;
726#endif
727
728 while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */
729 {
730 ret = sd_command(SD_APP_CMD, currcard->rca, NULL, CMDAT_RES_TYPE1);
731 if (ret < 0)
732 goto card_init_error;
733
734#ifdef HAVE_HOTSWAP
735 if(response == 0x1aa)
736 {
737 /* SDHC */
738 ret = sd_command(SD_APP_OP_COND, (1<<30)|0x100000,
739 &currcard->ocr, CMDAT_RES_TYPE3);
740 }
741 else
742#endif /* HAVE_HOTSWAP */
743 {
744 /* SD Standard */
745 ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr,
746 CMDAT_RES_TYPE3);
747 }
748
749 if (ret < 0)
750 goto card_init_error;
751
752 if (!sd_check_timeout(5000000, EC_POWER_UP))
753 {
754 ret = -EC_POWER_UP;
755 goto card_init_error;
756 }
757 }
758
759 ret = sd_command(SD_ALL_SEND_CID, 0, temp_reg, CMDAT_RES_TYPE2);
760 if (ret < 0)
761 goto card_init_error;
762
763 for(i=0; i<4; i++)
764 currcard->cid[i] = temp_reg[3-i];
765
766 ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, CMDAT_RES_TYPE1);
767 if (ret < 0)
768 goto card_init_error;
769
770 ret = sd_command(SD_SEND_CSD, currcard->rca, temp_reg, CMDAT_RES_TYPE2);
771 if (ret < 0)
772 goto card_init_error;
773
774 for(i=0; i<4; i++)
775 currcard->csd[i] = temp_reg[3-i];
776
777 sd_parse_csd(currcard);
778
779 MMC_CLKRT = 0; /* switch to highest clock rate */
780
781 ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL,
782 0x80 | CMDAT_RES_TYPE1);
783 if (ret < 0)
784 goto card_init_error;
785
786 ret = sd_command(SD_APP_CMD, currcard->rca, NULL, CMDAT_RES_TYPE1);
787 if (ret < 0)
788 goto card_init_error;
789
790 ret = sd_command(SD_SET_BUS_WIDTH, currcard->rca | 2, NULL,
791 CMDAT_RES_TYPE1); /* 4 bit */
792 if (ret < 0)
793 goto card_init_error;
794
795 ret = sd_command(SD_SET_BLOCKLEN, currcard->blocksize, NULL,
796 CMDAT_RES_TYPE1);
797 if (ret < 0)
798 goto card_init_error;
799
800 MMC_BLKLEN = currcard->blocksize;
801
802 /* If this card is >4GB & not SDHC, then we need to enable bank switching */
803 if( (currcard->numblocks >= BLOCKS_PER_BANK) &&
804 ((currcard->ocr & (1<<30)) == 0) )
805 {
806 MMC_SD_STATE = SD_TRAN;
807 MMC_NUMBLK = 1;
808
809 ret = sd_command(SD_SWITCH_FUNC, 0x80ffffef, NULL,
810 0x1c00 | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
811 if (ret < 0)
812 goto card_init_error;
813
814 /* Read 512 bytes from the card.
815 The first 512 bits contain the status information
816 TODO: Do something useful with this! */
817 dataptr = carddata;
818 for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN)
819 {
820 /* Wait for the FIFO to be full */
821 if (sd_poll_status(STAT_RECV_FIFO_FULL, 100000))
822 {
823 copy_read_sectors_slow(&dataptr);
824 continue;
825 }
826
827 ret = -EC_FIFO_ENA_BANK_EMPTY;
828 goto card_init_error;
829 }
830 }
831
832 currcard->initialized = 1;
833 return;
834
835 /* Card failed to initialize so disable it */
836card_init_error:
837 currcard->initialized = ret;
838}
839
840/* lock must already be aquired */
841static void sd_select_device(int card_no)
842{
843 currcard = &card_info[card_no];
844
845 if (card_no == 0)
846 {
847 /* Main card always gets a chance */
848 sd_status[0].retry = 0;
849 }
850
851 if (currcard->initialized > 0)
852 {
853 /* This card is already initialized - switch to it */
854 sd_card_mux(card_no);
855 return;
856 }
857
858 if (currcard->initialized == 0)
859 {
860 /* Card needs (re)init */
861 sd_init_device(card_no);
862 }
863}
864
865/* API Functions */
866
867int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
868 void* inbuf)
869{
870#ifndef HAVE_MULTIDRIVE
871 const int drive = 0;
872#endif
873 int ret;
874 unsigned char *buf, *buf_end;
875 unsigned int bank;
876
877 /* TODO: Add DMA support. */
878
879 mutex_lock(&sd_mtx);
880 sd_enable(true);
881 led(true);
882
883sd_read_retry:
884 if (drive != 0 && !card_detect_target())
885 {
886 /* no external sd-card inserted */
887 ret = -EC_NOCARD;
888 goto sd_read_error;
889 }
890
891 sd_select_device(drive);
892
893 if (currcard->initialized < 0)
894 {
895 ret = currcard->initialized;
896 goto sd_read_error;
897 }
898
899 last_disk_activity = current_tick;
900
901 /* Only switch banks with non-SDHC cards */
902 if((currcard->ocr & (1<<30))==0)
903 {
904 bank = start / BLOCKS_PER_BANK;
905
906 if (currcard->current_bank != bank)
907 {
908 ret = sd_select_bank(bank);
909 if (ret < 0)
910 goto sd_read_error;
911 }
912
913 start -= bank * BLOCKS_PER_BANK;
914 }
915
916 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
917 if (ret < 0)
918 goto sd_read_error;
919
920 MMC_NUMBLK = incount;
921
922#ifdef HAVE_HOTSWAP
923 if(currcard->ocr & (1<<30) )
924 {
925 /* SDHC */
926 ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL,
927 0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
928 }
929 else
930#endif
931 {
932 ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * SD_BLOCK_SIZE, NULL,
933 0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
934 }
935 if (ret < 0)
936 goto sd_read_error;
937
938 /* TODO: Don't assume SD_BLOCK_SIZE == SECTOR_SIZE */
939
940 buf_end = (unsigned char *)inbuf + incount * currcard->blocksize;
941 for (buf = inbuf; buf < buf_end;)
942 {
943 /* Wait for the FIFO to be full */
944 if (sd_poll_status(STAT_RECV_FIFO_FULL, 0x80000))
945 {
946 copy_read_sectors_fast(&buf); /* Copy one chunk of 16 words */
947 /* TODO: Switch bank if necessary */
948 continue;
949 }
950
951 ret = -EC_FIFO_READ_FULL;
952 goto sd_read_error;
953 }
954
955 last_disk_activity = current_tick;
956
957 ret = sd_command(SD_STOP_TRANSMISSION, 0, NULL, CMDAT_RES_TYPE1);
958 if (ret < 0)
959 goto sd_read_error;
960
961 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_EXIT);
962 if (ret < 0)
963 goto sd_read_error;
964
965 while (1)
966 {
967 led(false);
968 sd_enable(false);
969 mutex_unlock(&sd_mtx);
970
971 return ret;
972
973sd_read_error:
974 if (sd_status[drive].retry < sd_status[drive].retry_max
975 && ret != -EC_NOCARD)
976 {
977 sd_status[drive].retry++;
978 currcard->initialized = 0;
979 goto sd_read_retry;
980 }
981 }
982}
983
984int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
985 const void* outbuf)
986{
987/* Write support is not finished yet */
988/* TODO: The standard suggests using ACMD23 prior to writing multiple blocks
989 to improve performance */
990#ifndef HAVE_MULTIDRIVE
991 const int drive = 0;
992#endif
993 int ret;
994 const unsigned char *buf, *buf_end;
995 unsigned int bank;
996
997 mutex_lock(&sd_mtx);
998 sd_enable(true);
999 led(true);
1000
1001sd_write_retry:
1002 if (drive != 0 && !card_detect_target())
1003 {
1004 /* no external sd-card inserted */
1005 ret = -EC_NOCARD;
1006 goto sd_write_error;
1007 }
1008
1009 sd_select_device(drive);
1010
1011 if (currcard->initialized < 0)
1012 {
1013 ret = currcard->initialized;
1014 goto sd_write_error;
1015 }
1016
1017 /* Only switch banks with non-SDHC cards */
1018 if((currcard->ocr & (1<<30))==0)
1019 {
1020 bank = start / BLOCKS_PER_BANK;
1021
1022 if (currcard->current_bank != bank)
1023 {
1024 ret = sd_select_bank(bank);
1025 if (ret < 0)
1026 goto sd_write_error;
1027 }
1028
1029 start -= bank * BLOCKS_PER_BANK;
1030 }
1031
1032 check_time[EC_WRITE_TIMEOUT] = USEC_TIMER;
1033
1034 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
1035 if (ret < 0)
1036 goto sd_write_error;
1037
1038 MMC_NUMBLK = count;
1039
1040#ifdef HAVE_HOTSWAP
1041 if(currcard->ocr & (1<<30) )
1042 {
1043 /* SDHC */
1044 ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL,
1045 CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
1046 }
1047 else
1048#endif
1049 {
1050 ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*SD_BLOCK_SIZE, NULL,
1051 CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
1052 }
1053 if (ret < 0)
1054 goto sd_write_error;
1055
1056 buf_end = outbuf + count * currcard->blocksize - 2*FIFO_LEN;
1057
1058 for (buf = outbuf; buf <= buf_end;)
1059 {
1060 if (buf == buf_end)
1061 {
1062 /* Set MMC_SD_STATE to SD_PRG for the last buffer fill */
1063 MMC_SD_STATE = SD_PRG;
1064 }
1065
1066 copy_write_sectors(&buf); /* Copy one chunk of 16 words */
1067 /* TODO: Switch bank if necessary */
1068
1069 /* Wait for the FIFO to empty */
1070 if (!sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000))
1071 {
1072 ret = -EC_FIFO_WR_EMPTY;
1073 goto sd_write_error;
1074 }
1075 }
1076
1077 last_disk_activity = current_tick;
1078
1079 if (!sd_poll_status(STAT_PRG_DONE, 0x80000))
1080 {
1081 ret = -EC_FIFO_WR_DONE;
1082 goto sd_write_error;
1083 }
1084
1085 ret = sd_command(SD_STOP_TRANSMISSION, 0, NULL, CMDAT_RES_TYPE1);
1086 if (ret < 0)
1087 goto sd_write_error;
1088
1089 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_EXIT);
1090 if (ret < 0)
1091 goto sd_write_error;
1092
1093 while (1)
1094 {
1095 led(false);
1096 sd_enable(false);
1097 mutex_unlock(&sd_mtx);
1098
1099 return ret;
1100
1101sd_write_error:
1102 if (sd_status[drive].retry < sd_status[drive].retry_max
1103 && ret != -EC_NOCARD)
1104 {
1105 sd_status[drive].retry++;
1106 currcard->initialized = 0;
1107 goto sd_write_retry;
1108 }
1109 }
1110}
1111
1112#ifndef SD_DRIVER_CLOSE
1113static void sd_thread(void) NORETURN_ATTR;
1114#endif
1115static void sd_thread(void)
1116{
1117 struct queue_event ev;
1118 bool idle_notified = false;
1119
1120 while (1)
1121 {
1122 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1123
1124 switch ( ev.id )
1125 {
1126#ifdef HAVE_HOTSWAP
1127 case SYS_HOTSWAP_INSERTED:
1128 case SYS_HOTSWAP_EXTRACTED:
1129 fat_lock(); /* lock-out FAT activity first -
1130 prevent deadlocking via disk_mount that
1131 would cause a reverse-order attempt with
1132 another thread */
1133 mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
1134 into driver that bypass the fat cache */
1135
1136 /* We now have exclusive control of fat cache and ata */
1137
1138 disk_unmount(sd_first_drive+1); /* release "by force", ensure file
1139 descriptors aren't leaked and any busy
1140 ones are invalid if mounting */
1141
1142 /* Force card init for new card, re-init for re-inserted one or
1143 * clear if the last attempt to init failed with an error. */
1144 card_info[1].initialized = 0;
1145 sd_status[1].retry = 0;
1146
1147 if (ev.id == SYS_HOTSWAP_INSERTED)
1148 disk_mount(sd_first_drive+1);
1149
1150 queue_broadcast(SYS_FS_CHANGED, 0);
1151
1152 /* Access is now safe */
1153 mutex_unlock(&sd_mtx);
1154 fat_unlock();
1155 break;
1156#endif
1157 case SYS_TIMEOUT:
1158 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
1159 {
1160 idle_notified = false;
1161 }
1162 else
1163 {
1164 /* never let a timer wrap confuse us */
1165 next_yield = USEC_TIMER;
1166
1167 if (!idle_notified)
1168 {
1169 call_storage_idle_notifys(false);
1170 idle_notified = true;
1171 }
1172 }
1173 break;
1174 case SYS_USB_CONNECTED:
1175 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1176 /* Wait until the USB cable is extracted again */
1177 usb_wait_for_disconnect(&sd_queue);
1178 break;
1179
1180#ifdef SD_DRIVER_CLOSE
1181 case Q_CLOSE:
1182 return;
1183#endif
1184 }
1185 }
1186}
1187
1188#ifdef SD_DRIVER_CLOSE
1189void sd_close(void)
1190{
1191 unsigned int thread_id = sd_thread_id;
1192
1193 if (thread_id == 0)
1194 return;
1195
1196 sd_thread_id = 0;
1197
1198 queue_post(&sd_queue, Q_CLOSE, 0);
1199 thread_wait(thread_id);
1200}
1201#endif /* SD_DRIVER_CLOSE */
1202
1203void sd_enable(bool on)
1204{
1205 if(on)
1206 {
1207 DEV_EN |= DEV_ATA; /* Enable controller */
1208 }
1209 else
1210 {
1211 DEV_EN &= ~DEV_ATA; /* Disable controller */
1212 }
1213}
1214
1215
1216int sd_init(void)
1217{
1218 int ret = 0;
1219
1220 if (!initialized)
1221 mutex_init(&sd_mtx);
1222
1223 mutex_lock(&sd_mtx);
1224
1225 led(false);
1226
1227 if (!initialized)
1228 {
1229 initialized = true;
1230
1231 /* init controller */
1232#if defined(PHILIPS_SA9200)
1233 GPIOA_ENABLE = 0x00;
1234 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
1235#else
1236 outl(inl(0x70000088) & ~(0x4), 0x70000088);
1237 outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
1238 GPO32_ENABLE |= 0x4;
1239
1240 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
1241 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
1242 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
1243#endif
1244
1245#ifdef HAVE_HOTSWAP
1246 /* enable card detection port - mask interrupt first */
1247#ifdef SANSA_E200
1248 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
1249
1250 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
1251 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
1252#elif defined SANSA_C200
1253 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
1254
1255 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
1256 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
1257#endif
1258#endif
1259 sd_select_device(0);
1260
1261 if (currcard->initialized < 0)
1262 ret = currcard->initialized;
1263
1264 queue_init(&sd_queue, true);
1265 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
1266 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1267 IF_COP(, CPU));
1268
1269 /* enable interupt for the mSD card */
1270 sleep(HZ/10);
1271#ifdef HAVE_HOTSWAP
1272#ifdef SANSA_E200
1273 CPU_INT_EN = HI_MASK;
1274 CPU_HI_INT_EN = GPIO0_MASK;
1275
1276 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
1277
1278 GPIOA_INT_CLR = 0x80;
1279
1280 /* enable the card detect interrupt */
1281 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
1282#elif defined SANSA_C200
1283 CPU_INT_EN = HI_MASK;
1284 CPU_HI_INT_EN = GPIO2_MASK;
1285
1286 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
1287
1288 GPIOL_INT_CLR = 0x08;
1289
1290 /* enable the card detect interrupt */
1291 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
1292#endif
1293#endif
1294 }
1295
1296 mutex_unlock(&sd_mtx);
1297
1298 return ret;
1299}
1300
1301tCardInfo *card_get_info_target(int card_no)
1302{
1303 return &card_info[card_no];
1304}
1305#ifdef HAVE_HOTSWAP
1306static int sd1_oneshot_callback(struct timeout *tmo)
1307{
1308 (void)tmo;
1309
1310 /* This is called only if the state was stable for 300ms - check state
1311 * and post appropriate event. */
1312 if (card_detect_target())
1313 queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
1314 else
1315 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1316
1317 return 0;
1318}
1319
1320/* called on insertion/removal interrupt */
1321void microsd_int(void)
1322{
1323 static struct timeout sd1_oneshot;
1324
1325#ifdef SANSA_E200
1326 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
1327 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
1328 GPIOA_INT_CLR = 0x80;
1329 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
1330
1331#elif defined SANSA_C200
1332 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
1333 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
1334 GPIOL_INT_CLR = 0x08;
1335 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
1336#endif
1337 timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
1338}
1339#endif /* HAVE_HOTSWAP */
1340
1341long sd_last_disk_activity(void)
1342{
1343 return last_disk_activity;
1344}
1345
1346#ifdef HAVE_HOTSWAP
1347bool sd_removable(IF_MD_NONVOID(int drive))
1348{
1349#ifndef HAVE_MULTIDRIVE
1350 const int drive=0;
1351#endif
1352 return (drive==1);
1353}
1354
1355bool sd_present(IF_MD_NONVOID(int drive))
1356{
1357#ifndef HAVE_MULTIDRIVE
1358 const int drive=0;
1359#endif
1360 if(drive==0)
1361 {
1362 return true;
1363 }
1364 else
1365 {
1366 return card_detect_target();
1367 }
1368}
1369#endif
1370
1371#ifdef CONFIG_STORAGE_MULTI
1372int sd_num_drives(int first_drive)
1373{
1374#ifdef HAVE_HOTSWAP
1375 /* Store which logical drive number(s) we have been assigned */
1376 sd_first_drive = first_drive;
1377#else
1378 (void)first_drive;
1379#endif
1380
1381#ifdef HAVE_MULTIDRIVE
1382 return 2;
1383#else
1384 return 1;
1385#endif
1386}
1387#endif