Home | History | Annotate | Line # | Download | only in t_sh7706lan
scimci.c revision 1.4
      1 /*	$NetBSD: scimci.c,v 1.4 2021/08/07 16:18:53 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /*
     29  * Serial Peripheral interface driver to access MMC card
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: scimci.c,v 1.4 2021/08/07 16:18:53 thorpej Exp $");
     34 
     35 #include <sys/param.h>
     36 #include <sys/device.h>
     37 #include <sys/systm.h>
     38 #include <sys/malloc.h>
     39 #include <sys/kernel.h>
     40 #include <sys/proc.h>
     41 #include <sys/bus.h>
     42 #include <sys/intr.h>
     43 
     44 #include <sh3/devreg.h>
     45 #include <sh3/pfcreg.h>
     46 #include <sh3/scireg.h>
     47 
     48 #include <dev/sdmmc/sdmmcvar.h>
     49 #include <dev/sdmmc/sdmmcchip.h>
     50 
     51 #include <evbsh3/t_sh7706lan/t_sh7706lanvar.h>
     52 
     53 #ifdef SCIMCI_DEBUG
     54 int scimci_debug = 1;
     55 #define DPRINTF(n,s)	do { if ((n) <= scimci_debug) printf s; } while (0)
     56 #else
     57 #define DPRINTF(n,s)	do {} while (0)
     58 #endif
     59 
     60 static int	scimci_host_reset(sdmmc_chipset_handle_t);
     61 static uint32_t	scimci_host_ocr(sdmmc_chipset_handle_t);
     62 static int	scimci_host_maxblklen(sdmmc_chipset_handle_t);
     63 static int	scimci_card_detect(sdmmc_chipset_handle_t);
     64 static int	scimci_write_protect(sdmmc_chipset_handle_t);
     65 static int	scimci_bus_power(sdmmc_chipset_handle_t, uint32_t);
     66 static int	scimci_bus_clock(sdmmc_chipset_handle_t, int);
     67 static int	scimci_bus_width(sdmmc_chipset_handle_t, int);
     68 static void	scimci_exec_command(sdmmc_chipset_handle_t,
     69 		    struct sdmmc_command *);
     70 
     71 static struct sdmmc_chip_functions scimci_chip_functions = {
     72 	/* host controller reset */
     73 	.host_reset		= scimci_host_reset,
     74 
     75 	/* host controller capabilities */
     76 	.host_ocr		= scimci_host_ocr,
     77 	.host_maxblklen		= scimci_host_maxblklen,
     78 
     79 	/* card detection */
     80 	.card_detect		= scimci_card_detect,
     81 
     82 	/* write protect */
     83 	.write_protect		= scimci_write_protect,
     84 
     85 	/* bus power, clock frequency, width */
     86 	.bus_power		= scimci_bus_power,
     87 	.bus_clock		= scimci_bus_clock,
     88 	.bus_width		= scimci_bus_width,
     89 
     90 	/* command execution */
     91 	.exec_command		= scimci_exec_command,
     92 
     93 	/* card interrupt */
     94 	.card_enable_intr	= NULL,
     95 	.card_intr_ack		= NULL,
     96 };
     97 
     98 static void	scimci_spi_initialize(sdmmc_chipset_handle_t);
     99 
    100 static struct sdmmc_spi_chip_functions scimci_spi_chip_functions = {
    101 	.initialize		= scimci_spi_initialize,
    102 };
    103 
    104 #define	CSR_SET_1(reg,set,mask) 					\
    105 do {									\
    106 	uint8_t _r;							\
    107 	_r = _reg_read_1((reg));					\
    108 	_r &= ~(mask);							\
    109 	_r |= (set);							\
    110 	_reg_write_1((reg), _r);					\
    111 } while (/*CONSTCOND*/0)
    112 
    113 #define	CSR_SET_2(reg,set,mask) 					\
    114 do {									\
    115 	uint16_t _r;							\
    116 	_r = _reg_read_2((reg));					\
    117 	_r &= ~(mask);							\
    118 	_r |= (set);							\
    119 	_reg_write_2((reg), _r);					\
    120 } while (/*CONSTCOND*/0)
    121 
    122 #define	CSR_CLR_1(reg,clr)	 					\
    123 do {									\
    124 	uint8_t _r;							\
    125 	_r = _reg_read_1((reg));					\
    126 	_r &= ~(clr);							\
    127 	_reg_write_1((reg), _r);					\
    128 } while (/*CONSTCOND*/0)
    129 
    130 #define	CSR_CLR_2(reg,clr)	 					\
    131 do {									\
    132 	uint16_t _r;							\
    133 	_r = _reg_read_2((reg));					\
    134 	_r &= ~(clr);							\
    135 	_reg_write_2((reg), _r);					\
    136 } while (/*CONSTCOND*/0)
    137 
    138 #define SCPCR_CLK_MASK	0x000C
    139 #define SCPCR_CLK_IN	0x000C
    140 #define SCPCR_CLK_OUT	0x0004
    141 #define SCPDR_CLK	0x02
    142 #define SCPCR_DAT_MASK	0x0003
    143 #define SCPCR_DAT_IN	0x0003
    144 #define SCPCR_DAT_OUT	0x0001
    145 #define SCPDR_DAT	0x01
    146 #define SCPCR_CMD_MASK	0x0030
    147 #define SCPCR_CMD_IN	0x0030
    148 #define SCPCR_CMD_OUT	0x0010
    149 #define SCPDR_CMD	0x04
    150 #define SCPCR_CS_MASK	0x00C0
    151 #define SCPCR_CS_IN	0x00C0
    152 #define SCPCR_CS_OUT	0x0040
    153 #define SCPDR_CS	0x08
    154 #define PGCR_EJECT	0x0300
    155 #define PGDR_EJECT	0x10
    156 
    157 /* SCSCR */
    158 #define SCSCR_SCK_OUT	0
    159 #define SCSCR_SCK_IN	(SCSCR_CKE1)
    160 
    161 #define LOW_SPEED	144
    162 #define MID_SPEED	48
    163 #define MMC_TIME_OVER	1000
    164 
    165 struct scimci_softc {
    166 	device_t sc_dev;
    167 	device_t sc_sdmmc;
    168 };
    169 
    170 static int scimci_match(device_t, cfdata_t, void *);
    171 static void scimci_attach(device_t, device_t, void *);
    172 
    173 CFATTACH_DECL_NEW(scimci, sizeof(struct scimci_softc),
    174     scimci_match, scimci_attach, NULL, NULL);
    175 
    176 static void scimci_putc(int);
    177 static void scimci_putc_sw(void);
    178 static int scimci_getc(void);
    179 static void scimci_getc_sw(void);
    180 static void scimci_cmd_cfgread(struct scimci_softc *, struct sdmmc_command *);
    181 static void scimci_cmd_read(struct scimci_softc *, struct sdmmc_command *);
    182 static void scimci_cmd_write(struct scimci_softc *, struct sdmmc_command *);
    183 
    184 void scimci_read_buffer(u_char *buf);
    185 void scimci_write_buffer(const u_char *buf);
    186 
    187 /*ARGSUSED*/
    188 static int
    189 scimci_match(device_t parent, cfdata_t cf, void *aux)
    190 {
    191 
    192 	if (IS_SH7706LSR)
    193 		return 0;
    194 	return 1;
    195 }
    196 
    197 /*ARGSUSED*/
    198 static void
    199 scimci_attach(device_t parent, device_t self, void *aux)
    200 {
    201 	struct scimci_softc *sc = device_private(self);
    202 	struct sdmmcbus_attach_args saa;
    203 
    204 	sc->sc_dev = self;
    205 
    206 	aprint_naive("\n");
    207 	aprint_normal(": SCI MMC controller\n");
    208 
    209 	/* Setup */
    210 	CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_OUT | SCPCR_CMD_OUT,
    211 	    SCPCR_CLK_MASK | SCPCR_CMD_MASK);
    212 	CSR_CLR_2(SH7709_SCPCR, SCPCR_CMD_MASK);
    213 	CSR_SET_1(SH7709_SCPDR, SCPDR_CLK | SCPDR_CMD, 0);
    214 	CSR_SET_2(SH7709_SCPCR, SCPCR_CS_OUT, SCPCR_CS_MASK);
    215 
    216 	SHREG_SCSCR = 0x00;
    217 	SHREG_SCSSR = 0x00;
    218 	SHREG_SCSCMR = 0xfa;	/* MSB first */
    219 	SHREG_SCSMR = SCSMR_CA;	/* clock sync mode */
    220 	SHREG_SCBRR = LOW_SPEED;
    221 	delay(1000);		/* wait 1ms */
    222 
    223 	/*
    224 	 * Attach the generic SD/MMC bus driver.  (The bus driver must
    225 	 * not invoke any chipset functions before it is attached.)
    226 	 */
    227 	memset(&saa, 0, sizeof(saa));
    228 	saa.saa_busname = "sdmmc";
    229 	saa.saa_sct = &scimci_chip_functions;
    230 	saa.saa_spi_sct = &scimci_spi_chip_functions;
    231 	saa.saa_sch = sc;
    232 	saa.saa_clkmin = 4000 / (LOW_SPEED + 1);
    233 	saa.saa_clkmax = 4000 / (MID_SPEED + 1);
    234 	saa.saa_caps = SMC_CAPS_SPI_MODE
    235 		     | SMC_CAPS_SINGLE_ONLY
    236 		     | SMC_CAPS_POLL_CARD_DET;
    237 
    238 	sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL, CFARGS_NONE);
    239 	if (sc->sc_sdmmc == NULL)
    240 		aprint_error_dev(sc->sc_dev, "couldn't attach bus\n");
    241 }
    242 
    243 /*
    244  * SCI access functions
    245  */
    246 static void
    247 scimci_putc(int c)
    248 {
    249 
    250 	CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_OUT, SCPCR_CLK_MASK);
    251 	SHREG_SCSCR = SCSCR_TE | SCSCR_SCK_OUT;
    252 	while ((SHREG_SCSSR & SCSSR_TDRE) == 0)
    253 		continue;
    254 	CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
    255 	SHREG_SCTDR = (uint8_t)c;
    256 	(void) SHREG_SCSSR;
    257 	SHREG_SCSSR = 0;
    258 }
    259 
    260 static void
    261 scimci_putc_sw(void)
    262 {
    263 
    264 	while ((SHREG_SCSSR & SCSSR_TEND) == 0)
    265 		continue;
    266 
    267 	CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_IN, 0);
    268 	SHREG_SCSCR |= SCSCR_SCK_IN;
    269 	CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
    270 	SHREG_SCSMR = 0;
    271 	SHREG_SCSCR = SCSCR_SCK_OUT;
    272 	SHREG_SCSSR = 0;
    273 	SHREG_SCSMR = SCSMR_CA;
    274 }
    275 
    276 static int
    277 scimci_getc(void)
    278 {
    279 	int c;
    280 
    281 	SHREG_SCSCR = SCSCR_RE | SCSCR_SCK_OUT;
    282 	if (SHREG_SCSSR & SCSSR_ORER) {
    283 		SHREG_SCSSR &= ~SCSSR_ORER;
    284 		return -1;
    285 	}
    286 	CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
    287 	while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
    288 		continue;
    289 	c = SHREG_SCRDR;
    290 	(void) SHREG_SCSSR;
    291 	SHREG_SCSSR = 0;
    292 
    293 	return (uint8_t)c;
    294 }
    295 
    296 static void
    297 scimci_getc_sw(void)
    298 {
    299 
    300 	SHREG_SCBRR = LOW_SPEED;
    301 	while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
    302 		continue;
    303 	(void) SHREG_SCRDR;
    304 
    305 	CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_IN, 0);
    306 	SHREG_SCSCR |= SCSCR_SCK_IN;
    307 	CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
    308 	SHREG_SCSMR = 0;
    309 	SHREG_SCSCR = SCSCR_SCK_OUT;
    310 	SHREG_SCSSR = 0;
    311 	SHREG_SCSMR = SCSMR_CA;
    312 }
    313 
    314 /*
    315  * Reset the host controller.  Called during initialization, when
    316  * cards are removed, upon resume, and during error recovery.
    317  */
    318 /*ARGSUSED*/
    319 static int
    320 scimci_host_reset(sdmmc_chipset_handle_t sch)
    321 {
    322 
    323 	return 0;
    324 }
    325 
    326 /*ARGSUSED*/
    327 static uint32_t
    328 scimci_host_ocr(sdmmc_chipset_handle_t sch)
    329 {
    330 
    331 	return MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V;
    332 }
    333 
    334 /*ARGSUSED*/
    335 static int
    336 scimci_host_maxblklen(sdmmc_chipset_handle_t sch)
    337 {
    338 
    339 	return 512;
    340 }
    341 
    342 /*ARGSUSED*/
    343 static int
    344 scimci_card_detect(sdmmc_chipset_handle_t sch)
    345 {
    346 	uint8_t reg;
    347 	int s;
    348 
    349 	s = splserial();
    350 	CSR_SET_2(SH7709_PGCR, PGCR_EJECT, 0);
    351 	reg = _reg_read_1(SH7709_PGDR);
    352 	splx(s);
    353 
    354 	return !(reg & PGDR_EJECT);
    355 }
    356 
    357 /*ARGSUSED*/
    358 static int
    359 scimci_write_protect(sdmmc_chipset_handle_t sch)
    360 {
    361 
    362 	return 0;	/* non-protect */
    363 }
    364 
    365 /*
    366  * Set or change SD bus voltage and enable or disable SD bus power.
    367  * Return zero on success.
    368  */
    369 /*ARGSUSED*/
    370 static int
    371 scimci_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
    372 {
    373 
    374 	if ((ocr & (MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) == 0)
    375 		return 1;
    376 
    377 	/*XXX???*/
    378 	return 0;
    379 }
    380 
    381 /*
    382  * Set or change MMCLK frequency or disable the MMC clock.
    383  * Return zero on success.
    384  */
    385 /*ARGSUSED*/
    386 static int
    387 scimci_bus_clock(sdmmc_chipset_handle_t sch, int freq)
    388 {
    389 
    390 	return 0;
    391 }
    392 
    393 /*ARGSUSED*/
    394 static int
    395 scimci_bus_width(sdmmc_chipset_handle_t sch, int width)
    396 {
    397 
    398 	if (width != 1)
    399 		return 1;
    400 	return 0;
    401 }
    402 
    403 /*ARGSUSED*/
    404 static void
    405 scimci_spi_initialize(sdmmc_chipset_handle_t sch)
    406 {
    407 	int i, s;
    408 
    409 	s = splserial();
    410 	CSR_SET_1(SH7709_SCPDR, SCPDR_CS, 0);
    411 	for (i = 0; i < 20; i++)
    412 		scimci_putc(0xff);
    413 	scimci_putc_sw();
    414 	CSR_CLR_1(SH7709_SCPDR, SCPDR_CS);
    415 	splx(s);
    416 }
    417 
    418 static void
    419 scimci_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
    420 {
    421 	struct scimci_softc *sc = (struct scimci_softc *)sch;
    422 	uint16_t resp;
    423 	int timo;
    424 	int s;
    425 
    426 	DPRINTF(1,("%s: start cmd %d arg=%#x data=%p dlen=%d flags=%#x "
    427 	    "proc=%p \"%s\"\n", device_xname(sc->sc_dev),
    428 	    cmd->c_opcode, cmd->c_arg, cmd->c_data, cmd->c_datalen,
    429 	    cmd->c_flags, curproc, curproc ? curproc->p_comm : ""));
    430 
    431 	s = splhigh();
    432 
    433 	if (cmd->c_opcode == MMC_GO_IDLE_STATE)
    434 		SHREG_SCBRR = LOW_SPEED;
    435 	else
    436 		SHREG_SCBRR = MID_SPEED;
    437 
    438 	scimci_putc(0xff);
    439 	scimci_putc(0x40 | (cmd->c_opcode & 0x3f));
    440 	scimci_putc((cmd->c_arg >> 24) & 0xff);
    441 	scimci_putc((cmd->c_arg >> 16) & 0xff);
    442 	scimci_putc((cmd->c_arg >> 8) & 0xff);
    443 	scimci_putc((cmd->c_arg >> 0) & 0xff);
    444 	scimci_putc((cmd->c_opcode == MMC_GO_IDLE_STATE) ? 0x95 :
    445 	    (cmd->c_opcode == SD_SEND_IF_COND) ? 0x87 : 0); /* CRC */
    446 	scimci_putc(0xff);
    447 	scimci_putc_sw();
    448 
    449 	timo = MMC_TIME_OVER;
    450 	while ((resp = scimci_getc()) & 0x80) {
    451 		if(--timo == 0) {
    452 			DPRINTF(1, ("%s: response timeout\n",
    453 			    device_xname(sc->sc_dev)));
    454 			scimci_getc_sw();
    455 			cmd->c_error = ETIMEDOUT;
    456 			goto out;
    457 		}
    458 	}
    459 	if (ISSET(cmd->c_flags, SCF_RSP_SPI_S2)) {
    460 		resp |= (uint16_t)scimci_getc() << 8;
    461 	} else if (ISSET(cmd->c_flags, SCF_RSP_SPI_B4)) {
    462 		cmd->c_resp[1] =  (uint32_t) scimci_getc() << 24;
    463 		cmd->c_resp[1] |= (uint32_t) scimci_getc() << 16;
    464 		cmd->c_resp[1] |= (uint32_t) scimci_getc() << 8;
    465 		cmd->c_resp[1] |= (uint32_t) scimci_getc();
    466 		DPRINTF(1, ("R3 resp: %#x\n", cmd->c_resp[1]));
    467 	}
    468 	scimci_getc_sw();
    469 
    470 	cmd->c_resp[0] = resp;
    471 	if (resp != 0 && resp != R1_SPI_IDLE) {
    472 		DPRINTF(1, ("%s: response error: %#x\n",
    473 		    device_xname(sc->sc_dev), resp));
    474 		cmd->c_error = EIO;
    475 		goto out;
    476 	}
    477 	DPRINTF(1, ("R1 resp: %#x\n", resp));
    478 
    479 	if (cmd->c_datalen > 0) {
    480 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    481 			/* XXX: swap in this place? */
    482 			if (cmd->c_opcode == MMC_SEND_CID ||
    483 			    cmd->c_opcode == MMC_SEND_CSD) {
    484 				sdmmc_response res;
    485 				uint32_t *p = cmd->c_data;
    486 
    487 				scimci_cmd_cfgread(sc, cmd);
    488 				res[0] = be32toh(p[3]);
    489 				res[1] = be32toh(p[2]);
    490 				res[2] = be32toh(p[1]);
    491 				res[3] = be32toh(p[0]);
    492 				memcpy(p, &res, sizeof(res));
    493 			} else {
    494 				scimci_cmd_read(sc, cmd);
    495 			}
    496 		} else {
    497 			scimci_cmd_write(sc, cmd);
    498 		}
    499 	}
    500 
    501 out:
    502 	SET(cmd->c_flags, SCF_ITSDONE);
    503 	splx(s);
    504 
    505 	DPRINTF(1,("%s: cmd %d done (flags=%#x error=%d)\n",
    506 	  device_xname(sc->sc_dev), cmd->c_opcode, cmd->c_flags, cmd->c_error));
    507 }
    508 
    509 static void
    510 scimci_cmd_cfgread(struct scimci_softc *sc, struct sdmmc_command *cmd)
    511 {
    512 	u_char *data = cmd->c_data;
    513 	int timo;
    514 	int c;
    515 	int i;
    516 
    517 	/* wait data token */
    518 	for (timo = MMC_TIME_OVER; timo > 0; timo--) {
    519 		c = scimci_getc();
    520 		if (c < 0) {
    521 			aprint_error_dev(sc->sc_dev, "cfg read i/o error\n");
    522 			cmd->c_error = EIO;
    523 			return;
    524 		}
    525 		if (c != 0xff)
    526 			break;
    527 	}
    528 	if (timo == 0) {
    529 		aprint_error_dev(sc->sc_dev, "cfg read timeout\n");
    530 		cmd->c_error = ETIMEDOUT;
    531 		return;
    532 	}
    533 	if (c != 0xfe) {
    534 		aprint_error_dev(sc->sc_dev, "cfg read error (data=%#x)\n", c);
    535 		cmd->c_error = EIO;
    536 		return;
    537 	}
    538 
    539 	/* data read */
    540 	SHREG_SCSCR = SCSCR_RE | SCSCR_SCK_OUT;
    541 	data[0] = '\0'; /* XXXFIXME!!! */
    542 	for (i = 1 /* XXXFIXME!!!*/ ; i < cmd->c_datalen; i++) {
    543 		while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
    544 			continue;
    545 		data[i] = SHREG_SCRDR;
    546 		(void) SHREG_SCSSR;
    547 		SHREG_SCSSR = 0;
    548 	}
    549 
    550 	SHREG_SCBRR = LOW_SPEED;
    551 	(void) scimci_getc();
    552 	(void) scimci_getc();
    553 	(void) scimci_getc();
    554 	scimci_getc_sw();
    555 
    556 #ifdef SCIMCI_DEBUG
    557 	sdmmc_dump_data(NULL, cmd->c_data, cmd->c_datalen);
    558 #endif
    559 }
    560 
    561 static void
    562 scimci_cmd_read(struct scimci_softc *sc, struct sdmmc_command *cmd)
    563 {
    564 	u_char *data = cmd->c_data;
    565 	int timo;
    566 	int c;
    567 	int i;
    568 
    569 	/* wait data token */
    570 	for (timo = MMC_TIME_OVER; timo > 0; timo--) {
    571 		c = scimci_getc();
    572 		if (c < 0) {
    573 			aprint_error_dev(sc->sc_dev, "read i/o error\n");
    574 			cmd->c_error = EIO;
    575 			return;
    576 		}
    577 		if (c != 0xff)
    578 			break;
    579 	}
    580 	if (timo == 0) {
    581 		aprint_error_dev(sc->sc_dev, "read timeout\n");
    582 		cmd->c_error = ETIMEDOUT;
    583 		return;
    584 	}
    585 	if (c != 0xfe) {
    586 		aprint_error_dev(sc->sc_dev, "read error (data=%#x)\n", c);
    587 		cmd->c_error = EIO;
    588 		return;
    589 	}
    590 
    591 	/* data read */
    592 	SHREG_SCBRR = MID_SPEED;
    593 	SHREG_SCSCR = SCSCR_RE | SCSCR_SCK_OUT;
    594 	for (i = 0; i < cmd->c_datalen; i++) {
    595 		while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
    596 			continue;
    597 		data[i] = SHREG_SCRDR;
    598 		(void) SHREG_SCSSR;
    599 		SHREG_SCSSR = 0;
    600 	}
    601 
    602 	SHREG_SCBRR = LOW_SPEED;
    603 	(void) scimci_getc();
    604 	(void) scimci_getc();
    605 	(void) scimci_getc();
    606 	scimci_getc_sw();
    607 
    608 #ifdef SCIMCI_DEBUG
    609 	sdmmc_dump_data(NULL, cmd->c_data, cmd->c_datalen);
    610 #endif
    611 }
    612 
    613 static void
    614 scimci_cmd_write(struct scimci_softc *sc, struct sdmmc_command *cmd)
    615 {
    616 	char *data = cmd->c_data;
    617 	int timo;
    618 	int c;
    619 	int i;
    620 
    621 	scimci_putc(0xff);
    622 	scimci_putc(0xfe);
    623 
    624 	/* data write */
    625 	SHREG_SCBRR = MID_SPEED;
    626 	SHREG_SCSCR = SCSCR_TE | SCSCR_SCK_OUT;
    627 	for (i = 0; i < cmd->c_datalen; i++) {
    628 		while ((SHREG_SCSSR & SCSSR_TDRE) == 0)
    629 			continue;
    630 		SHREG_SCTDR = data[i];
    631 		(void) SHREG_SCSSR;
    632 		SHREG_SCSSR = 0;
    633 	}
    634 
    635 	SHREG_SCBRR = LOW_SPEED;
    636 	scimci_putc(0);
    637 	scimci_putc(0);
    638 	scimci_putc(0);
    639 	scimci_putc_sw();
    640 
    641 	for (timo = MMC_TIME_OVER; timo > 0; timo--) {
    642 		c = scimci_getc();
    643 		if (c < 0) {
    644 			aprint_error_dev(sc->sc_dev, "write i/o error\n");
    645 			cmd->c_error = EIO;
    646 			scimci_getc_sw();
    647 			return;
    648 		}
    649 		if (c == 0xff)
    650 			break;
    651 	}
    652 	if (timo == 0) {
    653 		aprint_error_dev(sc->sc_dev, "write timeout\n");
    654 		cmd->c_error = ETIMEDOUT;
    655 	}
    656 	scimci_getc_sw();
    657 }
    658