我的经历:
看了某些大神的说明,我胆怯地进入了drivers/mmc/host/。
由于用的是s3c2440,看驱动时,我首先会找s3c字样,于是我注意到sdhci-s3c.c和s3cmci.c。
看了一下Kconfig
config MMC_S3C
tristate "Samsung S3C SD/MMC Card Interface support"
depends on ARCH_S3C2410
help
This selects a driver for the MCI interface found in
Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs.
If you have a board based on one of those and a MMC/SD
slot, say Y or M here.
If unsure, say N.
再看Makefile
obj-$(CONFIG_MMC_S3C) += s3cmci.o
我想我用s3cmci就可以了。我就猜测s3cmci和sdhci-s3c就是对应不一样的芯片。但是当我看了看代码,不完全是这样。
记得大神说过struct mmc_host。sd驱动用到的主要结构,但是sdhci-s3c用到的是struct sdhci_host。
这是什么情况。
首先我就考虑sdhci到底是什么,我看所有sdhci-*.c驱动都用到了sdhci.c,我看到sdhci.c对寄存器操作的偏移都
是一样的,这样我想到了usb的ochi驱动。应该有个sd控制器都遵循的协议。
然后我又打开了s3c6410的datasheet
第一行 SD Standard Host很耀眼。最后我在百度找的了这个:
Part_A2_SD_Host_Controller_Simplified_Specification_Ver2.00.pdf
这个就是所说的协议,sdhci.c要实现的东西。s3c2440并不遵循这个。
先看看sdhci吧,看c之前先看.h文件分析
/*
* linux/include/linux/mmc/sdhci.h - Secure Digital Host Controller Interface
*
* Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#ifndef LINUX_MMC_SDHCI_H
#define LINUX_MMC_SDHCI_H
#include <linux/scatterlist.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/mmc/host.h>
struct sdhci_host {
/* Data set by hardware interface driver */
const char *hw_name; /* Hardware bus name */ //硬件总线名
unsigned int quirks; /* Deviations from spec. */ //偏离规范
//我们看有哪些怪癖,还有代码会如何处理
/* Controller doesn't honor resets unless we touch the clock register */
#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0)
/*
SDHCI_QUIRK_CLOCK_BEFORE_RESET 是有的要在复位前设置时钟寄存器
会在复位前调用host->ops->set_clock(host, clock);驱动提供
*/
/* Controller has bad caps bits, but really supports DMA */
#define SDHCI_QUIRK_FORCE_DMA (1<<1)
/*
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_SDMA;
就是支持SDMA
*/
/* Controller doesn't like to be reset when there is no card inserted. */
#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2)
/*
上面英文已说的很清楚:
没有卡插入时,控制器不想复位。
在复位时遇到这个标准,会想尝试读当前的状态,成功返回,失败进行复位。
*/
/* Controller doesn't like clearing the power reg before a change */
#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
/*
控制器不想清除电源寄存器在一个改变MMC_VDD前。
遇到这个,直接改电源寄存器值,不清除。
*/
/* Controller has flaky internal state so reset it on each ios change */
#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4)
/*
在sdhci_do_set_ios()中会用到。
解释:
有些控制器在一些操作时会发疯,即使是CMD0,解决方法就是复位