基于S3C2440的嵌入式Linux驅(qū)動(dòng)——SPI子系統(tǒng)解讀(一)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
本文將介紹SPI子系統(tǒng)。內(nèi)核版本為2.6.30。如有錯(cuò)誤歡迎指正。
預(yù)備知識(shí)要求:1.SPI總線
2. platfrom平臺(tái)
3. sysfs子系統(tǒng)
4. 閱讀過LDD3第3,5,6,7,9,10,11章的內(nèi)容。
NOTE:如果沒有看過LDD3的相關(guān)內(nèi)容,直接看內(nèi)核源碼將非常吃力!?。?/p>
PC主機(jī):Ubuntu 和 redhat 9.0
目標(biāo)板:TQ2440開發(fā)板 cpu:s3c2440 linux內(nèi)核:2.6.30
0.引言
本系列文章對(duì)Linux設(shè)備模型中的SPI子系統(tǒng)進(jìn)行講解。SPI子系統(tǒng)的講解將分為4個(gè)部分。
第一部分,即本篇文章,將對(duì)SPI子系統(tǒng)整體進(jìn)行描述,同時(shí)給出SPI的相關(guān)數(shù)據(jù)結(jié)構(gòu),最后描述SPI總線的注冊(cè)。
第二部分,該文將對(duì)SPI的主控制器(master)驅(qū)動(dòng)進(jìn)行描述。 基于S3C2440的嵌入式Linux驅(qū)動(dòng)——SPI子系統(tǒng)解讀(二)
第三部分,該文將對(duì)SPI設(shè)備驅(qū)動(dòng),也稱protocol 驅(qū)動(dòng),進(jìn)行講解?;赟3C2440的嵌入式Linux驅(qū)動(dòng)——SPI子系統(tǒng)解讀(三)
第四部分,通過SPI設(shè)備驅(qū)動(dòng)留給用戶層的API,我們將從上到下描述數(shù)據(jù)是如何通過SPI的protocol 驅(qū)動(dòng),由bitbang中轉(zhuǎn),最后由master驅(qū)動(dòng)將數(shù)據(jù)傳輸出去。
基于S3C2440的嵌入式Linux驅(qū)動(dòng)——SPI子系統(tǒng)解讀(四)
1.SPI子系統(tǒng)綜述
SPI子系統(tǒng)從上到下分為:spi設(shè)備驅(qū)動(dòng)層,核心層和master驅(qū)動(dòng)層。其中master驅(qū)動(dòng)抽象出spi控制器的相關(guān)操作,而spi設(shè)備驅(qū)動(dòng)層抽象出了用戶空間API。
platform_device結(jié)構(gòu)中描述了SPI控制器的相關(guān)資源,同時(shí)在板級(jí)信息中將會(huì)添加spi設(shè)備的相關(guān)信息。master驅(qū)動(dòng)將以platform_driver形式體現(xiàn)出來,也就是說
在主控制器(master)和主控制器驅(qū)動(dòng)將掛載到platform總線上。platform_driver的probe函數(shù)中將注冊(cè)spi_master,同時(shí)將會(huì)獲取在板級(jí)信息中添加的spi設(shè)備,將該
信息轉(zhuǎn)換成spi_device,然后注冊(cè)spi_device到spi總線上。spi_driver結(jié)構(gòu)用于描述spi設(shè)備驅(qū)動(dòng),也將掛載到spi總線上。連同spi_driver一起注冊(cè)的是字符設(shè)備,該
字符設(shè)備將提供5個(gè)API給用戶空間。通過API,用戶空間可以執(zhí)行半雙工讀、半雙工寫和全雙工讀寫。
2. SPI的相關(guān)數(shù)據(jù)結(jié)構(gòu)
這里將介紹內(nèi)核所用到的關(guān)鍵數(shù)據(jù)結(jié)構(gòu),還有些結(jié)構(gòu)將在用到時(shí)加以說明。
2.1 spi_master
該結(jié)構(gòu)用于描述SOC的SPI控制器,S3C2440共有兩個(gè)SPI控制器。
/**
*structspi_master-interfacetoSPImastercontroller
*@dev:deviceinterfacetothisdriver
*@bus_num:board-specific(andoftenSOC-specific)identifierfora
*givenSPIcontroller.
*@num_chipselect:chipselectsareusedtodistinguishindividual
*SPIslaves,andarenumberedfromzerotonum_chipselects.
*eachslavehasachipselectsignal,butit'scommonthatnot
*everychipselectisconnectedtoaslave.
*@dma_alignment:SPIcontrollerconstraintonDMAbuffersalignment.
*@setup:updatesthedevicemodeandclockingrecordsusedbya
*device'sSPIcontroller;protocolcodemaycallthis.This
*mustfailifanunrecognizedorunsupportedmodeisrequested.
*It'salwayssafetocallthisunlesstransfersarependingon
*thedevicewhosesettingsarebeingmodified.
*@transfer:addsamessagetothecontroller'stransferqueue.
*@cleanup:freescontroller-specificstate
*
*EachSPImastercontrollercancommunicatewithoneormore@spi_device
*children.Thesemakeasmallbus,sharingMOSI,MISOandSCKsignals
*butnotchipselectsignals.Eachdevicemaybeconfiguredtousea
*differentclockrate,sincethosesharedsignalsareignoredunless
*thechipisselected.
*
*ThedriverforanSPIcontrollermanagesaccesstothosedevicesthrough
*aqueueofspi_messagetransactions,copyingdatabetweenCPUmemoryand
*anSPIslavedevice.Foreachsuchmessageitqueues,itcallsthe
*message'scompletionfunctionwhenthetransactioncompletes.
*/
structspi_master{
structdevicedev;
/*otherthannegative(==assignonedynamically),bus_numisfully
*board-specific.usuallythatsimplifiestobeingSOC-specific.
*example:oneSOChasthreeSPIcontrollers,numbered0..2,
*andoneboard'sschematicsmightshowitusingSPI-2.software
*wouldnormallyusebus_num=2forthatcontroller.
*/
s16bus_num;
/*chipselectswillbeintegraltomanycontrollers;someothers
*mightuseboard-specificGPIOs.
*/
u16num_chipselect;//該值不能為0,否則會(huì)注冊(cè)失敗
/*someSPIcontrollersposealignmentrequirementsonDMAable
*buffers;letprotocoldriversknowabouttheserequirements.
*/
u16dma_alignment;
/*Setupmodeandclock,etc(spidrivermaycallmanytimes).
*
*IMPORTANT:thismaybecalledwhentransferstoanother
*deviceareactive.DONOTUPDATESHAREDREGISTERSinways
*whichcouldbreakthosetransfers.
*/
int(*setup)(structspi_device*spi);
/*bidirectionalbulktransfers
*
*+Thetransfer()methodmaynotsleep;itsmainroleis
*justtoaddthemessagetothequeue.
*+Fornowthere'snoremove-from-queueoperation,or
*anyotherrequestmanagement
*+Toagivenspi_device,messagequeueingispurefifo
*
*+Themaster'smainjobistoprocessitsmessagequeue,
*selectingachipthentransferringdata
*+Iftherearemultiplespi_devicechildren,thei/oqueue
* arbitration algorithm is unspecified (round