1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2011 by Amaury Pouly
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 ****************************************************************************/
25 #include "ssp-imx233.h"
26 #include "pinctrl-imx233.h"
27 #include "partitions-imx233.h"
28 #include "button-target.h"
37 const char *name
; /* name(for debug) */
38 int flags
; /* flags */
39 int power_pin
; /* power pin */
40 int power_delay
; /* extra power up delay */
41 int ssp
; /* associated ssp block */
42 int mode
; /* mode (SD vs MMC) */
46 #define POWER_PIN (1 << 0)
47 #define POWER_INVERTED (1 << 1)
48 #define REMOVABLE (1 << 2)
49 #define DETECT_INVERTED (1 << 3)
50 #define POWER_DELAY (1 << 4)
51 #define WINDOW (1 << 5)
57 #define PIN(bank,pin) ((bank) << 5 | (pin))
58 #define PIN2BANK(v) ((v) >> 5)
59 #define PIN2PIN(v) ((v) & 0x1f)
61 struct sdmmc_config_t sdmmc_config
[] =
64 /* The Fuze+ uses pin #B0P8 for power */
67 .flags
= POWER_PIN
| POWER_INVERTED
| REMOVABLE
,
68 .power_pin
= PIN(0, 8),
72 /* The Fuze+ uses pin #B1P29 for power */
75 .flags
= POWER_PIN
| POWER_INVERTED
| WINDOW
| POWER_DELAY
,
76 .power_pin
= PIN(1, 29),
77 .power_delay
= HZ
/ 5, /* extra delay, to ramp up voltage? */
81 #elif defined(CREATIVE_ZENXFI2)
82 /* The Zen X-Fi2 uses pin B1P29 for power*/
85 .flags
= POWER_PIN
| REMOVABLE
| DETECT_INVERTED
,
86 .power_pin
= PIN(1, 29),
90 #elif defined(CREATIVE_ZENXFI3)
92 .name
= "internal/SD",
97 /* The Zen X-Fi3 uses pin #B0P07 for power*/
100 .flags
= POWER_PIN
| POWER_INVERTED
| REMOVABLE
| POWER_DELAY
,
101 .power_pin
= PIN(0, 7),
102 .power_delay
= HZ
/ 10, /* extra delay, to ramp up voltage? */
107 #error You need to write the sd/mmc config!
111 #define SDMMC_NUM_DRIVES (sizeof(sdmmc_config) / sizeof(sdmmc_config[0]))
113 #define SDMMC_CONF(drive) sdmmc_config[drive]
114 #define SDMMC_FLAGS(drive) SDMMC_CONF(drive).flags
115 #define SDMMC_SSP(drive) SDMMC_CONF(drive).ssp
116 #define SDMMC_MODE(drive) SDMMC_CONF(drive).mode
119 static unsigned window_start
[SDMMC_NUM_DRIVES
];
120 static unsigned window_end
[SDMMC_NUM_DRIVES
];
121 static uint8_t aligned_buffer
[SDMMC_NUM_DRIVES
][512] CACHEALIGN_ATTR
;
122 static tCardInfo sdmmc_card_info
[SDMMC_NUM_DRIVES
];
124 #define SDMMC_INFO(drive) sdmmc_card_info[drive]
125 #define SDMMC_RCA(drive) SDMMC_INFO(drive).rca
128 #if CONFIG_STORAGE & STORAGE_SD
129 static long sd_stack
[(DEFAULT_STACK_SIZE
*2 + 0x200)/sizeof(long)];
130 static struct mutex sd_mutex
;
131 static const char sd_thread_name
[] = "sd";
132 static struct event_queue sd_queue
;
133 static int sd_first_drive
;
134 static unsigned _sd_num_drives
;
135 static int _sd_last_disk_activity
;
136 static int sd_map
[SDMMC_NUM_DRIVES
]; /* sd->sdmmc map */
139 #if CONFIG_STORAGE & STORAGE_MMC
140 static int mmc_first_drive
;
141 static unsigned _mmc_num_drives
;
142 static int _mmc_last_disk_activity
;
143 static int mmc_map
[SDMMC_NUM_DRIVES
]; /* mmc->sdmmc map */
146 /* WARNING NOTE BUG FIXME
147 * There are three numbering schemes involved in the driver:
148 * - the sdmmc indexes into sdmmc_config[]
149 * - the sd drive indexes
150 * - the mmc drive indexes
151 * By convention, [drive] refers to a sdmmc index whereas sd_drive/mmc_drive
152 * refer to sd/mmc drive indexes. We keep two maps sd->sdmmc and mmc->sdmmc
153 * to find the sdmmc index from the sd or mmc one */
155 static void sdmmc_detect_callback(int ssp
)
157 /* This is called only if the state was stable for 300ms - check state
158 * and post appropriate event. */
159 if(imx233_ssp_sdmmc_detect(ssp
))
160 queue_broadcast(SYS_HOTSWAP_INSERTED
, 0);
162 queue_broadcast(SYS_HOTSWAP_EXTRACTED
, 0);
163 imx233_ssp_sdmmc_setup_detect(ssp
, true, sdmmc_detect_callback
, false,
164 imx233_ssp_sdmmc_is_detect_inverted(ssp
));
167 static void sdmmc_power(int drive
, bool on
)
169 /* power chip if needed */
170 if(SDMMC_FLAGS(drive
) & POWER_PIN
)
172 int bank
= PIN2BANK(SDMMC_CONF(drive
).power_pin
);
173 int pin
= PIN2PIN(SDMMC_CONF(drive
).power_pin
);
174 imx233_pinctrl_acquire_pin(bank
, pin
, "sd/mmc power");
175 imx233_set_pin_function(bank
, pin
, PINCTRL_FUNCTION_GPIO
);
176 imx233_enable_gpio_output(bank
, pin
, true);
177 if(SDMMC_FLAGS(drive
) & POWER_INVERTED
)
178 imx233_set_gpio_output(bank
, pin
, !on
);
180 imx233_set_gpio_output(bank
, pin
, on
);
182 if(SDMMC_FLAGS(drive
) & POWER_DELAY
)
183 sleep(SDMMC_CONF(drive
).power_delay
);
184 /* setup pins, never use alternatives pin on SSP1 because no device use it
185 * but this could be made a flag */
186 int bus_width
= SDMMC_MODE(drive
) == MMC_MODE
? 8 : 4;
187 if(SDMMC_SSP(drive
) == 1)
188 imx233_ssp_setup_ssp1_sd_mmc_pins(on
, bus_width
, PINCTRL_DRIVE_4mA
, false);
190 imx233_ssp_setup_ssp2_sd_mmc_pins(on
, bus_width
, PINCTRL_DRIVE_4mA
);
193 #define MCI_NO_RESP 0
194 #define MCI_RESP (1<<0)
195 #define MCI_LONG_RESP (1<<1)
196 #define MCI_ACMD (1<<2)
197 #define MCI_NOCRC (1<<3)
198 #define MCI_BUSY (1<<4)
200 static bool send_sd_cmd(int drive
, uint8_t cmd
, uint32_t arg
, uint32_t flags
, uint32_t *resp
)
202 if((flags
& MCI_ACMD
) && !send_sd_cmd(drive
, SD_APP_CMD
, SDMMC_RCA(drive
), MCI_RESP
, resp
))
205 enum imx233_ssp_resp_t resp_type
= (flags
& MCI_LONG_RESP
) ? SSP_LONG_RESP
:
206 (flags
& MCI_RESP
) ? SSP_SHORT_RESP
: SSP_NO_RESP
;
207 enum imx233_ssp_error_t ret
= imx233_ssp_sd_mmc_transfer(SDMMC_SSP(drive
), cmd
,
208 arg
, resp_type
, NULL
, 0, !!(flags
& MCI_BUSY
), false, resp
);
209 if(resp_type
== SSP_LONG_RESP
)
211 /* Our SD codes assume most significant word first, so reverse resp */
212 uint32_t tmp
= resp
[0];
219 return ret
== SSP_SUCCESS
;
222 static int wait_for_sd_tran_state(int drive
)
224 unsigned long response
;
225 unsigned int timeout
= current_tick
+ 5*HZ
;
230 while(!send_sd_cmd(drive
, SD_SEND_STATUS
, SDMMC_RCA(drive
), MCI_RESP
, &response
) && cmd_retry
> 0)
236 if(((response
>> 9) & 0xf) == SD_TRAN
)
239 if(TIME_AFTER(current_tick
, timeout
))
240 return -10 * ((response
>> 9) & 0xf);
242 _sd_last_disk_activity
= current_tick
;
248 #if CONFIG_STORAGE & STORAGE_SD
249 static int sdmmc_init_sd_card(int drive
)
251 int ssp
= SDMMC_SSP(drive
);
252 sdmmc_power(drive
, false);
253 sdmmc_power(drive
, true);
254 imx233_ssp_start(ssp
);
255 imx233_ssp_softreset(ssp
);
256 imx233_ssp_set_mode(ssp
, HW_SSP_CTRL1__SSP_MODE__SD_MMC
);
258 * gives bitrate of 96000 / 240 / 1 = 400kHz */
259 imx233_ssp_set_timings(ssp
, 240, 0, 0xffff);
261 imx233_ssp_sd_mmc_power_up_sequence(ssp
);
262 imx233_ssp_set_bus_width(ssp
, 1);
263 imx233_ssp_set_block_size(ssp
, 9);
265 SDMMC_RCA(drive
) = 0;
269 /* go to idle state */
270 if(!send_sd_cmd(drive
, SD_GO_IDLE_STATE
, 0, MCI_NO_RESP
, NULL
))
272 /* CMD8 Check for v2 sd card. Must be sent before using ACMD41
273 Non v2 cards will not respond to this command */
274 if(send_sd_cmd(drive
, SD_SEND_IF_COND
, 0x1AA, MCI_RESP
, &resp
))
275 if((resp
& 0xFFF) == 0x1AA)
277 /* timeout for initialization is 1sec, from SD Specification 2.00 */
278 init_timeout
= current_tick
+ HZ
;
281 /* this timeout is the only valid error for this loop*/
282 if(TIME_AFTER(current_tick
, init_timeout
))
285 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
286 if(!send_sd_cmd(drive
, SD_APP_OP_COND
, (0x00FF8000 | (sd_v2
? 1<<30 : 0)),
287 MCI_ACMD
|MCI_NOCRC
|MCI_RESP
, &SDMMC_INFO(drive
).ocr
))
289 } while(!(SDMMC_INFO(drive
).ocr
& (1<<31)));
292 if(!send_sd_cmd(drive
, SD_ALL_SEND_CID
, 0, MCI_RESP
|MCI_LONG_RESP
, SDMMC_INFO(drive
).cid
))
296 if(!send_sd_cmd(drive
, SD_SEND_RELATIVE_ADDR
, 0, MCI_RESP
, &SDMMC_INFO(drive
).rca
))
299 /* Try to switch V2 cards to HS timings, non HS seem to ignore this */
302 /* CMD7 w/rca: Select card to put it in TRAN state */
303 if(!send_sd_cmd(drive
, SD_SELECT_CARD
, SDMMC_RCA(drive
), MCI_RESP
, NULL
))
306 if(wait_for_sd_tran_state(drive
))
310 if(!send_sd_cmd(drive
, SD_SWITCH_FUNC
, 0x80fffff1, MCI_NO_RESP
, NULL
))
314 /* go back to STBY state so we can read csd */
315 /* CMD7 w/rca=0: Deselect card to put it in STBY state */
316 if(!send_sd_cmd(drive
, SD_DESELECT_CARD
, 0, MCI_NO_RESP
, NULL
))
321 if(!send_sd_cmd(drive
, SD_SEND_CSD
, SDMMC_RCA(drive
), MCI_RESP
|MCI_LONG_RESP
,
322 SDMMC_INFO(drive
).csd
))
325 sd_parse_csd(&SDMMC_INFO(drive
));
326 window_start
[drive
] = 0;
327 window_end
[drive
] = SDMMC_INFO(drive
).numblocks
;
330 * gives bitrate of 96 / 4 / 1 = 24MHz */
331 imx233_ssp_set_timings(ssp
, 4, 0, 0xffff);
333 /* CMD7 w/rca: Select card to put it in TRAN state */
334 if(!send_sd_cmd(drive
, SD_SELECT_CARD
, SDMMC_RCA(drive
), MCI_RESP
, &resp
))
336 if(wait_for_sd_tran_state(drive
) < 0)
339 /* ACMD6: set bus width to 4-bit */
340 if(!send_sd_cmd(drive
, SD_SET_BUS_WIDTH
, 2, MCI_RESP
|MCI_ACMD
, &resp
))
342 /* ACMD42: disconnect the pull-up resistor on CD/DAT3 */
343 if(!send_sd_cmd(drive
, SD_SET_CLR_CARD_DETECT
, 0, MCI_RESP
|MCI_ACMD
, &resp
))
346 /* Switch to 4-bit */
347 imx233_ssp_set_bus_width(ssp
, 4);
349 SDMMC_INFO(drive
).initialized
= 1;
354 static int transfer_sd_sectors(int drive
, unsigned long start
, int count
, void *buf
, bool read
)
359 _sd_last_disk_activity
= current_tick
;
361 mutex_lock(&sd_mutex
);
363 if(SDMMC_INFO(drive
).initialized
<= 0)
365 ret
= sdmmc_init_sd_card(drive
);
366 if(SDMMC_INFO(drive
).initialized
<= 0)
371 start
+= window_start
[drive
];
372 if((start
+ count
) > window_end
[drive
])
378 if(!send_sd_cmd(drive
, SD_SELECT_CARD
, SDMMC_RCA(drive
), MCI_NO_RESP
, NULL
))
383 ret
= wait_for_sd_tran_state(drive
);
388 /* FIXME implement this_count > 1 by using a sub-buffer of [sub] that is
389 * cache-aligned and then moving the data when possible. This way we could
390 * transfer much greater amount of data at once */
392 /* Set bank_start to the correct unit (blocks or bytes) */
393 int bank_start
= start
;
394 if(!(SDMMC_INFO(drive
).ocr
& (1<<30))) /* not SDHC */
395 bank_start
*= SD_BLOCK_SIZE
;
397 memcpy(aligned_buffer
[drive
], buf
, 512);
398 ret
= imx233_ssp_sd_mmc_transfer(SDMMC_SSP(drive
),
399 read
? SD_READ_MULTIPLE_BLOCK
: SD_WRITE_MULTIPLE_BLOCK
,
400 bank_start
, SSP_SHORT_RESP
, aligned_buffer
[drive
], this_count
, false, read
, &resp
);
401 if(ret
!= SSP_SUCCESS
)
403 if(!send_sd_cmd(drive
, SD_STOP_TRANSMISSION
, 0, MCI_RESP
|MCI_BUSY
, &resp
))
409 memcpy(buf
, aligned_buffer
[drive
], 512);
412 buf
+= this_count
* 512;
416 /* CMD7 w/rca =0 : deselects card & puts it in STBY state */
417 if(!send_sd_cmd(drive
, SD_DESELECT_CARD
, 0, MCI_NO_RESP
, NULL
))
420 mutex_unlock(&sd_mutex
);
425 #if CONFIG_STORAGE & STORAGE_MMC
426 static int transfer_mmc_sectors(int drive
, unsigned long start
, int count
, void *buf
, bool read
)
429 start
+= window_start
[drive
];
430 if((start
+ count
) > window_end
[drive
])
435 _mmc_last_disk_activity
= current_tick
;
439 /* FIXME implement this_count > 1 by using a sub-buffer of [sub] that is
440 * cache-aligned and then moving the data when possible. This way we could
441 * transfer much greater amount of data at once */
444 memcpy(aligned_buffer
[drive
], buf
, 512);
445 ret
= imx233_ssp_sd_mmc_transfer(SDMMC_SSP(drive
), read
? 17 : 24, start
,
446 SSP_SHORT_RESP
, aligned_buffer
[drive
], this_count
, false, read
, &resp
);
448 memcpy(buf
, aligned_buffer
[drive
], 512);
451 buf
+= this_count
* 512;
452 }while(count
!= 0 && ret
== SSP_SUCCESS
);
457 static int sdmmc_init_mmc_drive(int drive
)
459 int ssp
= SDMMC_SSP(drive
);
460 // we can choose the RCA of mmc cards: pick drive
461 SDMMC_RCA(drive
) = drive
;
463 sdmmc_power(drive
, false);
464 sdmmc_power(drive
, true);
465 imx233_ssp_start(ssp
);
466 imx233_ssp_softreset(ssp
);
467 imx233_ssp_set_mode(ssp
, HW_SSP_CTRL1__SSP_MODE__SD_MMC
);
469 * gives bitrate of 96000 / 240 / 1 = 400kHz */
470 imx233_ssp_set_timings(ssp
, 240, 0, 0xffff);
471 imx233_ssp_sd_mmc_power_up_sequence(ssp
);
472 imx233_ssp_set_bus_width(ssp
, 1);
473 imx233_ssp_set_block_size(ssp
, 9);
474 /* go to idle state */
475 int ret
= imx233_ssp_sd_mmc_transfer(ssp
, 0, 0, SSP_NO_RESP
, NULL
, 0, false, false, NULL
);
478 /* send op cond until the card respond with busy bit set; it must complete within 1sec */
479 unsigned timeout
= current_tick
+ HZ
;
483 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 1, 0x40ff8000, SSP_SHORT_RESP
, NULL
, 0, false, false, &ocr
);
484 if(ret
== 0 && ocr
& (1 << 31))
486 }while(!TIME_AFTER(current_tick
, timeout
));
492 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 2, 0, SSP_LONG_RESP
, NULL
, 0, false, false, cid
);
497 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 3, SDMMC_RCA(drive
) << 16, SSP_SHORT_RESP
, NULL
, 0, false, false, &status
);
501 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 7, SDMMC_RCA(drive
) << 16, SSP_SHORT_RESP
, NULL
, 0, false, false, &status
);
504 /* Check TRAN state */
505 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 13, SDMMC_RCA(drive
) << 16, SSP_SHORT_RESP
, NULL
, 0, false, false, &status
);
508 if(((status
>> 9) & 0xf) != 4)
510 /* Switch to 8-bit bus */
511 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 6, 0x3b70200, SSP_SHORT_RESP
, NULL
, 0, true, false, &status
);
517 imx233_ssp_set_bus_width(ssp
, 8);
518 /* Switch to high speed mode */
519 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 6, 0x3b90100, SSP_SHORT_RESP
, NULL
, 0, true, false, &status
);
526 * gives bitrate of 96 / 2 / 1 = 48MHz */
527 imx233_ssp_set_timings(ssp
, 2, 0, 0xffff);
529 /* read extended CSD */
531 uint8_t ext_csd
[512];
532 ret
= imx233_ssp_sd_mmc_transfer(ssp
, 8, 0, SSP_SHORT_RESP
, aligned_buffer
[drive
], 1, true, true, &status
);
535 memcpy(ext_csd
, aligned_buffer
[drive
], 512);
536 uint32_t *sec_count
= (void *)&ext_csd
[212];
537 window_start
[drive
] = 0;
538 window_end
[drive
] = *sec_count
;
545 static int sdmmc_read_sectors(int drive
, unsigned long start
, int count
, void* buf
)
547 switch(SDMMC_MODE(drive
))
549 #if CONFIG_STORAGE & STORAGE_SD
550 case SD_MODE
: return transfer_sd_sectors(drive
, start
, count
, buf
, true);
552 #if CONFIG_STORAGE & STORAGE_MMC
553 case MMC_MODE
: return transfer_mmc_sectors(drive
, start
, count
, buf
, true);
559 static int sdmmc_write_sectors(int drive
, unsigned long start
, int count
, const void* buf
)
561 switch(SDMMC_MODE(drive
))
563 #if CONFIG_STORAGE & STORAGE_SD
564 case SD_MODE
: return transfer_sd_sectors(drive
, start
, count
, (void *)buf
, false);
566 #if CONFIG_STORAGE & STORAGE_MMC
567 case MMC_MODE
: return transfer_mmc_sectors(drive
, start
, count
, (void *)buf
, false);
573 static int sdmmc_init_drive(int drive
)
576 switch(SDMMC_MODE(drive
))
578 #if CONFIG_STORAGE & STORAGE_SD
579 case SD_MODE
: ret
= sdmmc_init_sd_card(drive
); break;
581 #if CONFIG_STORAGE & STORAGE_MMC
582 case MMC_MODE
: ret
= sdmmc_init_mmc_drive(drive
); break;
590 if((SDMMC_FLAGS(drive
) & WINDOW
) && imx233_partitions_is_window_enabled())
593 int ret
= sdmmc_read_sectors(IF_MD2(drive
,) 0, 1, mbr
);
595 panicf("Cannot read MBR: %d", ret
);
596 ret
= imx233_partitions_compute_window(mbr
, &window_start
[drive
],
599 panicf("cannot compute partitions window: %d", ret
);
600 if(SDMMC_MODE(drive
) == SD_MODE
)
601 SDMMC_INFO(drive
).numblocks
= window_end
[drive
] - window_start
[drive
];
607 static void sd_thread(void) NORETURN_ATTR
;
608 static void sd_thread(void)
610 struct queue_event ev
;
614 queue_wait_w_tmo(&sd_queue
, &ev
, HZ
);
618 case SYS_HOTSWAP_INSERTED
:
619 case SYS_HOTSWAP_EXTRACTED
:
621 int microsd_init
= 1;
622 /* lock-out FAT activity first -
623 * prevent deadlocking via disk_mount that
624 * would cause a reverse-order attempt with
627 /* lock-out card activity - direct calls
628 * into driver that bypass the fat cache */
629 mutex_lock(&sd_mutex
);
631 /* We now have exclusive control of fat cache and sd.
632 * Release "by force", ensure file
633 * descriptors aren't leaked and any busy
634 * ones are invalid if mounting. */
635 for(unsigned sd_drive
= 0; sd_drive
< _sd_num_drives
; sd_drive
++)
637 /* Skip non-removable drivers */
638 if(!sd_removable(sd_drive
))
640 disk_unmount(sd_first_drive
+ sd_drive
);
641 /* Force card init for new card, re-init for re-inserted one or
642 * clear if the last attempt to init failed with an error. */
643 SDMMC_INFO(sd_map
[sd_drive
]).initialized
= 0;
645 if(ev
.id
== SYS_HOTSWAP_INSERTED
)
647 microsd_init
= sdmmc_init_drive(sd_map
[sd_drive
]);
648 if(microsd_init
< 0) /* initialisation failed */
649 panicf("%s init failed : %d", SDMMC_CONF(sd_map
[sd_drive
]).name
, microsd_init
);
651 microsd_init
= disk_mount(sd_first_drive
+ sd_drive
); /* 0 if fail */
654 * Mount succeeded, or this was an EXTRACTED event,
655 * in both cases notify the system about the changed filesystems
658 queue_broadcast(SYS_FS_CHANGED
, 0);
660 /* Access is now safe */
661 mutex_unlock(&sd_mutex
);
666 if(!TIME_BEFORE(current_tick
, _sd_last_disk_activity
+ 3 * HZ
))
669 case SYS_USB_CONNECTED
:
670 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
671 /* Wait until the USB cable is extracted again */
672 usb_wait_for_disconnect(&sd_queue
);
680 static int is_initialized
= false;
683 is_initialized
= true;
685 #if CONFIG_STORAGE & STORAGE_SD
686 mutex_init(&sd_mutex
);
687 queue_init(&sd_queue
, true);
688 create_thread(sd_thread
, sd_stack
, sizeof(sd_stack
), 0,
689 sd_thread_name
IF_PRIO(, PRIORITY_USER_INTERFACE
) IF_COP(, CPU
));
692 for(unsigned drive
= 0; drive
< SDMMC_NUM_DRIVES
; drive
++)
694 if(SDMMC_FLAGS(drive
) & REMOVABLE
)
695 imx233_ssp_sdmmc_setup_detect(SDMMC_SSP(drive
), true, sdmmc_detect_callback
,
696 false, SDMMC_FLAGS(drive
) & DETECT_INVERTED
);
702 static int sdmmc_present(int drive
)
704 if(SDMMC_FLAGS(drive
) & REMOVABLE
)
705 return imx233_ssp_sdmmc_detect(SDMMC_SSP(drive
));
710 static inline int sdmmc_removable(int drive
)
712 return SDMMC_FLAGS(drive
) & REMOVABLE
;
715 #if CONFIG_STORAGE & STORAGE_SD
718 int ret
= sdmmc_init();
719 if(ret
< 0) return ret
;
722 for(unsigned drive
= 0; drive
< SDMMC_NUM_DRIVES
; drive
++)
723 if(SDMMC_MODE(drive
) == SD_MODE
)
724 sd_map
[_sd_num_drives
++] = drive
;
728 tCardInfo
*card_get_info_target(int sd_card_no
)
730 return &SDMMC_INFO(sd_map
[sd_card_no
]);
733 int sd_num_drives(int first_drive
)
735 sd_first_drive
= first_drive
;
736 return _sd_num_drives
;
739 bool sd_present(IF_MV_NONVOID(int sd_drive
))
741 return sdmmc_present(sd_map
[sd_drive
]);
744 bool sd_removable(IF_MV_NONVOID(int sd_drive
))
746 return sdmmc_removable(sd_map
[sd_drive
]);
749 long sd_last_disk_activity(void)
751 return _sd_last_disk_activity
;
754 void sd_enable(bool on
)
759 int sd_read_sectors(IF_MD2(int sd_drive
,) unsigned long start
, int count
, void *buf
)
761 return sdmmc_read_sectors(sd_map
[sd_drive
], start
, count
, buf
);
764 int sd_write_sectors(IF_MD2(int sd_drive
,) unsigned long start
, int count
, const void* buf
)
766 return sdmmc_write_sectors(sd_map
[sd_drive
], start
, count
, buf
);
770 #if CONFIG_STORAGE & STORAGE_MMC
773 int ret
= sdmmc_init();
774 if(ret
< 0) return ret
;
777 for(unsigned drive
= 0; drive
< SDMMC_NUM_DRIVES
; drive
++)
778 if(SDMMC_MODE(drive
) == MMC_MODE
)
780 mmc_map
[_mmc_num_drives
++] = drive
;
781 sdmmc_init_drive(drive
);
786 void mmc_get_info(IF_MD2(int mmc_drive
,) struct storage_info
*info
)
788 int drive
= mmc_map
[mmc_drive
];
789 info
->sector_size
= 512;
790 info
->num_sectors
= window_end
[drive
] - window_start
[drive
];
791 info
->vendor
= "Rockbox";
792 info
->product
= "Internal Storage";
793 info
->revision
= "0.00";
796 int mmc_num_drives(int first_drive
)
798 mmc_first_drive
= first_drive
;
799 return _mmc_num_drives
;
802 bool mmc_present(IF_MV_NONVOID(int mmc_drive
))
804 return sdmmc_present(mmc_map
[mmc_drive
]);
807 bool mmc_removable(IF_MV_NONVOID(int mmc_drive
))
809 return sdmmc_removable(mmc_map
[mmc_drive
]);
812 long mmc_last_disk_activity(void)
814 return _mmc_last_disk_activity
;
817 void mmc_enable(bool on
)
826 void mmc_sleepnow(void)
830 bool mmc_disk_is_active(void)
835 bool mmc_usb_active(void)
837 return mmc_disk_is_active();
840 int mmc_soft_reset(void)
854 void mmc_spindown(int seconds
)
859 int mmc_spinup_time(void)
864 int mmc_read_sectors(IF_MD2(int mmc_drive
,) unsigned long start
, int count
, void *buf
)
866 return sdmmc_read_sectors(mmc_map
[mmc_drive
], start
, count
, buf
);
869 int mmc_write_sectors(IF_MD2(int mmc_drive
,) unsigned long start
, int count
, const void* buf
)
871 return sdmmc_write_sectors(mmc_map
[mmc_drive
], start
, count
, buf
);