[BACK]Return to sdmmc_spi.c CVS log [TXT][DIR] Up to [local] / funnyos / dev / sdmmc

File: [local] / funnyos / dev / sdmmc / sdmmc_spi.c (download)

Revision 1.1, Thu Dec 20 15:23:15 2007 UTC (16 years, 5 months ago) by nbrk
Branch: MAIN

totally uncompleted implementation of SD/MMC protocol over SPI lines.
code is not finished yet, but commit it so i can hack at home

/*
 * $Id: sdmmc_spi.c,v 1.1 2007/12/20 15:23:15 nbrk Exp $
 */
#include <sys/types.h>
#include <sys/device.h>
#include <sys/bus_spi.h>

#include <dev/sdmmc/sdmmcvar.h>
#include <libkern/printf.h>

/*
 * SD/MMC conversation over SPI bus.
 */
struct spisdmmc_dd {
	struct spi_bus_handle *ss_sbhp;

//	struct sdmmc_bus_handle;
};

int 	spisdmmc_attach(struct device *, uint32_t, uint8_t);

struct driver spisdmmc_dr = {
	sizeof(struct spisdmmc_dd),
	spisdmmc_attach,
	NULL,
	NULL
};


int
spisdmmc_attach(struct device *self, uint32_t loc, uint8_t flags)
{
	struct spisdmmc_dd *ddp = self->dv_devdata;
	ddp->ss_sbhp = self->dv_parent->dv_aux;

	printf("SPI SD/MMC\n");

	return(0);
}


int
spisdmmc_init(struct spisdmmc_dd *ddp)
{
	uint8_t i, resp;

	/*
	 * Apply 80 clock pulses.
	 * XXX assert CS. (NPCS0)
	 */
	for (i = 0; i < 9; i++)
		spi_transmit(ddp->ss_sbhp, 0xff);

	/*
	 * Apply 16 clocks.
	 * XXX deassert CS.
	 */
	for (i = 0; i < 2; i ++)
		spi_transmit(ddp->ss_sbhp, 0xff);

	/*
	 * Send CMD0_GO_IDLE_STATE.
	 */
	spisdmmc_send_command(ddp, CMD0_GO_IDLE_STATE, 0, CMD0_HARDCODED_CRC);
	if (spisdmmc_get_response(ddp) != 0) {
		printf("spisdmmc_init: CMD0_GO_IDLE_STATE failed with %d\n", resp);

		return(-1);
	}

}


void
spisdmmc_send_command(struct spisdmmc_dd *ddp, uint8_t cmd, uint32_t arg, uint32_t crc)
{
	struct sdmmc_cmdframe sdcf;
	uint8_t i;

	/* construct frame */
	sdcf = sdmmc_command(cmd, arg, crc);

	/* transmit token */
	spi_transmit(ddp->ss_sbhp, sdcf.sc_cmd);

	/* transmit 32 bit argument XXX MSB first */
	for(i = 0; i < 4; i++)
		spi_transmit(ddp->ss_sbhp, ((sdcf.sc_arg & (0xff000000 >> i)) >> (8 * (4 - i + 1))) );

	/* transmit CRC field */
	spi_transmit(ddp->ss_sbhp, sdcf.sc_cmd)

}