SD/MMC DEVICE DRIVER 
1
目前SD卡的標準如下 
新舊版接腳相同,主要在支援的速度及指 
令不同。 
2 
SD card規範 
名稱版本最高容量 
SD 1.0 4G 
SDHC 2.0 32G 
SDXC 3.0 2T
SD Physical Specification 
Card 9 Pins define 
<1> CD/DAT3 
<2> CMD 
<3><6> Ground 
<4> VDD 
<5> CLK 
<7> DAT0 
<8> DAT1 
<9> DAT2
SD Physical Specification 
Card speed mode. 
<1> default:0~25Mhz, Input in clock rising edge, output in clock falling edge. 
<2> high speed:0~50Mhz, Input/output in clock rising edge. 
 Card bus width 
<1> 1-bit 
<2> 4-bit
SD Physical Specification 
卡片的暫存器 
OCR: Operation Condition about voltage and capacity. 
CID: Identification about vendor, product string, date, serial number. 
RCA: Relative card address, used for single/multiple card control. 
DSR: Driver stage, for bus driving performance. 
CSD: Card structure 1.0/2.0, TRAN_SPEED, command class, 
DSR_IMP, device size, block length… 
SCR: Card configuration ,SD Spec, Bus width, data after erase. 
SSR: SD status, current bus width, card type, speed_class.. 
CSR: card status, current state, error index, auxiliary state.
SD Physical Specification 
8 command class 
0: Basic commands 
2: Block-Oriented Read commands 
4: Block-Oriented Write commands 
5: Erase commands 
6: Block-Oriented Write Protection commands 
7: Lock Card commands 
8: Application-specific commands 
10: Switch function commands
SD Physical Specification 
 6 responses in two length(48/136) 
R1: Normal response 
R1b: Normal response with busy 
R2: CID,CSD register (136) 
R3: OCR register 
R6: Published RCA response 
R7: Card interface condition
SD Physical Specification 
Bus protocol 
<1> “no response” and “no data” Operations
SD Physical Specification 
Bus protocol 
<2> Block Read Operation
SD Physical Specification 
Bus protocol 
<3> Block Write Operation
SD Physical Specification 
Bus protocol 
<4> 4-bit wide bus
SD Speed Class/UHS Speed Class 
12
User Space 
Kernel Space 
Request Queue Request Queue 
Kernel Space 
Storage Media 
File I/O File I/O 
Virtual File System (VFS) Layer 
Individual Filesystems (EXT3,EXT4,JFFS2,Reiserfs,VFAT, …) 
Buffer Cache (Page Cache) 
I/O Schedulers 
Block Driver Block Driver 
Disk 
CD 
Driver
Block Diagram of Host Controller 
14
Kernel SD Device Driver Stack 
Kernel Virtual File Manager/File system 
MMC Block Device Driver 
SD Device Driver 
15 
DMA 
CPU Embedded SD controller 
interrupt 
interrupt
SD Host and the SD Card 
Request 
SD Command 
Reply 
16
17 
linux-2.6.x/drivers/mmc
18 
Source Code架構 
根目錄 
drivers/mmc 
子目錄card 
block file 
system 
interface 
子目錄core 
SD 標準協議程 
式碼 
子目錄host 
各別硬件控制程 
式碼
19 
SD Driver初始化流程 
使用platform device 
client driver的方式呼叫 
platform_driver_registe 
r()註冊一個platform 
probe call back 
function 
系統呼叫platform 
probe callback 
function,所以在該 
function中取得 
resource 並初始化該元 
件 
呼叫mmc_alloc_host()取 
得一個mmc結構的point, 
之後初始化該結構,接下 
來呼叫mmc_add_host()註 
冊一個mmc host driver 
在註冊一個mmc host 
driver時會填入幾個系統 
call back function,此時 
系統會使用這幾個 
function來scan是否有卡 
插入做SD卡的初始化
What do Probe call back function 
platform_get_resource()取得resource,並remap resource 
Allocate DMA resources 
若有用到work queue,則必需給予初始化 
註冊一個中斷服務,並起始中斷服務 
向上層MMC block註冊一個host MMC 
1) mmc = mmc_alloc_host(priv_size, dev) 
2) mmc_add_host(mmc) 
3) mmc_priv(mmc) 
* 在第一次註冊及後來插入SD卡時系統會掃描SD卡 
20
MMC block device driver call back function 
struct mmc_host_ops sd_ops = { 
.request = sdhci_request, 
.set_ios = sdhci_set_ios, 
.get_ro = sdhci_get_ro, 
}; // include/linux/mmc/host.h 
request 
The upper MMC block device driver will send a struct mmc_request *mrq 
to this. The mrq will include what want to do. When you finish this request 
you must call mmc_request_done() to note upper MMC block device 
driver what it is finisned. There include command or data access. 
set_ios 
1) Set/disable clock 
2) Power on/off to offer SD card or not 
3) Set SD card bus width 1 or 4 
get_ro 
1) To check the SD card write protect or not 
21
Callback function prototype 
struct mmc_host_ops { 
void (*request)(struct mmc_host *host, struct mmc_request *req); 
/* 
* Avoid calling these three functions too often or in a "fast path", 
* since underlaying controller might implement them in an expensive 
* and/or slow way. 
* 
* Also note that these functions might sleep, so don't call them 
* in the atomic contexts! 
* 
* Return values for the get_ro callback should be: 
* 0 for a read/write card 
* 1 for a read-only card 
* -ENOSYS when not supported (equal to NULL callback) 
* or a negative errno value when something bad happened 
* 
* Return values for the get_ro callback should be: 
* 0 for a absent card 
* 1 for a present card 
* -ENOSYS when not supported (equal to NULL callback) 
* or a negative errno value when something bad happened 
*/ 
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); 
int (*get_ro)(struct mmc_host *host); 
int (*get_cd)(struct mmc_host *host); 
void (*enable_sdio_irq)(struct mmc_host *host, int enable); 
};
Request callback function 
include/linux/mmc/core.h中定義 
struct mmc_request { 
struct mmc_command *cmd; 
struct mmc_data *data; 
struct mmc_command *stop; 
void *done_data; /* completion data */ 
void (*done)(struct mmc_request *);/* completion function */ 
}; 
由cmd中確認是否要送資料(檢查cmd->data 
是否為NULL pointer),或者只是送SD指令。 
處理完該cmd之後呼叫mmc_request_done() 
來回覆上層完成讓指令。 
23
struct mmc_command 
struct mmc_command { 
u32 opcode; 
u32 arg; 
u32 resp[4]; 
unsigned int flags; /* expected response type 
*/ 
unsigned int retries; /* max number of retries */ 
unsigned int error; /* command error */ 
struct mmc_data *data; /* data segment associated 
with cmd */ 
struct mmc_request *mrq; /* associated request */ 
}; // include/linux/mmc/core.h
struct mmc_data 
struct mmc_data { 
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ 
unsigned int timeout_clks; /* data timeout (in clocks) */ 
unsigned int blksz; /* data block size */ 
unsigned int blocks; /* number of blocks */ 
unsigned int error; /* data error */ 
unsigned int flags; 
#define MMC_DATA_WRITE (1 << 8) 
#define MMC_DATA_READ (1 << 9) 
#define MMC_DATA_STREAM (1 << 10) 
unsigned int bytes_xfered; 
struct mmc_command *stop; /* stop command */ 
struct mmc_request *mrq; /* associated request */ 
unsigned int sg_len; /* size of scatter list */ 
struct scatterlist *sg; /* I/O scatter list */ 
}; // include/linux/mmc/core.h
scattlerlist操作 
struct scatterlist { 
#ifdef CONFIG_DEBUG_SG 
unsigned long sg_magic; 
#endif 
unsigned long page_link; 
unsigned int offset; /* buffer offset */ 
dma_addr_t dma_address; /* dma address */ 
unsigned int length; /* length */ 
}; 
#define sg_dma_address(sg) ((sg)->dma_address) 
#define sg_dma_len(sg) ((sg)->length) 
• int dma_map_sg(struct device *, struct scatterlist *, int, enum 
dma_data_direction) - map a set of SG buffers for streaming mode DMA 
• kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; /*virtual address */ 
• kunmap_atomic(buffer, KM_BIO_SRC_IRQ) 
#define for_each_sg(sglist, sg, nr, __i)  
for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
SD card insert detecting flow chart 
27 
Card change interrupt 
happens 
Add card change work 
queue on interrupt 
service 
Insert or remove ? 
Remove all 
queue 
Set SD clock 
Call upper MMC block driver 
by mmc_detect_change() 
Send many command 
requests to this driver to get 
information from inserted 
card. 
remove insert 
Add a new disk to file 
manager.
Finish all data transfer ? 
28 
Read/Write data 
Received a request from 
upper block MMC driver to 
transfer data. The request 
callback function is called. 
1. Initial user space data 
context to kernel 
context. 
2. Set SD chipset for data 
length and timeout. 
Set DMA transfer 
information to DMA chipset 
for fist block data. 
Send start transfer data 
command 
Interrupt generates when a 
block data is transferred. 
Continue to DMA transfer 
information to DMA chipset 
for next block data. 
Send stop transfer data 
command 
Call upper MMC driver 
request done API 
Yes 
No
Classification of the Standard Register Map 
29
CODING EXAMPLE 
30
Register Structure Define 
typedef struct hw_register_struct { 
int rega; 
int regb; 
int regc; 
} hw_reg_t; 
static hw_reg_t *hw_reg; 
static int myfunc(void) 
{ 
…………………… 
readl(&hw_reg->rega); 
……………………………… 
writel(value, &hw_reg->regb); 
} 
static int __init module_init(void) 
{ 
hw_reg = (hw_reg_t *)ioremap(HW_PHYSICAL_ADDRESS, 0x100); 
……………….. 
} 
31

Linux SD/MMC device driver

  • 1.
  • 2.
    目前SD卡的標準如下 新舊版接腳相同,主要在支援的速度及指 令不同。 2 SD card規範 名稱版本最高容量 SD 1.0 4G SDHC 2.0 32G SDXC 3.0 2T
  • 3.
    SD Physical Specification Card 9 Pins define <1> CD/DAT3 <2> CMD <3><6> Ground <4> VDD <5> CLK <7> DAT0 <8> DAT1 <9> DAT2
  • 4.
    SD Physical Specification Card speed mode. <1> default:0~25Mhz, Input in clock rising edge, output in clock falling edge. <2> high speed:0~50Mhz, Input/output in clock rising edge.  Card bus width <1> 1-bit <2> 4-bit
  • 5.
    SD Physical Specification 卡片的暫存器 OCR: Operation Condition about voltage and capacity. CID: Identification about vendor, product string, date, serial number. RCA: Relative card address, used for single/multiple card control. DSR: Driver stage, for bus driving performance. CSD: Card structure 1.0/2.0, TRAN_SPEED, command class, DSR_IMP, device size, block length… SCR: Card configuration ,SD Spec, Bus width, data after erase. SSR: SD status, current bus width, card type, speed_class.. CSR: card status, current state, error index, auxiliary state.
  • 6.
    SD Physical Specification 8 command class 0: Basic commands 2: Block-Oriented Read commands 4: Block-Oriented Write commands 5: Erase commands 6: Block-Oriented Write Protection commands 7: Lock Card commands 8: Application-specific commands 10: Switch function commands
  • 7.
    SD Physical Specification  6 responses in two length(48/136) R1: Normal response R1b: Normal response with busy R2: CID,CSD register (136) R3: OCR register R6: Published RCA response R7: Card interface condition
  • 8.
    SD Physical Specification Bus protocol <1> “no response” and “no data” Operations
  • 9.
    SD Physical Specification Bus protocol <2> Block Read Operation
  • 10.
    SD Physical Specification Bus protocol <3> Block Write Operation
  • 11.
    SD Physical Specification Bus protocol <4> 4-bit wide bus
  • 12.
    SD Speed Class/UHSSpeed Class 12
  • 13.
    User Space KernelSpace Request Queue Request Queue Kernel Space Storage Media File I/O File I/O Virtual File System (VFS) Layer Individual Filesystems (EXT3,EXT4,JFFS2,Reiserfs,VFAT, …) Buffer Cache (Page Cache) I/O Schedulers Block Driver Block Driver Disk CD Driver
  • 14.
    Block Diagram ofHost Controller 14
  • 15.
    Kernel SD DeviceDriver Stack Kernel Virtual File Manager/File system MMC Block Device Driver SD Device Driver 15 DMA CPU Embedded SD controller interrupt interrupt
  • 16.
    SD Host andthe SD Card Request SD Command Reply 16
  • 17.
  • 18.
    18 Source Code架構 根目錄 drivers/mmc 子目錄card block file system interface 子目錄core SD 標準協議程 式碼 子目錄host 各別硬件控制程 式碼
  • 19.
    19 SD Driver初始化流程 使用platform device client driver的方式呼叫 platform_driver_registe r()註冊一個platform probe call back function 系統呼叫platform probe callback function,所以在該 function中取得 resource 並初始化該元 件 呼叫mmc_alloc_host()取 得一個mmc結構的point, 之後初始化該結構,接下 來呼叫mmc_add_host()註 冊一個mmc host driver 在註冊一個mmc host driver時會填入幾個系統 call back function,此時 系統會使用這幾個 function來scan是否有卡 插入做SD卡的初始化
  • 20.
    What do Probecall back function platform_get_resource()取得resource,並remap resource Allocate DMA resources 若有用到work queue,則必需給予初始化 註冊一個中斷服務,並起始中斷服務 向上層MMC block註冊一個host MMC 1) mmc = mmc_alloc_host(priv_size, dev) 2) mmc_add_host(mmc) 3) mmc_priv(mmc) * 在第一次註冊及後來插入SD卡時系統會掃描SD卡 20
  • 21.
    MMC block devicedriver call back function struct mmc_host_ops sd_ops = { .request = sdhci_request, .set_ios = sdhci_set_ios, .get_ro = sdhci_get_ro, }; // include/linux/mmc/host.h request The upper MMC block device driver will send a struct mmc_request *mrq to this. The mrq will include what want to do. When you finish this request you must call mmc_request_done() to note upper MMC block device driver what it is finisned. There include command or data access. set_ios 1) Set/disable clock 2) Power on/off to offer SD card or not 3) Set SD card bus width 1 or 4 get_ro 1) To check the SD card write protect or not 21
  • 22.
    Callback function prototype struct mmc_host_ops { void (*request)(struct mmc_host *host, struct mmc_request *req); /* * Avoid calling these three functions too often or in a "fast path", * since underlaying controller might implement them in an expensive * and/or slow way. * * Also note that these functions might sleep, so don't call them * in the atomic contexts! * * Return values for the get_ro callback should be: * 0 for a read/write card * 1 for a read-only card * -ENOSYS when not supported (equal to NULL callback) * or a negative errno value when something bad happened * * Return values for the get_ro callback should be: * 0 for a absent card * 1 for a present card * -ENOSYS when not supported (equal to NULL callback) * or a negative errno value when something bad happened */ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); int (*get_ro)(struct mmc_host *host); int (*get_cd)(struct mmc_host *host); void (*enable_sdio_irq)(struct mmc_host *host, int enable); };
  • 23.
    Request callback function include/linux/mmc/core.h中定義 struct mmc_request { struct mmc_command *cmd; struct mmc_data *data; struct mmc_command *stop; void *done_data; /* completion data */ void (*done)(struct mmc_request *);/* completion function */ }; 由cmd中確認是否要送資料(檢查cmd->data 是否為NULL pointer),或者只是送SD指令。 處理完該cmd之後呼叫mmc_request_done() 來回覆上層完成讓指令。 23
  • 24.
    struct mmc_command structmmc_command { u32 opcode; u32 arg; u32 resp[4]; unsigned int flags; /* expected response type */ unsigned int retries; /* max number of retries */ unsigned int error; /* command error */ struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ }; // include/linux/mmc/core.h
  • 25.
    struct mmc_data structmmc_data { unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ unsigned int timeout_clks; /* data timeout (in clocks) */ unsigned int blksz; /* data block size */ unsigned int blocks; /* number of blocks */ unsigned int error; /* data error */ unsigned int flags; #define MMC_DATA_WRITE (1 << 8) #define MMC_DATA_READ (1 << 9) #define MMC_DATA_STREAM (1 << 10) unsigned int bytes_xfered; struct mmc_command *stop; /* stop command */ struct mmc_request *mrq; /* associated request */ unsigned int sg_len; /* size of scatter list */ struct scatterlist *sg; /* I/O scatter list */ }; // include/linux/mmc/core.h
  • 26.
    scattlerlist操作 struct scatterlist{ #ifdef CONFIG_DEBUG_SG unsigned long sg_magic; #endif unsigned long page_link; unsigned int offset; /* buffer offset */ dma_addr_t dma_address; /* dma address */ unsigned int length; /* length */ }; #define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) • int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction) - map a set of SG buffers for streaming mode DMA • kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; /*virtual address */ • kunmap_atomic(buffer, KM_BIO_SRC_IRQ) #define for_each_sg(sglist, sg, nr, __i) for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
  • 27.
    SD card insertdetecting flow chart 27 Card change interrupt happens Add card change work queue on interrupt service Insert or remove ? Remove all queue Set SD clock Call upper MMC block driver by mmc_detect_change() Send many command requests to this driver to get information from inserted card. remove insert Add a new disk to file manager.
  • 28.
    Finish all datatransfer ? 28 Read/Write data Received a request from upper block MMC driver to transfer data. The request callback function is called. 1. Initial user space data context to kernel context. 2. Set SD chipset for data length and timeout. Set DMA transfer information to DMA chipset for fist block data. Send start transfer data command Interrupt generates when a block data is transferred. Continue to DMA transfer information to DMA chipset for next block data. Send stop transfer data command Call upper MMC driver request done API Yes No
  • 29.
    Classification of theStandard Register Map 29
  • 30.
  • 31.
    Register Structure Define typedef struct hw_register_struct { int rega; int regb; int regc; } hw_reg_t; static hw_reg_t *hw_reg; static int myfunc(void) { …………………… readl(&hw_reg->rega); ……………………………… writel(value, &hw_reg->regb); } static int __init module_init(void) { hw_reg = (hw_reg_t *)ioremap(HW_PHYSICAL_ADDRESS, 0x100); ……………….. } 31