寫在前面
初次接觸SPI是因為幾年前玩單片機的時候,由於普通的51單片機沒有SPI控制器,所以只好用IO口去模擬。最近一次接觸SPI是大三時參加的校內選拔賽,當時需要用2440去控制nrf24L01,從而實現數據的無線傳輸。nrf24L01是一種典型的SPI接口的2.4GHz無線收發器,當時搞了很久,由於時間比較緊,而且當時根本不熟悉Linux的SPI子系統,最后雖然采用IO口模擬SPI的方式勉強實現了,但是這根本就不符合Linux驅動的編程規范,或者說是在破壞Linux、污染kernel。
根據我個人所知道的,Linux SPI一直是處於被“忽略”的角色,市場上大部分板子在板級文件里都沒有關於SPI的相關代碼,而大部分講驅動的書籍也沒有專門的一章來講述關於Linux SPI方面的內容,與IIC相比,SPI就是一個不被重視的“家伙”,為什么?我也不知道。為了幫SPI抱打不平,我決定基於Linux-2.6.36,說說Linux中SPI子系統。
先給出Linux SPI子系統的體系結構圖:
SPI子系統體系結構
下面開始分析SPI子系統。
Linux中SPI子系統的初始化是從drivers/spi/spi.c文件中的spi_init函數開始的,看看它的定義:
00001025 static int __init spi_init(void) 00001026 { 00001027 int status; 00001028 00001029 buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); 00001030 if (!buf) { 00001031 status = -ENOMEM; 00001032 goto err0; 00001033 } 00001034 00001035 status = bus_register(&spi_bus_type); 00001036 if (status < 0) 00001037 goto err1; 00001038 00001039 status = class_register(&spi_master_class); 00001040 if (status < 0) 00001041 goto err2; 00001042 return 0; 00001043 00001044 err2: 00001045 bus_unregister(&spi_bus_type); 00001046 err1: 00001047 kfree(buf); 00001048 buf = NULL; 00001049 err0: 00001050 return status; 00001051 }
1029行,分配spi buf內存,其中buf和SPI_BUFSIZ都在spi.c文件中定義:
00000945 #define SPI_BUFSIZ max(32,SMP_CACHE_BYTES) 00000946 00000947 static u8 *buf;
1035行,注冊spi總線,同樣是在spi.c文件中:
00000145 struct bus_type spi_bus_type = { 00000146 .name = "spi", 00000147 .dev_attrs = spi_dev_attrs, 00000148 .match = spi_match_device, 00000149 .uevent = spi_uevent, 00000150 .suspend = spi_suspend, 00000151 .resume = spi_resume, 00000152 };
146行,總線的名字就叫spi。
148行,比較重要的,spi_match_device是spi總線上匹配設備和設備驅動的函數,同樣是在spi.c文件中:
00000085 static int spi_match_device(struct device *dev, struct device_driver *drv) 00000086 { 00000087 const struct spi_device *spi = to_spi_device(dev); 00000088 const struct spi_driver *sdrv = to_spi_driver(drv); 00000089 00000090 /* Attempt an OF style match */ 00000091 if (of_driver_match_device(dev, drv)) 00000092 return 1; 00000093 00000094 if (sdrv->id_table) 00000095 return !!spi_match_id(sdrv->id_table, spi); 00000096 00000097 return strcmp(spi->modalias, drv->name) == 0; 00000098 }
寫過驅動的都應該知道platform總線有struct platform_device和struct platform_driver,到了SPI總線,當然也有對應的struct spi_device和struct spi_driver,如87、88行所示。87行,關於struct spi_device的定義是在include/linux/spi/spi.h中:
00000069 struct spi_device { 00000070 struct device dev; 00000071 struct spi_master *master; 00000072 u32 max_speed_hz; 00000073 u8 chip_select; 00000074 u8 mode; 00000075 #define SPI_CPHA 0x01 /* clock phase */ 00000076 #define SPI_CPOL 0x02 /* clock polarity */ 00000077 #define SPI_MODE_0 (0|0) /* (original MicroWire) */ 00000078 #define SPI_MODE_1 (0|SPI_CPHA) 00000079 #define SPI_MODE_2 (SPI_CPOL|0) 00000080 #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) 00000081 #define SPI_CS_HIGH 0x04 /* chipselect active high? */ 00000082 #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ 00000083 #define SPI_3WIRE 0x10 /* SI/SO signals shared */ 00000084 #define SPI_LOOP 0x20 /* loopback mode */ 00000085 #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ 00000086 #define SPI_READY 0x80 /* slave pulls low to pause */ 00000087 u8 bits_per_word; 00000088 int irq; 00000089 void *controller_state; 00000090 void *controller_data; 00000091 char modalias[SPI_NAME_SIZE]; 00000092 00000093 /* 00000094 * likely need more hooks for more protocol options affecting how 00000095 * the controller talks to each chip, like: 00000096 * - memory packing (12 bit samples into low bits, others zeroed) 00000097 * - priority 00000098 * - drop chipselect after each word 00000099 * - chipselect delays 00000100 * - ... 00000101 */ 00000102 };
70行,dev,嵌入到設備模型中用的。
71行,master,spi設備的更高層描述,每一個spi控制器就對應一個master,一個spi設備必須對應一個master,master下可以有多個spi設備。
72,73行沒什么好說的,從變量的名字就可以明白。
74行,mode,針對時鍾相位CPHA(0或1)和時鍾極性CPOL(0或1)的不同組合,將spi分成四種模式,就是77至80行這四種。CPOL表示當空閑時(沒有進行數據傳輸)時鍾信號的電平,CPOL=0表示低電平,CPOL=1表示高電平。每個時鍾周期都有兩次電平的跳變,上升沿和下降沿,CPHA就表示在每個時鍾周期里是第一個邊沿采樣數據還是第二個邊沿采樣數據,具體第一個邊沿或者第二個邊沿是上升沿還是下降沿則由CPOL決定。看下面這張圖就明白了。藍色箭頭表示對數據進行采樣。
87行,如果傳輸是以字節為單位的話就設置為8,相應地,如果是以2個字節為單位則設置為16。
88行,中斷號。89行,沒有使用,在后面會看到這個值會被設置為NULL。90行,后面講到具體的控制器再說。91行,很重要,一般來說設備與驅動能否匹配起來就要看它,注意,這里只是說一般,因為還有另外兩種匹配的方法,不過大部分設備和驅動能否匹配起來都是根據名字是否相等,當然像USB驅動就不是根據名字來匹配的,而是根據與id table。struct spi_driver的定義也是在include/linux/spi/spi.h:
00000175 struct spi_driver { 00000176 const struct spi_device_id *id_table; 00000177 int (*probe)(struct spi_device *spi); 00000178 int (*remove)(struct spi_device *spi); 00000179 void (*shutdown)(struct spi_device *spi); 00000180 int (*suspend)(struct spi_device *spi, pm_message_t mesg); 00000181 int (*resume)(struct spi_device *spi); 00000182 struct device_driver driver; 00000183 };
182行,driver就是在設備模型中使用的那個device_driver,其他都是一些函數指針的定義,挺熟悉的了,就不多說了。
回到spi_match_device函數,91行和95行就是設備和驅動匹配的另外兩種方法,因為后文要講的spi驅動使用的是第三種方法,因此這里就不討論這兩種方法了。97行,根據設備名和驅動名是否相等進行匹配,相等則返回1,表示匹配成功,此時驅動里的probe函數將會被調用,這也是我們最希望看到的,返回0則表示匹配失敗。
我們知道,對於具體的平台,nand、iic、frame buffer等這些都是平台設備,spi當然也一樣是平台設備,對於平台設備,大部分情況下是先注冊設備再注冊驅動。因此下面就以tiny6410為具體平台,按照這種先后順序來講述。
S3c6410有兩個SPI控制器,以SPI0為例就可以了。首先看s3c6410中關於SPI0控制器的描述,在arch/arm/mach-s3c64xx/dev-spi.c文件中:
00000101 struct platform_device s3c64xx_device_spi0 = { 00000102 .name = "s3c64xx-spi", 00000103 .id = 0, 00000104 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), 00000105 .resource = s3c64xx_spi0_resource, 00000106 .dev = { 00000107 .dma_mask = &spi_dmamask, 00000108 .coherent_dma_mask = DMA_BIT_MASK(32), 00000109 .platform_data = &s3c64xx_spi0_pdata, 00000110 }, 00000111 };
102行,驅動能否與這個設備匹配,就看這個名字了,因此對應的驅動名字必須與之一樣。103行,SPI控制器的ID,SPI0控制器就為0,SPI1控制器就為1。
104和105行是關於IO口資源、DMA資源和中斷資源的。107、108行是關於DMA的,不說了。109行,給驅動用的,在驅動那里再說。在板初始化函數mini6410_machine_init里調用platform_add_devices函數就可以將SPI0設備注冊到platform總線上。
S3c6410的SPI控制器驅動在drivers/spi/spi_s3c64xx.c文件里。初始化函數:
00001183 static int __init s3c64xx_spi_init(void) 00001184 { 00001185 return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); 00001186 }
1185行,s3c64xx_spi_driver是struct platform_driver的實例,也在spi_s3c64xx.c文件中定義:
00001172 static struct platform_driver s3c64xx_spi_driver = { 00001173 .driver = { 00001174 .name = "s3c64xx-spi", 00001175 .owner = THIS_MODULE, 00001176 }, 00001177 .remove = s3c64xx_spi_remove, 00001178 .suspend = s3c64xx_spi_suspend, 00001179 .resume = s3c64xx_spi_resume, 00001180 };
1174行,看到了沒?和之前在s3c64xx_device_spi0里定義的名字是一樣的,這樣它們就可以匹配起來,1185行的s3c64xx_spi_probe驅動探測函數就會被調用,看下它的定義:
00000911 static int __init s3c64xx_spi_probe(struct platform_device *pdev) 00000912 { 00000913 struct resource *mem_res, *dmatx_res, *dmarx_res; 00000914 struct s3c64xx_spi_driver_data *sdd; 00000915 struct s3c64xx_spi_info *sci; 00000916 struct spi_master *master; 00000917 int ret; 00000918 00000919 if (pdev->id < 0) { 00000920 dev_err(&pdev->dev, 00000921 "Invalid platform device id-%d\n", pdev->id); 00000922 return -ENODEV; 00000923 } 00000924 00000925 if (pdev->dev.platform_data == NULL) { 00000926 dev_err(&pdev->dev, "platform_data missing!\n"); 00000927 return -ENODEV; 00000928 } 00000929 00000930 sci = pdev->dev.platform_data; 00000931 if (!sci->src_clk_name) { 00000932 dev_err(&pdev->dev, 00000933 "Board init must call s3c64xx_spi_set_info()\n"); 00000934 return -EINVAL; 00000935 } 00000936 00000937 /* Check for availability of necessary resource */ 00000938 00000939 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 00000940 if (dmatx_res == NULL) { 00000941 dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); 00000942 return -ENXIO; 00000943 } 00000944 00000945 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 00000946 if (dmarx_res == NULL) { 00000947 dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); 00000948 return -ENXIO; 00000949 } 00000950 00000951 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 00000952 if (mem_res == NULL) { 00000953 dev_err(&pdev->dev, "Unable to get SPI MEM resource\n"); 00000954 return -ENXIO; 00000955 } 00000956 00000957 master = spi_alloc_master(&pdev->dev, 00000958 sizeof(struct s3c64xx_spi_driver_data)); 00000959 if (master == NULL) { 00000960 dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); 00000961 return -ENOMEM; 00000962 } 00000963 00000964 platform_set_drvdata(pdev, master); 00000965 00000966 sdd = spi_master_get_devdata(master); 00000967 sdd->master = master; 00000968 sdd->cntrlr_info = sci; 00000969 sdd->pdev = pdev; 00000970 sdd->sfr_start = mem_res->start; 00000971 sdd->tx_dmach = dmatx_res->start; 00000972 sdd->rx_dmach = dmarx_res->start; 00000973 00000974 sdd->cur_bpw = 8; 00000975 00000976 master->bus_num = pdev->id; 00000977 master->setup = s3c64xx_spi_setup; 00000978 master->transfer = s3c64xx_spi_transfer; 00000979 master->num_chipselect = sci->num_cs; 00000980 master->dma_alignment = 8; 00000981 /* the spi->mode bits understood by this driver: */ 00000982 00000983 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 00000984 00000985 if (request_mem_region(mem_res->start, 00000986 resource_size(mem_res), pdev->name) == NULL) { 00000987 dev_err(&pdev->dev, "Req mem region failed\n"); 00000988 ret = -ENXIO; 00000989 goto err0; 00000990 } 00000991 00000992 sdd->regs = ioremap(mem_res->start, resource_size(mem_res)); 00000993 if (sdd->regs == NULL) { 00000994 dev_err(&pdev->dev, "Unable to remap IO\n"); 00000995 ret = -ENXIO; 00000996 goto err1; 00000997 } 00000998 00000999 if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) { 00001000 dev_err(&pdev->dev, "Unable to config gpio\n"); 00001001 ret = -EBUSY; 00001002 goto err2; 00001003 } 00001004 00001005 /* Setup clocks */ 00001006 sdd->clk = clk_get(&pdev->dev, "spi"); 00001007 if (IS_ERR(sdd->clk)) { 00001008 dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n"); 00001009 ret = PTR_ERR(sdd->clk); 00001010 goto err3; 00001011 } 00001012 00001013 if (clk_enable(sdd->clk)) { 00001014 dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n"); 00001015 ret = -EBUSY; 00001016 goto err4; 00001017 } 00001018 00001019 sdd->src_clk = clk_get(&pdev->dev, sci->src_clk_name); 00001020 if (IS_ERR(sdd->src_clk)) { 00001021 dev_err(&pdev->dev, 00001022 "Unable to acquire clock '%s'\n", sci->src_clk_name); 00001023 ret = PTR_ERR(sdd->src_clk); 00001024 goto err5; 00001025 } 00001026 00001027 if (clk_enable(sdd->src_clk)) { 00001028 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", 00001029 sci->src_clk_name); 00001030 ret = -EBUSY; 00001031 goto err6; 00001032 } 00001033 00001034 sdd->workqueue = create_singlethread_workqueue( 00001035 dev_name(master->dev.parent)); 00001036 if (sdd->workqueue == NULL) { 00001037 dev_err(&pdev->dev, "Unable to create workqueue\n"); 00001038 ret = -ENOMEM; 00001039 goto err7; 00001040 } 00001041 00001042 /* Setup Deufult Mode */ 00001043 s3c64xx_spi_hwinit(sdd, pdev->id); 00001044 00001045 spin_lock_init(&sdd->lock); 00001046 init_completion(&sdd->xfer_completion); 00001047 INIT_WORK(&sdd->work, s3c64xx_spi_work); 00001048 INIT_LIST_HEAD(&sdd->queue); 00001049 00001050 if (spi_register_master(master)) { 00001051 dev_err(&pdev->dev, "cannot register SPI master\n"); 00001052 ret = -EBUSY; 00001053 goto err8; 00001054 } 00001055 00001056 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d " 00001057 "with %d Slaves attached\n", 00001058 pdev->id, master->num_chipselect); 00001059 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", 00001060 mem_res->end, mem_res->start, 00001061 sdd->rx_dmach, sdd->tx_dmach); 00001062 00001063 return 0; 00001064 00001065 err8: 00001066 destroy_workqueue(sdd->workqueue); 00001067 err7: 00001068 clk_disable(sdd->src_clk); 00001069 err6: 00001070 clk_put(sdd->src_clk); 00001071 err5: 00001072 clk_disable(sdd->clk); 00001073 err4: 00001074 clk_put(sdd->clk); 00001075 err3: 00001076 err2: 00001077 iounmap((void *) sdd->regs); 00001078 err1: 00001079 release_mem_region(mem_res->start, resource_size(mem_res)); 00001080 err0: 00001081 platform_set_drvdata(pdev, NULL); 00001082 spi_master_put(master); 00001083 00001084 return ret; 00001085 }
函數很長,但做的東西卻很簡單。919至923行,SPI控制器的ID是從0開始的,小於0的話,沒門,出錯。
925至928行,必須要有platform_data,否則出錯。930行,如果platform_data存在的話就把它取出來。
931至935行,如果src_clk_name為0,則表示在板初始化函數里沒有調用s3c64xx_spi_set_info函數。
939至955行,獲取在設備里定義的IO口和DMA資源。