5858#define SDIOHCR_SOFTWARERESET 0x2f
5959
6060#define SDIOHCR_HOSTCONTROL_4BIT 0x02
61+ #define SDIOHCR_HOSTCONTROL_HS 0x04
6162
62- #define SDIO_DEFAULT_TIMEOUT 0xe
63+ #define SDIO_DEFAULT_TIMEOUT 0x0e
6364
6465#define IOCTL_SDIO_WRITEHCREG 0x01
6566#define IOCTL_SDIO_READHCREG 0x02
8485#define SDIO_RESPONSE_NONE 0
8586#define SDIO_RESPONSE_R1 1
8687#define SDIO_RESPONSE_R1B 2
87- #define SDIO_RESPOSNE_R2 3
88+ #define SDIO_RESPONSE_R2 3
8889#define SDIO_RESPONSE_R3 4
8990#define SDIO_RESPONSE_R4 5
9091#define SDIO_RESPONSE_R5 6
9394#define SDIO_CMD_GOIDLE 0x00
9495#define SDIO_CMD_ALL_SENDCID 0x02
9596#define SDIO_CMD_SENDRCA 0x03
97+ #define SDIO_CMD_SWITCHFUNC 0x06
9698#define SDIO_CMD_SELECT 0x07
9799#define SDIO_CMD_DESELECT 0x07
98100#define SDIO_CMD_SENDIFCOND 0x08
111113#define SDIO_ACMD_SENDOPCOND 0x29
112114
113115#define SDIO_STATUS_CARD_INSERTED 0x1
116+ #define SDIO_STATUS_CARD_LOCKED 0x4
114117#define SDIO_STATUS_CARD_INITIALIZED 0x10000
115118#define SDIO_STATUS_CARD_SDHC 0x100000
116119
117- #define READ_BL_LEN ((u8)(__sd0_csd[5]&0x0f))
118- #define WRITE_BL_LEN ((u8)(((__sd0_csd[12]&0x03)<<2)|((__sd0_csd[13]>>6)&0x03)))
119-
120+ #define TRAN_SPEED ((u8)(__sd0_csd[8]))
121+ #define CCC ((u16)((__sd0_csd[9]<<4)|((__sd0_csd[10]>>4)&0x0f)))
120122static u8 * rw_buffer = NULL ;
121123
122124struct _sdiorequest
@@ -142,13 +144,11 @@ static s32 hId = -1;
142144
143145static s32 __sd0_fd = -1 ;
144146static u16 __sd0_rca = 0 ;
145- static s32 __sd0_initialized = 0 ;
146147static s32 __sd0_sdhc = 0 ;
147- // static u8 __sd0_csd[16];
148+ static u8 __sd0_csd [16 ];
148149static u8 __sd0_cid [16 ];
149-
150- static s32 __sdio_initialized = 0 ;
151-
150+ static u8 __sd0_functions [64 ] ATTRIBUTE_ALIGN (32 );
151+ static bool __sdio_initialized = false;
152152static char _sd0_fs [] ATTRIBUTE_ALIGN (32 ) = "/dev/sdio/slot0" ;
153153
154154static s32 __sdio_sendcommand (u32 cmd ,u32 cmd_type ,u32 rsp_type ,u32 arg ,u32 blk_cnt ,u32 blk_size ,void * buffer ,void * reply ,u32 rlen )
@@ -277,7 +277,7 @@ static s32 __sdio_waithcr(u8 reg, u8 size, u8 unset, u32 mask)
277277 return -1 ;
278278}
279279
280- static s32 __sdio_setbuswidth (u32 bus_width )
280+ static s32 __sdio_setbuswidth (bool enable , u8 function )
281281{
282282 s32 ret ;
283283 u32 hc_reg = 0 ;
@@ -286,8 +286,8 @@ static s32 __sdio_setbuswidth(u32 bus_width)
286286 if (ret < 0 ) return ret ;
287287
288288 hc_reg &= 0xff ;
289- hc_reg &= ~SDIOHCR_HOSTCONTROL_4BIT ;
290- if (bus_width == 4 ) hc_reg |= SDIOHCR_HOSTCONTROL_4BIT ;
289+ hc_reg &= ~function ;
290+ if (enable ) hc_reg |= function ;
291291
292292 return __sdio_sethcr (SDIOHCR_HOSTCONTROL , 1 , hc_reg );
293293}
@@ -356,26 +356,25 @@ static s32 __sd0_setbuswidth(u32 bus_width)
356356 if (ret < 0 ) return ret ;
357357
358358 ret = __sdio_sendcommand (SDIO_ACMD_SETBUSWIDTH ,SDIOCMD_TYPE_AC ,SDIO_RESPONSE_R1 ,val ,0 ,0 ,NULL ,NULL ,0 );
359-
360- return ret ;
359+ if (ret < 0 ) return ret ;
360+
361+ return __sdio_setbuswidth (bus_width == 4 , SDIOHCR_HOSTCONTROL_4BIT );
361362}
362363
363- #if 0
364364static s32 __sd0_getcsd (void )
365365{
366366 s32 ret ;
367367
368- ret = __sdio_sendcommand (SDIO_CMD_SENDCSD ,SDIOCMD_TYPE_AC ,SDIO_RESPOSNE_R2 ,(__sd0_rca <<16 ),0 ,0 ,NULL ,__sd0_csd ,16 );
368+ ret = __sdio_sendcommand (SDIO_CMD_SENDCSD ,SDIOCMD_TYPE_AC ,SDIO_RESPONSE_R2 ,(__sd0_rca <<16 ),0 ,0 ,NULL ,__sd0_csd ,sizeof ( __sd0_csd ) );
369369
370370 return ret ;
371371}
372- #endif
373372
374373static s32 __sd0_getcid (void )
375374{
376375 s32 ret ;
377376
378- ret = __sdio_sendcommand (SDIO_CMD_ALL_SENDCID ,0 ,SDIO_RESPOSNE_R2 ,(__sd0_rca <<16 ),0 ,0 ,NULL ,__sd0_cid ,16 );
377+ ret = __sdio_sendcommand (SDIO_CMD_ALL_SENDCID ,0 ,SDIO_RESPONSE_R2 ,(__sd0_rca <<16 ),0 ,0 ,NULL ,__sd0_cid ,sizeof ( __sd0_cid ) );
379378
380379 return ret ;
381380}
@@ -386,6 +385,7 @@ static bool __sd0_initio(void)
386385 s32 ret ;
387386 s32 tries ;
388387 u32 status ;
388+ u32 clock = 1 ;
389389 struct _sdioresponse resp ;
390390
391391 __sdio_resetcard ();
@@ -466,30 +466,57 @@ static bool __sd0_initio(void)
466466 __sd0_sdhc = 1 ;
467467 else
468468 __sd0_sdhc = 0 ;
469-
470- ret = __sdio_setbuswidth (4 );
471- if (ret < 0 ) return false;
472-
473- ret = __sdio_setclock (1 );
469+
470+ ret = __sd0_getcsd ();
474471 if (ret < 0 ) return false;
475472
476473 ret = __sd0_select ();
477474 if (ret < 0 ) return false;
478475
479476 ret = __sd0_setblocklength (PAGE_SIZE512 );
480477 if (ret < 0 ) {
481- ret = __sd0_deselect ();
478+ __sd0_deselect ();
482479 return false;
483480 }
484481
485482 ret = __sd0_setbuswidth (4 );
486483 if (ret < 0 ) {
487- ret = __sd0_deselect ();
484+ __sd0_deselect ();
488485 return false;
489486 }
490- __sd0_deselect ();
491487
492- __sd0_initialized = 1 ;
488+ if (CCC & (1 << 10 )) {
489+ ret = __sdio_sendcommand (SDIO_CMD_SWITCHFUNC , 1 , SDIO_RESPONSE_R1 , 0x00fffff0 , 1 , sizeof (__sd0_functions ), __sd0_functions , NULL , 0 );
490+ if (ret < 0 ) {
491+ __sd0_deselect ();
492+ return false;
493+ }
494+
495+ if (((u16 * )__sd0_functions )[6 ] & (1 << 1 )) {
496+ ret = __sdio_sendcommand (SDIO_CMD_SWITCHFUNC , 1 , SDIO_RESPONSE_R1 , 0x80fffff1 , 1 , sizeof (__sd0_functions ), __sd0_functions , NULL , 0 );
497+ if (ret < 0 ) {
498+ __sd0_deselect ();
499+ return false;
500+ }
501+
502+ if ((__sd0_functions [16 ] & 0xf ) == 1 ) {
503+ ret = __sdio_setbuswidth (true, SDIOHCR_HOSTCONTROL_HS );
504+ if (ret < 0 ) {
505+ __sd0_deselect ();
506+ return false;
507+ }
508+ clock = 0 ;
509+ }
510+ }
511+ }
512+
513+ ret = __sdio_setclock (clock );
514+ if (ret < 0 ) {
515+ __sd0_deselect ();
516+ return false;
517+ }
518+
519+ __sd0_deselect ();
493520 return true;
494521
495522 fail :
@@ -506,13 +533,13 @@ static bool sdio_Deinitialize(void)
506533 IOS_Close (__sd0_fd );
507534
508535 __sd0_fd = -1 ;
509- __sdio_initialized = 0 ;
536+ __sdio_initialized = false ;
510537 return true;
511538}
512539
513540static bool sdio_Startup (void )
514541{
515- if (__sdio_initialized == 1 ) return true;
542+ if (__sdio_initialized ) return true;
516543
517544 if (hId < 0 ) {
518545 hId = iosCreateHeap (SDIO_HEAPSIZE );
@@ -533,17 +560,15 @@ static bool sdio_Startup(void)
533560 sdio_Deinitialize ();
534561 return false;
535562 }
536- __sdio_initialized = 1 ;
563+ __sdio_initialized = true ;
537564 return true;
538565}
539566
540567static bool sdio_Shutdown (void )
541568{
542- if (__sd0_initialized == 0 ) return false;
569+ if (! __sdio_initialized ) return false;
543570
544571 sdio_Deinitialize ();
545-
546- __sd0_initialized = 0 ;
547572 return true;
548573}
549574
@@ -554,6 +579,7 @@ static bool sdio_ReadSectors(sec_t sector, sec_t numSectors,void* buffer)
554579 sec_t blk_off ;
555580
556581 if (buffer == NULL ) return false;
582+ if (!__sdio_initialized ) return false;
557583
558584 ret = __sd0_select ();
559585 if (ret < 0 ) return false;
@@ -592,6 +618,7 @@ static bool sdio_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer)
592618 u32 blk_off ;
593619
594620 if (buffer == NULL ) return false;
621+ if (!__sdio_initialized ) return false;
595622
596623 ret = __sd0_select ();
597624 if (ret < 0 ) return false;
@@ -630,17 +657,12 @@ static bool sdio_ClearStatus(void)
630657
631658static bool sdio_IsInserted (void )
632659{
660+ if (!__sdio_initialized ) return false;
661+
633662 return ((__sdio_getstatus () & SDIO_STATUS_CARD_INSERTED ) ==
634663 SDIO_STATUS_CARD_INSERTED );
635664}
636665
637- /*static bool sdio_IsInitialized(void)
638- {
639- return ((__sdio_getstatus() & SDIO_STATUS_CARD_INITIALIZED) ==
640- SDIO_STATUS_CARD_INITIALIZED);
641- }
642- */
643-
644666const DISC_INTERFACE __io_wiisd = {
645667 DEVICE_TYPE_WII_SD ,
646668 FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_SD ,
0 commit comments