谨以此文纪念过往的岁月
一.前言
SD卡的大名是耳熟能详,但是SDIO总线确是不为人解,不过说起他的近亲SPI就知道了。我们这里主要是理解SDIO总线,并不去理解SPI总线。也许大家会畏惧其庞大的代码,其实我们并不需要详细理解其具体的实现,我们需要理解其架构。
二.主机(host)
在linux2.6.28中,在sdhci-s3c.c实现对主机的sdhci的驱动,而其设备的添加则在smdk6410_devices中。
在sdhci-s3c.c的sdhci_s3c_probe实现对主机端的驱,对于里面具体的一些实现我们就不看了,主要是看其中通用的code。
static int __devinit sdhci_s3c_probe(structplatform_device *pdev)
{
structsdhci_host*host;
structsdhci_s3c *sc;
host= sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
sc= sdhci_priv(host);
sdhci_add_host(host);
}
对于上面的函数,主要就是关心上面的几段代码。首先,来看sdhci_host这个结构体,这个是个很重要的东西,这个将会贯穿整个驱动。
struct sdhci_host {
/*Data set by hardware interface driver */
constchar *hw_name; /* Hardware bus name */
unsignedint quirks; /* Deviations from spec. */
int irq; /* Device IRQ */
void__iomem * ioaddr; /* Mapped address */
conststruct sdhci_ops *ops; /* Low level hw interface */
structmmc_host *mmc; /* MMC structure */
u64 dma_mask; /* custom DMA mask */
spinlock_t lock; /* Mutex */
int flags; /* Host attributes */
unsignedint version; /* SDHCI spec. version */
unsignedint max_clk; /* Max possible freq (MHz) */
unsignedint timeout_clk; /* Timeout freq (KHz) */
unsignedint clock; /* Current clock (MHz) */
unsignedshort power; /* Current voltage */
structmmc_request *mrq; /* Current request */
structmmc_command *cmd; /* Current command */
structmmc_data *data; /* Current data request */
unsignedint data_early:1; /* Data finished before cmd */
structsg_mapping_iter sg_miter; /* SG state for PIO */
unsignedint blocks; /* remaining PIO blocks */
int sg_count; /* Mapped sg entries */
u8 *adma_desc; /* ADMA descriptor table */
u8 *align_buffer; /* Bounce buffer */
dma_addr_t adma_addr; /* Mapped ADMA descr. table */
dma_addr_t align_addr; /* Mapped bounce buffer */
structtasklet_struct card_tasklet; /* Tasklet structures */
structtasklet_struct finish_tasklet;
structtimer_list timer; /* Timer for timeouts */
unsignedlong private[0]____cacheline_aligned;
};
上