added missing sdhc ipc calls

This commit is contained in:
Sven Peter 2009-04-12 18:29:20 +02:00 committed by bushing
parent 8792586575
commit 168ec956ae
2 changed files with 79 additions and 6 deletions

8
ipc.h
View File

@ -68,12 +68,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define IPC_SDMMC_ACK 0x0000
#define IPC_SDMMC_READ 0x0001
#define IPC_SDMMC_WRITE 0x0002
/*#define IPC_SD_MOUNT 0x0000
#define IPC_SD_SELECT 0x0001
#define IPC_SD_GETSTATE 0x0002
#define IPC_SD_READ 0x0003
#define IPC_SD_WRITE 0x0004
#define IPC_SD_GETSIZE 0x0005*/
#define IPC_SDMMC_STATE 0x0003
#define IPC_SDMMC_SIZE 0x0004
#define IPC_KEYS_GETOTP 0x0000
#define IPC_KEYS_GETEEP 0x0001

77
sdmmc.c
View File

@ -444,6 +444,75 @@ int sdmmc_write(struct device *dev, u32 blk_start, u32 blk_count, void *data)
return 0;
}
int sdmmc_get_sectors(struct device *dev)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_command cmd;
u8 *resp;
if (c->inserted == 0) {
gecko_printf("sdmmc: READ: no card inserted.\n");
return -1;
}
if (c->selected == 0) {
if (sdmmc_select(dev) < 0) {
gecko_printf("sdmmc: READ: cannot select card.\n");
return -1;
}
}
if (c->new_card == 1) {
gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n");
return -1;
}
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_SEND_CSD;
cmd.c_arg = ((u32)c->rca)<<16;
cmd.c_flags = SCF_RSP_R2;
sdmmc_host_exec_command(c, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_SEND_CSD failed for "
"card %d with %d", no, cmd.c_error);
return -1;
}
resp = (u8 *)cmd.c_resp;
int num_sectors;
if (resp[13] == 0xe) { // sdhc
unsigned int c_size = resp[7] << 16 | resp[6] << 8 | resp[5];
// sdhc_error(sdhci->reg_base, "sdhc mode, c_size=%u, card size = %uk", c_size, (c_size + 1)* 512);
// sdhci->timeout = 250 * 1000000; // spec says read timeout is 100ms and write/erase timeout is 250ms
num_sectors = (c_size + 1) * 1024; // number of 512-byte sectors
}
else {
unsigned int taac, nsac, read_bl_len, c_size, c_size_mult;
taac = resp[13];
nsac = resp[12];
read_bl_len = resp[9] & 0xF;
c_size = (resp[8] & 3) << 10;
c_size |= (resp[7] << 2);
c_size |= (resp[6] >> 6);
c_size_mult = (resp[5] & 3) << 1;
c_size_mult |= resp[4] >> 7;
// sdhc_error(sdhci->reg_base, "taac=%u nsac=%u read_bl_len=%u c_size=%u c_size_mult=%u card size=%u bytes",
// taac, nsac, read_bl_len, c_size, c_size_mult, (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len));
// static const unsigned int time_unit[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
// static const unsigned int time_value[] = {1, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80}; // must div by 10
// sdhci->timeout = time_unit[taac & 7] * time_value[(taac >> 3) & 0xf] / 10;
// sdhc_error(sdhci->reg_base, "calculated timeout = %uns", sdhci->timeout);
num_sectors = (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len) / 512;
}
// sdhc_error(sdhci->reg_base, "num sectors = %u", sdhci->num_sectors);
return num_sectors;
}
void sdmmc_ipc(volatile ipc_request *req)
{
int ret;
@ -466,6 +535,14 @@ void sdmmc_ipc(volatile ipc_request *req)
req->args[1], (void *)req->args[2]);
ipc_post(req->code, req->tag, 1, ret);
break;
case IPC_SDMMC_STATE:
ipc_post(req->code, req->tag, 1,
sdmmc_check_card(SDMMC_DEFAULT_DEVICE));
break;
case IPC_SDMMC_SIZE:
ipc_post(req->code, req->tag, 1,
sdmmc_get_sectors(SDMMC_DEFAULT_DEVICE));
break;
}
}