一、注册平台设备
platform_device_register(&usr_mci_device);
二、填写平台设备结构体
static struct platform_device usr_mci_device= {
.name = "xxx",
.id = 0,
.dev = {
.release = usr_mci_platdev_release,
.dma_mask = &usr_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(usr_mci_resources),
.resource = usr_mci_resources,
};
三、填写资源结构体(物理地址查芯片手册)
static struct resource usr_mci_resources[] = {
[0] = {
.start = CONFIG_USR_IOBASE,
.end = CONFIG_USR_IOBASE + USR_MCI_IO_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = CONFIG_USR_INTR,
.end = CONFIG_USR_INTR,
.flags = IORESOURCE_IRQ,
},
};
四、注册平台驱动
platform_driver_register(&usr_mci_driver);
五、填写平台驱动结构体
static struct platform_driver usr_mci_driver= {
.probe = usr_mci_probe,
.remove = usr_mci_remove,
.suspend = usr_mci_suspend,
.resume = usr_mci_resume,
.driver = {
.name = DRIVER_NAME,
},
};
六、重写probe函数
static int __devinit usr_mci_probe(struct platform_device *pdev)
七、创建一个自己的设备结构体
struct usr_host {
struct mmc_host*mmc;
spinlock_tlock;
struct mmc_request*mrq;
struct mmc_command*cmd;
struct mmc_data*data;
void __iomem*base;
unsigned intcard_status;
struct scatterlist*dma_sg;
unsigned intdma_sg_num;
unsigned intdma_alloc_size;
unsigned intdma_dir;
dma_addr_tdma_paddr;
unsigned int*dma_vaddr;
struct timer_listtimer;
unsigned intirq;
unsigned intirq_status;
unsigned intis_tuning;
wait_queue_head_tintr_wait;
unsigned longpending_events;
unsigned intid;
};
struct usr_host *host;
八、分配一个包含了mmc_host的自定义结构体(core需要)
struct mmc_host *mmc;
mmc = mmc_alloc_host(sizeof(struct usr_host), &pdev->dev);
九、初始化mmc_host结构体
mmc->ops
mmc->f_min
mmc->f_max
mmc->caps
mmc->max_blk_count
mmc->max_segs
mmc->max_seg_size
mmc->max_req_size
mmc->ocr_avail
mmc->ocr
十、初始化usr_host
host=mmc->private;
host->dma_vaddr = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,&host->dma_paddr, GFP_KERNEL);
host->mmc = mmc;
host->id
host->base
十一、初始化SDIO的时钟、驱动能力
十二、SDIO复位
十三、SDIO重上电
十四、设置时钟相位
十五、设置阈值
十六、设置中断状态
十七、设置中断屏蔽
十八、设置DMA搬移数据
十九、设置全局中断使能
二十、设置FIFO突发长度与FIFO大小
二十一、卡检测
二十二、初始化定时器,定时处理函数为卡检测
二十三、获取资源结构体的软中断号
二十四、初始化等待队列
init_waitqueue_head(&host->intr_wait);
二十五、request_irq注册中断
二十六、写中断函数(唤醒等待队列)
static irqreturn_t usr_irq(int irq, void *dev_id)
{
wake_up(&host->intr_wait);
}