移植Motorola开源的SD/MMC驱动程序
首先感谢Motorola的开源精神,它告诉其他嵌入式linux的开发人员:你们不是一个人在战斗,不是一个人!
好了,言归正传,下面将介绍我的移植过程。
内核版本为linux-2.4.21,CPU是PXA255。
下载motorola开源的SM/MM驱动程序源码
https://opensource.motorola.com/sf/frs/do/listReleases/projects.sd-mmc/frs.sample_package
解压该源码包,有driver和include两个目录,分别复制到内核相应的目录下。
修改Makefile和Config.in文件,可参考E680的设置。
下面是主要源码文件的修改过程:
添加文件include/asm-arm/arch-pxa/ezx.h
#define GPIO_MMC_DETECT 12 测试卡是否存在
#define GPIO_MMC_CLK 6
#define GPIO_MMC_WP 26 写保护
#define GPIO_MMC_MMCCS0 8
修改include/asm-arm/arch-pxa/pxa-regs.h
添加宏
/*
* MultiMediaCard (MMC) controller
*/
#define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */
#define MMC_STRPCL_STRT_CLK (1 << 1) /* Start the MMC clock */
#define MMC_STRPCL_STOP_CLK (1 << 0) /* Stop the MMC clock */
#define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */
#define MMC_STAT_SDIO_SUSPEND_ACK (1 << 16) /* SDIO data transfer has been
suspended by SDIO card */
#define MMC_STAT_SDIO_INT (1 << 15) /* SDIO Interrupt occured */
#define MMC_STAT_RD_STALLED (1 << 14) /* Read transfer stalled */
#define MMC_STAT_END_CMD_RES (1 << 13) /* Command and response
sequence has completed */
#define MMC_STAT_PRG_DONE (1 << 12) /* Card has finished programming
and is not busy */
#define MMC_STAT_DATA_TRAN_DONE (1 << 11) /* Data transmission to card
has been completed */
#define MMC_STAT_SPI_WR_ERR (1 << 10) /* Write data rejected by card
due to a Write Error */
#define MMC_STAT_FLASH_ERR (1 << 9) /* Flash programming error
occurred */
#define MMC_STAT_CLK_EN (1 << 8) /* MMC/SDIO clock is on */
#define MMC_STAT_RES_CRC_ERR (1 << 5) /* Response CRC error */
#define MMC_STAT_DAT_ERR_TOKEN (1 << 4) /* SPI data error token recv*/
#define MMC_STAT_CRC_RD_ERR (1 << 3) /* CRC error on receive */
#define MMC_STAT_CRC_WR_ERR (1 << 2) /* Write data rejected due to
CRC error */
#define MMC_STAT_TIME_OUT_RES (1 << 1) /* Card response timed out */
#define MMC_STAT_TIME_OUT_READ (1 << 0) /* Card read data timed out*/
#define MMC_STAT_ALL (0x1ffff)
#define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */
#define MMC_CLKRT_FREQ (7 << 0) /* Clock Frequency: */
#define MMC_CLKRT_FREQ_19_5MHZ (0 << 0) /* 19.5 MHz */
#define MMC_CLKRT_FREQ_9_75MHZ (1 << 0) /* 9.75 MHz */
#define MMC_CLKRT_FREQ_4_88MHZ (2 << 0) /* 4.88 MHz */
#define MMC_CLKRT_FREQ_2_44MHZ (3 << 0) /* 2.44 MHz */
#define MMC_CLKRT_FREQ_1_22MHZ (4 << 0) /* 1.22 MHz */
#define MMC_CLKRT_FREQ_609KHZ (5 << 0) /* 609 KHz */
#define MMC_CLKRT_FREQ_304KHZ (6 << 0) /* 304 KHz */
#define MMC_SPI __REG(0x4110000c) /* SPI mode control bits */
#define MMC_SPI_CS_ADDRESS (1 << 3) /* Enable CS1 or CS0 */
#define MMC_SPI_CS_EN (1 << 2) /* Enable SPI Chip Select */
#define MMC_SPI_CRC_EN (1 << 1) /* Enable CRC generation and
verification */
#define MMC_SPI_MODE (1 << 0) /* Enable SPI mode */
#define MMC_CMDAT __REG(0x41100010) /* Command/response/data sequence control */
#define MMC_CMDAT_SDIO_RESUME (1 << 13) /* SDIO CMD52, resume a
suspended data transfer */
#define MMC_CMDAT_SDIO_SUSPEND (1 << 12) /* SDIO CMD52, suspend current
data transfer */
#define MMC_CMDAT_SDIO_INT_EN (1 << 11) /* Enable check for SDIO
interrupt from card */
#define MMC_CMDAT_STOP_TRAN (1 << 10) /* Stop data transmission */
#define MMC_CMDAT_SD_4DAT (1 << 8) /* Enable 4-bit data transfer*/
#define MMC_CMDAT_DMA_EN (1 << 7) /* Enable DMA access to FIFO */
#define MMC_CMDAT_INIT (1 << 6) /* Precede command sequence
with 80 clocks, for
initialisation */
#define MMC_CMDAT_BUSY (1 << 5) /* Specifies whether a busy
signal possible after the
current command */
#define MMC_CMDAT_STRM_BLK (1 << 4) /* Data transfer is in
stream mode */
#define MMC_CMDAT_WR (1 << 3) /* Data transfer is a write
operation */
#define MMC_CMDAT_RD (0 << 3) /* Data transfer is a read
operation */
#define MMC_CMDAT_DATA_EN (1 << 2) /* Current command includes
a data transfer */
#define MMC_CMDAT_RES_TYPE (3 << 0) /* Command reponse format */
#define MMC_CMDAT_RES_NORESP (0 << 0) /* No response */
#define MMC_CMDAT_RES_RESP (1 << 0) /* Response with CRC */
#define MMC_CMDAT_RES_R2 (2 << 0) /* CID/CSD response */
#define MMC_CMDAT_RES_R3 (3 << 0) /* R3 response */
#define MMC_RESTO __REG(0x41100014) /* Expected response time out */
#define MMC_RESTO_MASK (0x0000007f)
#define MMC_RDTO __REG(0x41100018) /* Expected data read time out */
#define MMC_RDTO_MASK (0x0000ffff)
#define MMC_BLKLEN __REG(0x4110001c) /* Block length of data transaction */
#define MMC_BLKLEN_MASK (0x00000fff)
#define MMC_NOB __REG(0x41100020) /* Number of blocks, for block mode */
#define MMC_NOB_MASK (0x0000ffff)
#define MMC_PRTBUF __REG(0x41100024) /* Partial MMC_TXFIFO FIFO written */
#define MMC_PRTBUF_PRT_FULL (1 << 0) /* Buffer is partially full */
#define MMC_I_MASK __REG(0x41100028) /* Interrupt Mask */
#define MMC_I_REG __REG(0x4110002c) /* Interrupt Register (read only) */
#define MMC_I_SDIO_SUSPEND_ACK (1 << 12) /* SDIO data transfer has been
suspended by SDIO card */
#define MMC_I_SDIO_INT (1 << 11) /* An SDIO interrupt occured*/
#define MMC_I_RD_STALLED (1 << 10) /* Card has stalled read */
#define MMC_I_RES_ERR (1 << 9) /* Error occured on the resp */
#define MMC_I_DAT_ERR (1 << 8) /* Data error occurred during
data transmission */
#define MMC_I_TINT (1 << 7) /* Transmit Interrupt */
#define MMC_I_TXFIFO_WR_REQ (1 << 6) /* Tx FIFO Write Request */
#define MMC_I_TXFIFO_RD_REQ (1 << 5) /* Rx FIFO Read Request */
#define MMC_I_CLK_IS_OFF (1 << 4) /* Clock is Off */
#define MMC_I_STOP_CMD (1 << 3) /* MMC is ready for the stop
transmission command */
#define MMC_I_END_CMD_RES (1 << 2) /* End Command Response */
#define MMC_I_PRG_DONE (1 << 1) /* Programming Done */
#define MMC_I_DATA_TRAN_DONE (1 << 0) /* Data Transfer Done */
#define MMC_I_ALL (0x00001fff)
#define MMC_CMD __REG(0x41100030) /* Index of current command */
#define MMC_CMD_MASK (0x0000003f)
#define MMC_ARGH __REG(0x41100034) /* MSW part of the current command argument */
#define MMC_ARGH_MASK (0x0000ffff)
#define MMC_ARGL __REG(0x41100038) /* LSW part of the current command argument */
#define MMC_ARGL_MASK (0x0000ffff)
#define MMC_RES __REG(0x4110003c) /* Response FIFO (read only) */
#define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */
#define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */
#define MMC_RDWAIT __REG(0x41100048) /* RD_WAIT operation to SDIO card */
#define MMC_RDWAIT_START (1 << 1) /* Restart the read data tran*/
#define MMC_RDWAIT_EN (1 << 0) /* RD_WAIT enable */
#define MMC_BLKS_REM __REG(0x4110004c) /* Number of data blocks which are
not transferred */
#define MMC_BLKS_REM_MASK (0x0000ffff)
#define PGSR(x) __REG(0x40F00020 + ((unsigned long)(x)/32 * 4))
修改bvd_mmc.c
在void bvd_mmc_slot_up(void) 函数里修改相关的管脚属性
set_GPIO_mode(GPIO_MMC_CLK | GPIO_ALT_FN_1_OUT);
set_GPIO_mode(GPIO_MMC_MMCCS0 | GPIO_ALT_FN_1_OUT);
make zImage
下载到目标板运行,经过测试可支持2G的SD卡。