/dev/sdio/slot0
From WiiBrew
This allows access to the front SD slot.
Contents |
Ioctl listing
| Request number | Name | Input | Output | Notes |
|---|---|---|---|---|
| 1 | sd_hc_write8 | 6-word param array: [reg, 0, 0, 1 (reg size), data, 0] | none | reg and data should both be 8-bit values |
| 2 | sd_hc_read8 | 6-word param array: [reg, 0, 0, 1 (reg size), 0, 0] | 32-bit word | |
| 4 | sd_reset_card | none | 32-bit word | |
| 6 | sd_set_clock | 32-bit word: one half of the sdclk divisor: a power of two or zero. (usually, 1) | none | |
| 7 | sd_command | 9-word param array: [cmd, cmd_type, resp_type, arg, block_count, block_size, (u32)addr, 0, 0] | 4-word reply buffer ?? | input or output from command will go into the address point to by addr, which should be a physical pointer |
| 7 (ioctlv) | sd_data_command | 9-word param array: [cmd, cmd_type, resp_type, arg, block_count, block_size, (u32)addr, 0, 0], data buffer of arbitrary size (block_count * block_size?) | 4-word reply buffer? | |
| 11 | sd_get_status | none | 32-bit status register | |
| 12 | sd_get_ocr | none | 32-bit register |
GetDeviceStatus
SD_GetDeviceStatus u32 buffer ios_ioctl( sd_fd, 0x0B, 0, 0, &buffer, 4);
buffer contains the status of the SD slot:
- 1: SD card is inserted.
- 2: No SD card is inserted.
ResetDevice
SD_ResetDevice ios_ioctl( sd_fd, 4, 0, 0, buffer, 4);
GetOCRegister
SD_GetOCRegister ios_ioctl( sd_fd, 0xC, 0, 0, buffer, 4);
GetHCRegister
The host controller is just a standard SD host controller and you can directly read and write to its registers using the following two functions.
SD_GetHCRegister (untested iirc) ((u32*)inbuf)[0] = register_offset; ((u32*)inbuf)[3] = 1; ((u32*)inbuf)[4] = 0; ios_ioctl( sd_fd, 2, inbuf, 0x18, outbuf, 4);
SetHCRegister
SD_SetHCRegister ((u32*)inbuf)[0] = register_offset; ((u32*)inbuf)[3] = 1; ((u32*)inbuf)[4] = value; ios_ioctl( sd_fd, 1, inbuf, 0x18, 0, 0);
SendCMD
SD_SendCMD(cmd, cmd_type, resp_type, arg, buffer, block_count, sector_size) ((u32*)inbuf)[0]=cmd; ((u32*)inbuf)[1]=cmd_type; ((u32*)inbuf)[2]=resp_type; ((u32*)inbuf)[3]=arg; ((u32*)inbuf)[4]=block_count; ((u32*)inbuf)[5]=sector_size; ((u32*)inbuf)[6]=buffer; ((u32*)inbuf)[7]=0; // ? ((u32*)inbuf)[8]=0; // ? ios_ioctl( sd_fd, 7, inbuf, 0x24, outbuf, 0x10);
SD Commands
SD_SendCmd(0x10, 3, 1, 0x200, 0, 0, 0) card_set_blocklen(0x200) SD_SendCmd(0x37, 3, 1, ?, 0, 0, 0) set data bus width SD_SendCmd(7, 3, 2, sd_status&0xFFFF0000, 0, 0, 0) // select SD_SendCmd(7, 3, 2, 0, 0, 0, 0) // deselect IOS_Ioctl(fd, 11, 0, 0, (u32 *)&status, 4); // get status IOS_Ioctl(fd, 4, 0, 0, (u32 *)&status, 4) // reset and get status IOS_Ioctl(fd, 6, (u32 *)&clock, 4, 0, 0) // using 1 as clock seems to work
Set bus width to 4
SD_SendCmd(0x37, 3, 1, sd_status&0xFFFF0000, 0, 0, 0) SD_SendCmd(6, 3, 1, 2, 0, 0, 0) //Read the HCR register and AND it with ~0x2. If width is 4 bit OR it with 0x2 and write it back.
Block Read
IOS_ioctlv(fd, 7, 2 /* input n */, 1 /* output n */, vectors) // First vector is {0x12, 3, 1, blockno * 0x200, 1, 0x200, &buffer /* 0x200 bytes */, 1, 0}, the second one is the buffer again (WTF?) and the third one a 0x10 byte reply buffer. // Do a reset and a select before the first read and set block length to 0x200, bus width to 4 and clock to 1 to make this command work. // 0x12 is CMD18 READ_MULTIPLE_BLOCK // 3 seems to be CMDTYPE AC (Addressed Command) although it should be ADTC (Address Data Tranfer Command) // blockno * 0x200 (512) is the offset in bytes of the block as expected by CMD18 // 0x200 (512) is the default block size
Block Write
Works the same way as reading does. Just use 0x19 instead of 0x12 in the first vector. 0x19 is CMD25 WRITE_MULTIPLE_BLOCK

