mmc_spi.c

来自「linux 内核源代码」· C语言 代码 · 共 1,414 行 · 第 1/3 页

C
1,414
字号
			dev_dbg(&host->spi->dev, "bogus command\n");			cmd->error = -EINVAL;			invalid = 1;		}		cmd = mrq->stop;		if (cmd && !mmc_spi_resp_type(cmd)) {			dev_dbg(&host->spi->dev, "bogus STOP command\n");			cmd->error = -EINVAL;			invalid = 1;		}		if (invalid) {			dump_stack();			mmc_request_done(host->mmc, mrq);			return;		}	}#endif	/* issue command; then optionally data and stop */	status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);	if (status == 0 && mrq->data) {		mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz);		if (mrq->stop)			status = mmc_spi_command_send(host, mrq, mrq->stop, 0);		else			mmc_cs_off(host);	}	mmc_request_done(host->mmc, mrq);}/* See Section 6.4.1, in SD "Simplified Physical Layer Specification 2.0" * * NOTE that here we can't know that the card has just been powered up; * not all MMC/SD sockets support power switching. * * FIXME when the card is still in SPI mode, e.g. from a previous kernel, * this doesn't seem to do the right thing at all... */static void mmc_spi_initsequence(struct mmc_spi_host *host){	/* Try to be very sure any previous command has completed;	 * wait till not-busy, skip debris from any old commands.	 */	mmc_spi_wait_unbusy(host, r1b_timeout);	mmc_spi_readbytes(host, 10);	/*	 * Do a burst with chipselect active-high.  We need to do this to	 * meet the requirement of 74 clock cycles with both chipselect	 * and CMD (MOSI) high before CMD0 ... after the card has been	 * powered up to Vdd(min), and so is ready to take commands.	 *	 * Some cards are particularly needy of this (e.g. Viking "SD256")	 * while most others don't seem to care.	 *	 * Note that this is one of the places MMC/SD plays games with the	 * SPI protocol.  Another is that when chipselect is released while	 * the card returns BUSY status, the clock must issue several cycles	 * with chipselect high before the card will stop driving its output.	 */	host->spi->mode |= SPI_CS_HIGH;	if (spi_setup(host->spi) != 0) {		/* Just warn; most cards work without it. */		dev_warn(&host->spi->dev,				"can't change chip-select polarity\n");		host->spi->mode &= ~SPI_CS_HIGH;	} else {		mmc_spi_readbytes(host, 18);		host->spi->mode &= ~SPI_CS_HIGH;		if (spi_setup(host->spi) != 0) {			/* Wot, we can't get the same setup we had before? */			dev_err(&host->spi->dev,					"can't restore chip-select polarity\n");		}	}}static char *mmc_powerstring(u8 power_mode){	switch (power_mode) {	case MMC_POWER_OFF: return "off";	case MMC_POWER_UP:  return "up";	case MMC_POWER_ON:  return "on";	}	return "?";}static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios){	struct mmc_spi_host *host = mmc_priv(mmc);	if (host->power_mode != ios->power_mode) {		int		canpower;		canpower = host->pdata && host->pdata->setpower;		dev_dbg(&host->spi->dev, "mmc_spi: power %s (%d)%s\n",				mmc_powerstring(ios->power_mode),				ios->vdd,				canpower ? ", can switch" : "");		/* switch power on/off if possible, accounting for		 * max 250msec powerup time if needed.		 */		if (canpower) {			switch (ios->power_mode) {			case MMC_POWER_OFF:			case MMC_POWER_UP:				host->pdata->setpower(&host->spi->dev,						ios->vdd);				if (ios->power_mode == MMC_POWER_UP)					msleep(host->powerup_msecs);			}		}		/* See 6.4.1 in the simplified SD card physical spec 2.0 */		if (ios->power_mode == MMC_POWER_ON)			mmc_spi_initsequence(host);		/* If powering down, ground all card inputs to avoid power		 * delivery from data lines!  On a shared SPI bus, this		 * will probably be temporary; 6.4.2 of the simplified SD		 * spec says this must last at least 1msec.		 *		 *   - Clock low means CPOL 0, e.g. mode 0		 *   - MOSI low comes from writing zero		 *   - Chipselect is usually active low...		 */		if (canpower && ios->power_mode == MMC_POWER_OFF) {			int mres;			host->spi->mode &= ~(SPI_CPOL|SPI_CPHA);			mres = spi_setup(host->spi);			if (mres < 0)				dev_dbg(&host->spi->dev,					"switch to SPI mode 0 failed\n");			if (spi_w8r8(host->spi, 0x00) < 0)				dev_dbg(&host->spi->dev,					"put spi signals to low failed\n");			/*			 * Now clock should be low due to spi mode 0;			 * MOSI should be low because of written 0x00;			 * chipselect should be low (it is active low)			 * power supply is off, so now MMC is off too!			 *			 * FIXME no, chipselect can be high since the			 * device is inactive and SPI_CS_HIGH is clear...			 */			msleep(10);			if (mres == 0) {				host->spi->mode |= (SPI_CPOL|SPI_CPHA);				mres = spi_setup(host->spi);				if (mres < 0)					dev_dbg(&host->spi->dev,						"switch back to SPI mode 3"						" failed\n");			}		}		host->power_mode = ios->power_mode;	}	if (host->spi->max_speed_hz != ios->clock && ios->clock != 0) {		int		status;		host->spi->max_speed_hz = ios->clock;		status = spi_setup(host->spi);		dev_dbg(&host->spi->dev,			"mmc_spi:  clock to %d Hz, %d\n",			host->spi->max_speed_hz, status);	}}static int mmc_spi_get_ro(struct mmc_host *mmc){	struct mmc_spi_host *host = mmc_priv(mmc);	if (host->pdata && host->pdata->get_ro)		return host->pdata->get_ro(mmc->parent);	/* board doesn't support read only detection; assume writeable */	return 0;}static const struct mmc_host_ops mmc_spi_ops = {	.request	= mmc_spi_request,	.set_ios	= mmc_spi_set_ios,	.get_ro		= mmc_spi_get_ro,};/****************************************************************************//* * SPI driver implementation */static irqreturn_tmmc_spi_detect_irq(int irq, void *mmc){	struct mmc_spi_host *host = mmc_priv(mmc);	u16 delay_msec = max(host->pdata->detect_delay, (u16)100);	mmc_detect_change(mmc, msecs_to_jiffies(delay_msec));	return IRQ_HANDLED;}struct count_children {	unsigned	n;	struct bus_type	*bus;};static int maybe_count_child(struct device *dev, void *c){	struct count_children *ccp = c;	if (dev->bus == ccp->bus) {		if (ccp->n)			return -EBUSY;		ccp->n++;	}	return 0;}static int mmc_spi_probe(struct spi_device *spi){	void			*ones;	struct mmc_host		*mmc;	struct mmc_spi_host	*host;	int			status;	/* MMC and SD specs only seem to care that sampling is on the	 * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode	 * should be legit.  We'll use mode 0 since it seems to be a	 * bit less troublesome on some hardware ... unclear why.	 */	spi->mode = SPI_MODE_0;	spi->bits_per_word = 8;	status = spi_setup(spi);	if (status < 0) {		dev_dbg(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",				spi->mode, spi->max_speed_hz / 1000,				status);		return status;	}	/* We can use the bus safely iff nobody else will interfere with us.	 * Most commands consist of one SPI message to issue a command, then	 * several more to collect its response, then possibly more for data	 * transfer.  Clocking access to other devices during that period will	 * corrupt the command execution.	 *	 * Until we have software primitives which guarantee non-interference,	 * we'll aim for a hardware-level guarantee.	 *	 * REVISIT we can't guarantee another device won't be added later...	 */	if (spi->master->num_chipselect > 1) {		struct count_children cc;		cc.n = 0;		cc.bus = spi->dev.bus;		status = device_for_each_child(spi->dev.parent, &cc,				maybe_count_child);		if (status < 0) {			dev_err(&spi->dev, "can't share SPI bus\n");			return status;		}		dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");	}	/* We need a supply of ones to transmit.  This is the only time	 * the CPU touches these, so cache coherency isn't a concern.	 *	 * NOTE if many systems use more than one MMC-over-SPI connector	 * it'd save some memory to share this.  That's evidently rare.	 */	status = -ENOMEM;	ones = kmalloc(MMC_SPI_BLOCKSIZE, GFP_KERNEL);	if (!ones)		goto nomem;	memset(ones, 0xff, MMC_SPI_BLOCKSIZE);	mmc = mmc_alloc_host(sizeof(*host), &spi->dev);	if (!mmc)		goto nomem;	mmc->ops = &mmc_spi_ops;	mmc->max_blk_size = MMC_SPI_BLOCKSIZE;	/* As long as we keep track of the number of successfully	 * transmitted blocks, we're good for multiwrite.	 */	mmc->caps = MMC_CAP_SPI | MMC_CAP_MULTIWRITE;	/* SPI doesn't need the lowspeed device identification thing for	 * MMC or SD cards, since it never comes up in open drain mode.	 * That's good; some SPI masters can't handle very low speeds!	 *	 * However, low speed SDIO cards need not handle over 400 KHz;	 * that's the only reason not to use a few MHz for f_min (until	 * the upper layer reads the target frequency from the CSD).	 */	mmc->f_min = 400000;	mmc->f_max = spi->max_speed_hz;	host = mmc_priv(mmc);	host->mmc = mmc;	host->spi = spi;	host->ones = ones;	/* Platform data is used to hook up things like card sensing	 * and power switching gpios.	 */	host->pdata = spi->dev.platform_data;	if (host->pdata)		mmc->ocr_avail = host->pdata->ocr_mask;	if (!mmc->ocr_avail) {		dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n");		mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;	}	if (host->pdata && host->pdata->setpower) {		host->powerup_msecs = host->pdata->powerup_msecs;		if (!host->powerup_msecs || host->powerup_msecs > 250)			host->powerup_msecs = 250;	}	dev_set_drvdata(&spi->dev, mmc);	/* preallocate dma buffers */	host->data = kmalloc(sizeof(*host->data), GFP_KERNEL);	if (!host->data)		goto fail_nobuf1;	if (spi->master->dev.parent->dma_mask) {		struct device	*dev = spi->master->dev.parent;		host->dma_dev = dev;		host->ones_dma = dma_map_single(dev, ones,				MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);		host->data_dma = dma_map_single(dev, host->data,				sizeof(*host->data), DMA_BIDIRECTIONAL);		/* REVISIT in theory those map operations can fail... */		dma_sync_single_for_cpu(host->dma_dev,				host->data_dma, sizeof(*host->data),				DMA_BIDIRECTIONAL);	}	/* setup message for status/busy readback */	spi_message_init(&host->readback);	host->readback.is_dma_mapped = (host->dma_dev != NULL);	spi_message_add_tail(&host->status, &host->readback);	host->status.tx_buf = host->ones;	host->status.tx_dma = host->ones_dma;	host->status.rx_buf = &host->data->status;	host->status.rx_dma = host->data_dma + offsetof(struct scratch, status);	host->status.cs_change = 1;	/* register card detect irq */	if (host->pdata && host->pdata->init) {		status = host->pdata->init(&spi->dev, mmc_spi_detect_irq, mmc);		if (status != 0)			goto fail_glue_init;	}	status = mmc_add_host(mmc);	if (status != 0)		goto fail_add_host;	dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n",			mmc->class_dev.bus_id,			host->dma_dev ? "" : ", no DMA",			(host->pdata && host->pdata->get_ro)				? "" : ", no WP",			(host->pdata && host->pdata->setpower)				? "" : ", no poweroff");	return 0;fail_add_host:	mmc_remove_host (mmc);fail_glue_init:	if (host->dma_dev)		dma_unmap_single(host->dma_dev, host->data_dma,				sizeof(*host->data), DMA_BIDIRECTIONAL);	kfree(host->data);fail_nobuf1:	mmc_free_host(mmc);	dev_set_drvdata(&spi->dev, NULL);nomem:	kfree(ones);	return status;}static int __devexit mmc_spi_remove(struct spi_device *spi){	struct mmc_host		*mmc = dev_get_drvdata(&spi->dev);	struct mmc_spi_host	*host;	if (mmc) {		host = mmc_priv(mmc);		/* prevent new mmc_detect_change() calls */		if (host->pdata && host->pdata->exit)			host->pdata->exit(&spi->dev, mmc);		mmc_remove_host(mmc);		if (host->dma_dev) {			dma_unmap_single(host->dma_dev, host->ones_dma,				MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);			dma_unmap_single(host->dma_dev, host->data_dma,				sizeof(*host->data), DMA_BIDIRECTIONAL);		}		kfree(host->data);		kfree(host->ones);		spi->max_speed_hz = mmc->f_max;		mmc_free_host(mmc);		dev_set_drvdata(&spi->dev, NULL);	}	return 0;}static struct spi_driver mmc_spi_driver = {	.driver = {		.name =		"mmc_spi",		.bus =		&spi_bus_type,		.owner =	THIS_MODULE,	},	.probe =	mmc_spi_probe,	.remove =	__devexit_p(mmc_spi_remove),};static int __init mmc_spi_init(void){	return spi_register_driver(&mmc_spi_driver);}module_init(mmc_spi_init);static void __exit mmc_spi_exit(void){	spi_unregister_driver(&mmc_spi_driver);}module_exit(mmc_spi_exit);MODULE_AUTHOR("Mike Lavender, David Brownell, "		"Hans-Peter Nilsson, Jan Nikitenko");MODULE_DESCRIPTION("SPI SD/MMC host driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?