SPI協議及SDIO協議
主要影響SPI通訊的兩個引數是時鐘極性(CPOL)和時鐘相位(CPHA)兩個引數,SPI傳輸序列資料時首先傳輸最高位。時鐘極性(CPOL)對傳輸協議沒有重大的影響,如果CPOL=0,串行同步時鐘的空閒狀態為低電平;如果CPOL=1,串行同步時鐘的空閒狀態為高電平。時鐘相位(CPHA)能夠配置用於選擇兩種不同的傳輸協議之一進行資料傳輸,如果CPHA=0,在串行同步時鐘的第一個跳變沿(上升或下降)資料被取樣;如果CPHA=1,在串行同步時鐘的第二個跳變沿(上升或下降)資料被取樣。圖示如下:
一般的ARM系統對SPI的支援方式分三種:輪詢(POLLING),中斷(INTERRUPT,需要定義SPI的中斷號),和DMA(配置好SPI和DMA對應的暫存器,和DMA的源頭和目的地址,就可以開始進行DMA傳輸)。
========================================================================
基於SDIO協議,SD卡的定義如下:
它可以支援三種操作模式:SPI,SD一線,SD四線(介面通過暫存器累配置)。SPI速度較低,一線或者四線需要暫存器來選擇,高速模式下需要四線支援。其中DAT是資料線,一線模式下預設DAT0;CMD線上傳輸序列命令,可以是單機定址或者廣播命令。
6410平臺對SD卡的支援,表現在CH0(CH1被用來連線WIFI,和CH0共一個DETECT腳,即XmmcCDN0),新增HSMMC裝置,分配對應資源即可。
(1)
static struct platform_device *smdk6410_devices[] __initdata = {
........
&s3c_device_hsmmc0,
........
}
定義如下:
struct platform_device s3c_device_hsmmc0 = {
.name = "s3c-sdhci",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_hsmmc_resource),
.resource = s3c_hsmmc_resource,
.dev = {
.dma_mask = &s3c_device_hsmmc_dmamask,
.coherent_dma_mask = 0xffffffffUL,
.platform_data = &s3c_hsmmc0_def_platdata,
},
};
呼叫如下:
static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED |
MMC_CAP_SD_HIGHSPEED),
};
(2)
完善s3c_hsmmc0_def_platdata 的配置,在
static inline void s3c6410_default_sdhci0(void)
{
s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio;
s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
}
在s3c6410_setup_sdhci0_cfg_gpio這個函式中,對XmmcCDN0進行了配置,使其只能單獨用在MMC0或MMC1,此處用在MMC0上檢測SD卡的熱插拔:
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
對應的在s3c6410_setup_sdhci1_cfg_gpio裡面就要遮蔽掉這些東西。
補充:在函式void s3c6410_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)中的width引數是用來配置1線還是4線模式的。在最開始的時候,mmc控制器不知道是什麼卡,所以傳進來的width就是1,這樣就只初始化cmd和clk,僅僅保證可以識別出來,在識別出卡的型別後在傳具體的width進來,比如4或者1來配置。這個過程在sdhci-s3c-sdio.c中。
(3)
以上是platform device,則dirver在sdhci-s3c.c呼叫如下:
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
.suspend = sdhci_s3c_suspend,
.resume = sdhci_s3c_resume,
.remove = __devexit_p(sdhci_s3c_remove),
.driver = {
.owner = THIS_MODULE,
.name = "s3c-sdhci",
},
};
在初始化模組時用platform_driver_register(&sdhci_s3c_driver)即可。