From patchwork Fri Apr 23 00:39:33 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Make sd card spi mode to support write operation Date: Thu, 22 Apr 2010 14:39:33 -0000 From: =?utf-8?b?5LmU5bSH?= X-Patchwork-Id: 50775 Message-Id: <4BD0EC45.9010107@loongson.cn> To: qemu-devel@nongnu.org 0001-accroding-sdcard-spi-protocal-should-at-least-wait-8.patch: accroding sdcard spi protocal,should at least wait 8 spi clk,before response. 0002-make-sd-card-spi-mode-to-support-write.patch make sd card spi mode to support write. >From 96bc31a8103d19ef8876198c6ca99739deac0f2a Mon Sep 17 00:00:00 2001 From: qiaochong Date: Thu, 22 Apr 2010 19:39:18 +0800 Subject: [PATCH] make sd card spi mode to support write. --- hw/sd.c | 6 +----- hw/ssi-sd.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/hw/sd.c b/hw/sd.c index 7b345e7..5569dc6 100644 --- a/hw/sd.c +++ b/hw/sd.c @@ -900,13 +900,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, /* Block write commands (Class 4) */ case 24: /* CMD24: WRITE_SINGLE_BLOCK */ - if (sd->spi) - goto unimplemented_cmd; switch (sd->state) { case sd_transfer_state: /* Writing in SPI mode not implemented. */ - if (sd->spi) - break; sd->state = sd_receivingdata_state; sd->data_start = addr; sd->data_offset = 0; @@ -1643,7 +1639,7 @@ uint8_t sd_read_data(SDState *sd) int sd_data_ready(SDState *sd) { - return sd->state == sd_sendingdata_state; + return sd->state == sd_sendingdata_state?1:sd->state == sd_receivingdata_state?2:0; } void sd_enable(SDState *sd, int enable) diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c index 72a442c..6f196de 100644 --- a/hw/ssi-sd.c +++ b/hw/ssi-sd.c @@ -30,6 +30,8 @@ typedef enum { SSI_SD_RESPONSE, SSI_SD_DATA_START, SSI_SD_DATA_READ, + SSI_SD_DATA_START_WRITE, + SSI_SD_DATA_WRITE, } ssi_sd_mode; typedef struct { @@ -169,10 +171,13 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) DPRINTF("Response 0x%02x\n", s->response[s->response_pos]); return s->response[s->response_pos++]; } - if (sd_data_ready(s->sd)) { + if (sd_data_ready(s->sd)==1) { DPRINTF("Data read\n"); s->mode = SSI_SD_DATA_START; - } else { + } else if (sd_data_ready(s->sd)==2) { + s->mode = SSI_SD_DATA_START_WRITE; + } + else { DPRINTF("End of command\n"); s->mode = SSI_SD_CMD; } @@ -188,6 +193,18 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) s->mode = SSI_SD_CMD; } return val; + case SSI_SD_DATA_START_WRITE: + DPRINTF("Start write block\n"); + if(val==0xfe) + s->mode = SSI_SD_DATA_WRITE; + return 0xff; + case SSI_SD_DATA_WRITE: + sd_write_data(s->sd,val); + if (!sd_data_ready(s->sd)) { + DPRINTF("Data write end\n"); + s->mode = SSI_SD_CMD; + } + return 0xff; } /* Should never happen. */ return 0xff; -- 1.5.6.5