rk32spi.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. rk32spi.c
  5. Abstract:
  6. This module implements support for the SPI controllers on the RockChip
  7. RK3288 SoC.
  8. Author:
  9. Evan Green 24-Aug-2015
  10. Environment:
  11. Kernel
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/driver.h>
  17. #include <minoca/spb/spbhost.h>
  18. //
  19. // --------------------------------------------------------------------- Macros
  20. //
  21. #define RK32_READ_SPI(_Controller, _Register) \
  22. HlReadRegister32((_Controller)->ControllerBase + (_Register))
  23. #define RK32_WRITE_SPI(_Controller, _Register, _Value) \
  24. HlWriteRegister32((_Controller)->ControllerBase + (_Register), (_Value))
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. #define RK32_SPI_ALLOCATION_TAG 0x53336B52
  29. #define RK32_SPI_INPUT_CLOCK 99000000
  30. #define RK32_SPI_FIFO_DEPTH 32
  31. //
  32. // Define control register 0 bits.
  33. //
  34. #define RK32_SPI_CONTROL0_DATA_FRAME_4 (0x0 << 0)
  35. #define RK32_SPI_CONTROL0_DATA_FRAME_8 (0x1 << 0)
  36. #define RK32_SPI_CONTROL0_DATA_FRAME_16 (0x2 << 0)
  37. #define RK32_SPI_CONTROL0_CONTROL_FRAME_SIZE_MASK (0xF << 2)
  38. #define RK32_SPI_CONTROL0_CLOCK_PHASE (1 << 6)
  39. #define RK32_SPI_CONTROL0_CLOCK_INACTIVE_HIGH (1 << 7)
  40. #define RK32_SPI_CONTROL0_CHIP_SELECT_KEEP_LOW (0x0 << 8)
  41. #define RK32_SPI_CONTROL0_CHIP_SELECT_HIGH_HALF (0x1 << 8)
  42. #define RK32_SPI_CONTROL0_CHIP_SELECT_HIGH_FULL (0x2 << 8)
  43. #define RK32_SPI_CONTROL0_SS_CLK_DELAY_FULL_CLOCK (1 << 10)
  44. #define RK32_SPI_CONTROL0_BIG_ENDIAN (1 << 11)
  45. #define RK32_SPI_CONTROL0_LSB_FIRST (1 << 12)
  46. #define RK32_SPI_CONTROL0_APB_8BIT (1 << 13)
  47. #define RK32_SPI_CONTROL0_DELAY_CYCLE_SHIFT 14
  48. #define RK32_SPI_CONTROL0_FRAME_MOTOROLA (0x0 << 16)
  49. #define RK32_SPI_CONTROL0_FRAME_TI_SSP (0x1 << 16)
  50. #define RK32_SPI_CONTROL0_FRAME_NS_MICROWIRE (0x2 << 16)
  51. #define RK32_SPI_CONTROL0_TRANSMIT_AND_RECEIVE (0x0 << 18)
  52. #define RK32_SPI_CONTROL0_TRANSMIT_ONLY (0x1 << 18)
  53. #define RK32_SPI_CONTROL0_RECEIVE_ONLY (0x2 << 18)
  54. #define RK32_SPI_CONTROL0_TRANSCEIVE_MASK (0x3 << 18)
  55. #define RK32_SPI_CONTROL0_SLAVE_MODE (1 << 20)
  56. #define RK32_SPI_CONTROL0_MICROWIRE_SEQUENTIAL (1 << 21)
  57. //
  58. // Define SPI enable register bits.
  59. //
  60. #define RK32_SPI_ENABLE (1 << 0)
  61. //
  62. // Define SPI status register bits.
  63. //
  64. #define RK32_SPI_STATUS_SPI_BUSY (1 << 0)
  65. #define RK32_SPI_STATUS_TX_FIFO_FULL (1 << 1)
  66. #define RK32_SPI_STATUS_TX_FIFO_EMPTY (1 << 2)
  67. #define RK32_SPI_STATUS_RX_FIFO_EMPTY (1 << 3)
  68. #define RK32_SPI_STATUS_RX_FIFO_FULL (1 << 4)
  69. //
  70. // Define SPI interrupt polarity bits.
  71. //
  72. #define RK32_SPI_INTERRUPT_POLARITY_LOW (1 << 0)
  73. //
  74. // Define SPI interrupt register bits.
  75. //
  76. #define RK32_SPI_INTERRUPT_TX_EMPTY (1 << 0)
  77. #define RK32_SPI_INTERRUPT_TX_OVERFLOW (1 << 1)
  78. #define RK32_SPI_INTERRUPT_RX_UNDERFLOW (1 << 2)
  79. #define RK32_SPI_INTERRUPT_RX_OVERFLOW (1 << 3)
  80. #define RK32_SPI_INTERRUPT_RX_FULL (1 << 4)
  81. #define RK32_SPI_INTERRUPT_MASK \
  82. (RK32_SPI_INTERRUPT_TX_EMPTY | RK32_SPI_INTERRUPT_TX_OVERFLOW | \
  83. RK32_SPI_INTERRUPT_RX_UNDERFLOW | RK32_SPI_INTERRUPT_RX_OVERFLOW | \
  84. RK32_SPI_INTERRUPT_RX_FULL)
  85. #define RK32_SPI_INTERRUPT_ERROR_MASK \
  86. (RK32_SPI_INTERRUPT_TX_OVERFLOW | RK32_SPI_INTERRUPT_RX_UNDERFLOW | \
  87. RK32_SPI_INTERRUPT_RX_OVERFLOW)
  88. #define RK32_SPI_INTERRUPT_DEFAULT_MASK \
  89. (RK32_SPI_INTERRUPT_TX_OVERFLOW | RK32_SPI_INTERRUPT_RX_UNDERFLOW | \
  90. RK32_SPI_INTERRUPT_RX_OVERFLOW | RK32_SPI_INTERRUPT_RX_FULL)
  91. //
  92. // Define DMA control register bits.
  93. //
  94. #define RK32_SPI_DMA_RX_ENABLE (1 << 0)
  95. #define RK32_SPI_DMA_TX_ENABLE (1 << 1)
  96. //
  97. // ------------------------------------------------------ Data Type Definitions
  98. //
  99. typedef enum _RK32_SPI_REGISTER {
  100. Rk32SpiControl0 = 0x00,
  101. Rk32SpiControl1 = 0x04,
  102. Rk32SpiEnable = 0x08,
  103. Rk32SpiSlaveEnable = 0x0C,
  104. Rk32SpiBaudRateSelect = 0x10,
  105. Rk32SpiTxFifoThreshold = 0x14,
  106. Rk32SpiRxFifoThreshold = 0x18,
  107. Rk32SpiTxFifoLevel = 0x1C,
  108. Rk32SpiRxFifoLevel = 0x20,
  109. Rk32SpiSpiStatus = 0x24,
  110. Rk32SpiInterruptPolarity = 0x28,
  111. Rk32SpiInterruptMask = 0x2C,
  112. Rk32SpiInterruptStatus = 0x30,
  113. Rk32SpiRawInterruptStatus = 0x34,
  114. Rk32SpiInterruptClear = 0x38,
  115. Rk32SpiDmaControl = 0x3C,
  116. Rk32SpiDmaTxDataLevel = 0x40,
  117. Rk32SpiDmaRxDataLevel = 0x44,
  118. Rk32SpiTxFifoData = 0x400,
  119. Rk32SpiRxFifoData = 0x800
  120. } RK32_SPI_REGISTER, *PRK32_SPI_REGISTER;
  121. /*++
  122. Structure Description:
  123. This structure defines the context for an RK32 SPI controller.
  124. Members:
  125. OsDevice - Stores a pointer to the OS device object.
  126. InterruptLine - Stores the interrupt line that this controller's interrupt
  127. comes in on.
  128. InterruptVector - Stores the interrupt vector that this controller's
  129. interrupt comes in on.
  130. InterruptResourcesFound - Stores a boolean indicating whether or not the
  131. interrupt line and interrupt vector fields are valid.
  132. InterruptHandle - Stores a pointer to the handle received when the
  133. interrupt was connected.
  134. ControllerBase - Stores the virtual address of the memory mapping to the
  135. SPI controller registers.
  136. SpbController - Stores a pointer to the library Simple Peripheral Bus
  137. controller.
  138. Control - Stores a shadow copy of the current control 0 register.
  139. Transfer - Stores the current transfer being worked on.
  140. PendingInterrupts - Stores a bitfield of pending interrupts.
  141. InterruptMask - Stores a shadow copy of the current interrupt mask.
  142. Lock - Stores a pointer to a lock serializing access to the controller.
  143. --*/
  144. typedef struct _RK32_SPI_CONTROLLER {
  145. PDEVICE OsDevice;
  146. ULONGLONG InterruptLine;
  147. ULONGLONG InterruptVector;
  148. BOOL InterruptResourcesFound;
  149. HANDLE InterruptHandle;
  150. PVOID ControllerBase;
  151. PSPB_CONTROLLER SpbController;
  152. ULONG Control;
  153. PSPB_TRANSFER Transfer;
  154. ULONG PendingInterrupts;
  155. ULONG InterruptMask;
  156. PQUEUED_LOCK Lock;
  157. } RK32_SPI_CONTROLLER, *PRK32_SPI_CONTROLLER;
  158. //
  159. // ----------------------------------------------- Internal Function Prototypes
  160. //
  161. KSTATUS
  162. Rk32SpiAddDevice (
  163. PVOID Driver,
  164. PSTR DeviceId,
  165. PSTR ClassId,
  166. PSTR CompatibleIds,
  167. PVOID DeviceToken
  168. );
  169. VOID
  170. Rk32SpiDispatchStateChange (
  171. PIRP Irp,
  172. PVOID DeviceContext,
  173. PVOID IrpContext
  174. );
  175. VOID
  176. Rk32SpiDispatchOpen (
  177. PIRP Irp,
  178. PVOID DeviceContext,
  179. PVOID IrpContext
  180. );
  181. VOID
  182. Rk32SpiDispatchClose (
  183. PIRP Irp,
  184. PVOID DeviceContext,
  185. PVOID IrpContext
  186. );
  187. VOID
  188. Rk32SpiDispatchIo (
  189. PIRP Irp,
  190. PVOID DeviceContext,
  191. PVOID IrpContext
  192. );
  193. VOID
  194. Rk32SpiDispatchSystemControl (
  195. PIRP Irp,
  196. PVOID DeviceContext,
  197. PVOID IrpContext
  198. );
  199. INTERRUPT_STATUS
  200. Rk32SpiInterruptService (
  201. PVOID Context
  202. );
  203. INTERRUPT_STATUS
  204. Rk32SpiInterruptServiceWorker (
  205. PVOID Context
  206. );
  207. KSTATUS
  208. Rk32SpiProcessResourceRequirements (
  209. PIRP Irp
  210. );
  211. KSTATUS
  212. Rk32SpiStartDevice (
  213. PIRP Irp,
  214. PRK32_SPI_CONTROLLER Device
  215. );
  216. KSTATUS
  217. Rk32SpiConfigureBus (
  218. PVOID Context,
  219. PRESOURCE_SPB_DATA Configuration
  220. );
  221. KSTATUS
  222. Rk32SpiSubmitTransfer (
  223. PVOID Context,
  224. PSPB_TRANSFER Transfer
  225. );
  226. VOID
  227. Rk32SpiLockBus (
  228. PVOID Context,
  229. PRESOURCE_SPB_DATA Configuration
  230. );
  231. VOID
  232. Rk32SpiUnlockBus (
  233. PVOID Context
  234. );
  235. KSTATUS
  236. Rk32SpiSetupTransfer (
  237. PRK32_SPI_CONTROLLER Controller,
  238. PSPB_TRANSFER Transfer
  239. );
  240. KSTATUS
  241. Rk32SpiTransferData (
  242. PRK32_SPI_CONTROLLER Controller,
  243. PSPB_TRANSFER Transfer
  244. );
  245. VOID
  246. Rk32SpiEnableController (
  247. PRK32_SPI_CONTROLLER Controller,
  248. BOOL Enable
  249. );
  250. //
  251. // -------------------------------------------------------------------- Globals
  252. //
  253. PDRIVER Rk32SpiDriver;
  254. SPB_FUNCTION_TABLE Rk32SpiFunctionTableTemplate = {
  255. Rk32SpiConfigureBus,
  256. Rk32SpiSubmitTransfer,
  257. Rk32SpiLockBus,
  258. Rk32SpiUnlockBus
  259. };
  260. //
  261. // ------------------------------------------------------------------ Functions
  262. //
  263. KSTATUS
  264. DriverEntry (
  265. PDRIVER Driver
  266. )
  267. /*++
  268. Routine Description:
  269. This routine is the entry point for the RK32 SPI driver. It registers
  270. its other dispatch functions, and performs driver-wide initialization.
  271. Arguments:
  272. Driver - Supplies a pointer to the driver object.
  273. Return Value:
  274. STATUS_SUCCESS on success.
  275. Failure code on error.
  276. --*/
  277. {
  278. DRIVER_FUNCTION_TABLE FunctionTable;
  279. KSTATUS Status;
  280. Rk32SpiDriver = Driver;
  281. RtlZeroMemory(&FunctionTable, sizeof(DRIVER_FUNCTION_TABLE));
  282. FunctionTable.Version = DRIVER_FUNCTION_TABLE_VERSION;
  283. FunctionTable.AddDevice = Rk32SpiAddDevice;
  284. FunctionTable.DispatchStateChange = Rk32SpiDispatchStateChange;
  285. FunctionTable.DispatchOpen = Rk32SpiDispatchOpen;
  286. FunctionTable.DispatchClose = Rk32SpiDispatchClose;
  287. FunctionTable.DispatchIo = Rk32SpiDispatchIo;
  288. FunctionTable.DispatchSystemControl = Rk32SpiDispatchSystemControl;
  289. Status = IoRegisterDriverFunctions(Driver, &FunctionTable);
  290. return Status;
  291. }
  292. KSTATUS
  293. Rk32SpiAddDevice (
  294. PVOID Driver,
  295. PSTR DeviceId,
  296. PSTR ClassId,
  297. PSTR CompatibleIds,
  298. PVOID DeviceToken
  299. )
  300. /*++
  301. Routine Description:
  302. This routine is called when a device is detected for which this driver
  303. acts as the function driver. The driver will attach itself to the stack.
  304. Arguments:
  305. Driver - Supplies a pointer to the driver being called.
  306. DeviceId - Supplies a pointer to a string with the device ID.
  307. ClassId - Supplies a pointer to a string containing the device's class ID.
  308. CompatibleIds - Supplies a pointer to a string containing device IDs
  309. that would be compatible with this device.
  310. DeviceToken - Supplies an opaque token that the driver can use to identify
  311. the device in the system. This token should be used when attaching to
  312. the stack.
  313. Return Value:
  314. STATUS_SUCCESS on success.
  315. Failure code if the driver was unsuccessful in attaching itself.
  316. --*/
  317. {
  318. PRK32_SPI_CONTROLLER Controller;
  319. KSTATUS Status;
  320. Controller = MmAllocateNonPagedPool(sizeof(RK32_SPI_CONTROLLER),
  321. RK32_SPI_ALLOCATION_TAG);
  322. if (Controller == NULL) {
  323. return STATUS_INSUFFICIENT_RESOURCES;
  324. }
  325. RtlZeroMemory(Controller, sizeof(RK32_SPI_CONTROLLER));
  326. Controller->OsDevice = DeviceToken;
  327. Controller->InterruptHandle = INVALID_HANDLE;
  328. Controller->Lock = KeCreateQueuedLock();
  329. if (Controller->Lock == NULL) {
  330. Status = STATUS_INSUFFICIENT_RESOURCES;
  331. goto AddDeviceEnd;
  332. }
  333. Status = IoAttachDriverToDevice(Driver, DeviceToken, Controller);
  334. AddDeviceEnd:
  335. if (!KSUCCESS(Status)) {
  336. if (Controller != NULL) {
  337. if (Controller->Lock != NULL) {
  338. KeDestroyQueuedLock(Controller->Lock);
  339. }
  340. MmFreeNonPagedPool(Controller);
  341. }
  342. }
  343. return Status;
  344. }
  345. VOID
  346. Rk32SpiDispatchStateChange (
  347. PIRP Irp,
  348. PVOID DeviceContext,
  349. PVOID IrpContext
  350. )
  351. /*++
  352. Routine Description:
  353. This routine handles State Change IRPs.
  354. Arguments:
  355. Irp - Supplies a pointer to the I/O request packet.
  356. DeviceContext - Supplies the context pointer supplied by the driver when it
  357. attached itself to the driver stack. Presumably this pointer contains
  358. driver-specific device context.
  359. IrpContext - Supplies the context pointer supplied by the driver when
  360. the IRP was created.
  361. Return Value:
  362. None.
  363. --*/
  364. {
  365. KSTATUS Status;
  366. ASSERT(Irp->MajorCode == IrpMajorStateChange);
  367. if (Irp->Direction == IrpUp) {
  368. switch (Irp->MinorCode) {
  369. case IrpMinorQueryResources:
  370. Status = Rk32SpiProcessResourceRequirements(Irp);
  371. if (!KSUCCESS(Status)) {
  372. IoCompleteIrp(Rk32SpiDriver, Irp, Status);
  373. }
  374. break;
  375. case IrpMinorStartDevice:
  376. Status = Rk32SpiStartDevice(Irp, DeviceContext);
  377. if (!KSUCCESS(Status)) {
  378. IoCompleteIrp(Rk32SpiDriver, Irp, Status);
  379. }
  380. break;
  381. default:
  382. break;
  383. }
  384. }
  385. return;
  386. }
  387. VOID
  388. Rk32SpiDispatchOpen (
  389. PIRP Irp,
  390. PVOID DeviceContext,
  391. PVOID IrpContext
  392. )
  393. /*++
  394. Routine Description:
  395. This routine handles Open IRPs.
  396. Arguments:
  397. Irp - Supplies a pointer to the I/O request packet.
  398. DeviceContext - Supplies the context pointer supplied by the driver when it
  399. attached itself to the driver stack. Presumably this pointer contains
  400. driver-specific device context.
  401. IrpContext - Supplies the context pointer supplied by the driver when
  402. the IRP was created.
  403. Return Value:
  404. None.
  405. --*/
  406. {
  407. return;
  408. }
  409. VOID
  410. Rk32SpiDispatchClose (
  411. PIRP Irp,
  412. PVOID DeviceContext,
  413. PVOID IrpContext
  414. )
  415. /*++
  416. Routine Description:
  417. This routine handles Close IRPs.
  418. Arguments:
  419. Irp - Supplies a pointer to the I/O request packet.
  420. DeviceContext - Supplies the context pointer supplied by the driver when it
  421. attached itself to the driver stack. Presumably this pointer contains
  422. driver-specific device context.
  423. IrpContext - Supplies the context pointer supplied by the driver when
  424. the IRP was created.
  425. Return Value:
  426. None.
  427. --*/
  428. {
  429. return;
  430. }
  431. VOID
  432. Rk32SpiDispatchIo (
  433. PIRP Irp,
  434. PVOID DeviceContext,
  435. PVOID IrpContext
  436. )
  437. /*++
  438. Routine Description:
  439. This routine handles I/O IRPs.
  440. Arguments:
  441. Irp - Supplies a pointer to the I/O request packet.
  442. DeviceContext - Supplies the context pointer supplied by the driver when it
  443. attached itself to the driver stack. Presumably this pointer contains
  444. driver-specific device context.
  445. IrpContext - Supplies the context pointer supplied by the driver when
  446. the IRP was created.
  447. Return Value:
  448. None.
  449. --*/
  450. {
  451. return;
  452. }
  453. VOID
  454. Rk32SpiDispatchSystemControl (
  455. PIRP Irp,
  456. PVOID DeviceContext,
  457. PVOID IrpContext
  458. )
  459. /*++
  460. Routine Description:
  461. This routine handles System Control IRPs.
  462. Arguments:
  463. Irp - Supplies a pointer to the I/O request packet.
  464. DeviceContext - Supplies the context pointer supplied by the driver when it
  465. attached itself to the driver stack. Presumably this pointer contains
  466. driver-specific device context.
  467. IrpContext - Supplies the context pointer supplied by the driver when
  468. the IRP was created.
  469. Return Value:
  470. None.
  471. --*/
  472. {
  473. ASSERT(Irp->MajorCode == IrpMajorSystemControl);
  474. //
  475. // Do no processing on any IRPs. Let them flow.
  476. //
  477. return;
  478. }
  479. INTERRUPT_STATUS
  480. Rk32SpiInterruptService (
  481. PVOID Context
  482. )
  483. /*++
  484. Routine Description:
  485. This routine implements the interrupt service routine for the RK32 SPI
  486. controller.
  487. Arguments:
  488. Context - Supplies the context supplied when this interrupt was initially
  489. connected.
  490. Return Value:
  491. Returns an interrupt status indicating if this ISR is claiming the
  492. interrupt, not claiming the interrupt, or needs the interrupt to be
  493. masked temporarily.
  494. --*/
  495. {
  496. PRK32_SPI_CONTROLLER Controller;
  497. ULONG Mask;
  498. ULONG Status;
  499. Controller = Context;
  500. Status = RK32_READ_SPI(Controller, Rk32SpiInterruptStatus);
  501. if (Status != 0) {
  502. //
  503. // Clear the bits out of the mask to avoid an interrupt storm.
  504. //
  505. Mask = RK32_READ_SPI(Controller, Rk32SpiInterruptMask);
  506. Mask &= ~Status;
  507. RK32_WRITE_SPI(Controller, Rk32SpiInterruptMask, Mask);
  508. RK32_WRITE_SPI(Controller, Rk32SpiInterruptClear, Status);
  509. RtlAtomicOr32(&(Controller->PendingInterrupts), Status);
  510. return InterruptStatusClaimed;
  511. }
  512. return InterruptStatusNotClaimed;
  513. }
  514. INTERRUPT_STATUS
  515. Rk32SpiInterruptServiceWorker (
  516. PVOID Context
  517. )
  518. /*++
  519. Routine Description:
  520. This routine represents the low level interrupt service routine for the
  521. RK32 SPI controller.
  522. Arguments:
  523. Context - Supplies the context supplied when this interrupt was initially
  524. connected.
  525. Return Value:
  526. Returns an interrupt status indicating if this ISR is claiming the
  527. interrupt, not claiming the interrupt, or needs the interrupt to be
  528. masked temporarily.
  529. --*/
  530. {
  531. PRK32_SPI_CONTROLLER Controller;
  532. ULONG InterruptBits;
  533. KSTATUS Status;
  534. PSPB_TRANSFER Transfer;
  535. Controller = Context;
  536. InterruptBits = RtlAtomicExchange32(&(Controller->PendingInterrupts), 0);
  537. if (InterruptBits == 0) {
  538. return InterruptStatusNotClaimed;
  539. }
  540. KeAcquireQueuedLock(Controller->Lock);
  541. Transfer = Controller->Transfer;
  542. if (Transfer == NULL) {
  543. goto InterruptServiceWorkerEnd;
  544. }
  545. //
  546. // Loop processing transfers.
  547. //
  548. while (TRUE) {
  549. //
  550. // If an error came in, fail the current transfer.
  551. //
  552. if ((InterruptBits & RK32_SPI_INTERRUPT_ERROR_MASK) != 0) {
  553. RtlDebugPrint("RK32 SPI: Error %08x\n", InterruptBits);
  554. Status = STATUS_DEVICE_IO_ERROR;
  555. //
  556. // Transfer more data. If the transfer fills the FIFOs, then
  557. // break out and wait for the interrupt to fire to put more data in.
  558. //
  559. } else {
  560. Status = Rk32SpiTransferData(Controller, Transfer);
  561. if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
  562. break;
  563. }
  564. }
  565. //
  566. // The interrupt bits apply only to the first iteration of the loop.
  567. //
  568. InterruptBits = 0;
  569. //
  570. // The transfer completed entirely, so complete this one and go get a
  571. // new one.
  572. //
  573. Transfer = SpbTransferCompletion(Controller->SpbController,
  574. Transfer,
  575. Status);
  576. if (Transfer == NULL) {
  577. break;
  578. }
  579. Rk32SpiSetupTransfer(Controller, Transfer);
  580. }
  581. InterruptServiceWorkerEnd:
  582. KeReleaseQueuedLock(Controller->Lock);
  583. return InterruptStatusClaimed;
  584. }
  585. //
  586. // --------------------------------------------------------- Internal Functions
  587. //
  588. KSTATUS
  589. Rk32SpiProcessResourceRequirements (
  590. PIRP Irp
  591. )
  592. /*++
  593. Routine Description:
  594. This routine filters through the resource requirements presented by the
  595. bus for an RK32 SPI controller. It adds an interrupt vector requirement
  596. for any interrupt line requested.
  597. Arguments:
  598. Irp - Supplies a pointer to the I/O request packet.
  599. Return Value:
  600. Status code.
  601. --*/
  602. {
  603. PRESOURCE_CONFIGURATION_LIST Requirements;
  604. KSTATUS Status;
  605. RESOURCE_REQUIREMENT VectorRequirement;
  606. ASSERT((Irp->MajorCode == IrpMajorStateChange) &&
  607. (Irp->MinorCode == IrpMinorQueryResources));
  608. //
  609. // Initialize a nice interrupt vector requirement in preparation.
  610. //
  611. RtlZeroMemory(&VectorRequirement, sizeof(RESOURCE_REQUIREMENT));
  612. VectorRequirement.Type = ResourceTypeInterruptVector;
  613. VectorRequirement.Minimum = 0;
  614. VectorRequirement.Maximum = -1;
  615. VectorRequirement.Length = 1;
  616. //
  617. // Loop through all configuration lists, creating a vector for each line.
  618. //
  619. Requirements = Irp->U.QueryResources.ResourceRequirements;
  620. Status = IoCreateAndAddInterruptVectorsForLines(Requirements,
  621. &VectorRequirement);
  622. if (!KSUCCESS(Status)) {
  623. goto ProcessResourceRequirementsEnd;
  624. }
  625. ProcessResourceRequirementsEnd:
  626. return Status;
  627. }
  628. KSTATUS
  629. Rk32SpiStartDevice (
  630. PIRP Irp,
  631. PRK32_SPI_CONTROLLER Device
  632. )
  633. /*++
  634. Routine Description:
  635. This routine starts the RK32 SPI device.
  636. Arguments:
  637. Irp - Supplies a pointer to the start IRP.
  638. Device - Supplies a pointer to the device information.
  639. Return Value:
  640. Status code.
  641. --*/
  642. {
  643. ULONG AlignmentOffset;
  644. PRESOURCE_ALLOCATION Allocation;
  645. PRESOURCE_ALLOCATION_LIST AllocationList;
  646. IO_CONNECT_INTERRUPT_PARAMETERS Connect;
  647. PRESOURCE_ALLOCATION ControllerBase;
  648. PHYSICAL_ADDRESS EndAddress;
  649. PRESOURCE_ALLOCATION LineAllocation;
  650. ULONG PageSize;
  651. PHYSICAL_ADDRESS PhysicalAddress;
  652. SPB_CONTROLLER_INFORMATION Registration;
  653. ULONG Size;
  654. KSTATUS Status;
  655. ControllerBase = NULL;
  656. //
  657. // Loop through the allocated resources to get the controller base and the
  658. // interrupt.
  659. //
  660. ASSERT(Device->InterruptHandle == INVALID_HANDLE);
  661. Device->InterruptResourcesFound = FALSE;
  662. AllocationList = Irp->U.StartDevice.ProcessorLocalResources;
  663. Allocation = IoGetNextResourceAllocation(AllocationList, NULL);
  664. while (Allocation != NULL) {
  665. //
  666. // If the resource is an interrupt vector, then it should have an
  667. // owning interrupt line allocation.
  668. //
  669. if (Allocation->Type == ResourceTypeInterruptVector) {
  670. LineAllocation = Allocation->OwningAllocation;
  671. if (Device->InterruptResourcesFound == FALSE) {
  672. ASSERT(Allocation->OwningAllocation != NULL);
  673. //
  674. // Save the line and vector number.
  675. //
  676. Device->InterruptLine = LineAllocation->Allocation;
  677. Device->InterruptVector = Allocation->Allocation;
  678. Device->InterruptResourcesFound = TRUE;
  679. } else {
  680. ASSERT((Device->InterruptLine == LineAllocation->Allocation) &&
  681. (Device->InterruptVector == Allocation->Allocation));
  682. }
  683. //
  684. // Look for the first physical address reservation, the registers.
  685. //
  686. } else if (Allocation->Type == ResourceTypePhysicalAddressSpace) {
  687. if (ControllerBase == NULL) {
  688. ControllerBase = Allocation;
  689. }
  690. }
  691. //
  692. // Get the next allocation in the list.
  693. //
  694. Allocation = IoGetNextResourceAllocation(AllocationList, Allocation);
  695. }
  696. //
  697. // Fail to start if the controller base was not found.
  698. //
  699. if (ControllerBase == NULL) {
  700. Status = STATUS_INVALID_CONFIGURATION;
  701. goto StartDeviceEnd;
  702. }
  703. //
  704. // Map the controller.
  705. //
  706. if (Device->ControllerBase == NULL) {
  707. //
  708. // Page align the mapping request.
  709. //
  710. PageSize = MmPageSize();
  711. PhysicalAddress = ControllerBase->Allocation;
  712. EndAddress = PhysicalAddress + ControllerBase->Length;
  713. PhysicalAddress = ALIGN_RANGE_DOWN(PhysicalAddress, PageSize);
  714. AlignmentOffset = ControllerBase->Allocation - PhysicalAddress;
  715. EndAddress = ALIGN_RANGE_UP(EndAddress, PageSize);
  716. Size = (ULONG)(EndAddress - PhysicalAddress);
  717. //
  718. // If the size is not a page, then the failure code at the bottom needs
  719. // to be fancier.
  720. //
  721. ASSERT(Size == PageSize);
  722. Device->ControllerBase = MmMapPhysicalAddress(PhysicalAddress,
  723. Size,
  724. TRUE,
  725. FALSE,
  726. TRUE);
  727. if (Device->ControllerBase == NULL) {
  728. Status = STATUS_NO_MEMORY;
  729. goto StartDeviceEnd;
  730. }
  731. Device->ControllerBase += AlignmentOffset;
  732. }
  733. ASSERT(Device->ControllerBase != NULL);
  734. //
  735. // Allocate the controller structures.
  736. //
  737. if (Device->SpbController == NULL) {
  738. RtlZeroMemory(&Registration, sizeof(SPB_CONTROLLER_INFORMATION));
  739. Registration.Version = SPB_CONTROLLER_INFORMATION_VERSION;
  740. Registration.Context = Device;
  741. Registration.Device = Device->OsDevice;
  742. Registration.MaxFrequency = RK32_SPI_INPUT_CLOCK / 2;
  743. Registration.BusType = ResourceSpbBusSpi;
  744. RtlCopyMemory(&(Registration.FunctionTable),
  745. &Rk32SpiFunctionTableTemplate,
  746. sizeof(SPB_FUNCTION_TABLE));
  747. Status = SpbCreateController(&Registration, &(Device->SpbController));
  748. if (!KSUCCESS(Status)) {
  749. goto StartDeviceEnd;
  750. }
  751. }
  752. //
  753. // Start up the controller.
  754. //
  755. Status = SpbStartController(Device->SpbController);
  756. if (!KSUCCESS(Status)) {
  757. goto StartDeviceEnd;
  758. }
  759. //
  760. // Connect the interrupt.
  761. //
  762. if (Device->InterruptHandle == INVALID_HANDLE) {
  763. RtlZeroMemory(&Connect, sizeof(IO_CONNECT_INTERRUPT_PARAMETERS));
  764. Connect.Version = IO_CONNECT_INTERRUPT_PARAMETERS_VERSION;
  765. Connect.Device = Irp->Device;
  766. Connect.LineNumber = Device->InterruptLine;
  767. Connect.Vector = Device->InterruptVector;
  768. Connect.InterruptServiceRoutine = Rk32SpiInterruptService;
  769. Connect.LowLevelServiceRoutine = Rk32SpiInterruptServiceWorker;
  770. Connect.Context = Device;
  771. Connect.Interrupt = &(Device->InterruptHandle);
  772. Status = IoConnectInterrupt(&Connect);
  773. if (!KSUCCESS(Status)) {
  774. return Status;
  775. }
  776. }
  777. StartDeviceEnd:
  778. if (!KSUCCESS(Status)) {
  779. if (Device->ControllerBase != NULL) {
  780. MmUnmapAddress(Device->ControllerBase, MmPageSize());
  781. Device->ControllerBase = NULL;
  782. }
  783. if (Device->SpbController != NULL) {
  784. SpbDestroyController(Device->SpbController);
  785. Device->SpbController = NULL;
  786. }
  787. }
  788. return Status;
  789. }
  790. KSTATUS
  791. Rk32SpiConfigureBus (
  792. PVOID Context,
  793. PRESOURCE_SPB_DATA Configuration
  794. )
  795. /*++
  796. Routine Description:
  797. This routine configures the given Simple Peripheral Bus controller.
  798. Arguments:
  799. Context - Supplies the host controller context.
  800. Configuration - Supplies a pointer to the new configuration to set.
  801. Return Value:
  802. Status code.
  803. --*/
  804. {
  805. ULONG Control;
  806. PRK32_SPI_CONTROLLER Controller;
  807. ULONG Divisor;
  808. PRESOURCE_SPB_SPI Spi;
  809. ULONG Value;
  810. Controller = Context;
  811. if (Configuration->BusType != ResourceSpbBusSpi) {
  812. return STATUS_INVALID_PARAMETER;
  813. }
  814. Spi = PARENT_STRUCTURE(Configuration, RESOURCE_SPB_SPI, Header);
  815. Control = RK32_SPI_CONTROL0_SS_CLK_DELAY_FULL_CLOCK |
  816. RK32_SPI_CONTROL0_APB_8BIT;
  817. if (Spi->WordSize == 4) {
  818. Control |= RK32_SPI_CONTROL0_DATA_FRAME_4;
  819. } else if (Spi->WordSize == 8) {
  820. Control |= RK32_SPI_CONTROL0_DATA_FRAME_8;
  821. } else if (Spi->WordSize == 16) {
  822. Control |= RK32_SPI_CONTROL0_DATA_FRAME_16;
  823. } else {
  824. return STATUS_INVALID_CONFIGURATION;
  825. }
  826. if ((Spi->Flags & RESOURCE_SPB_SPI_SECOND_PHASE) != 0) {
  827. Control |= RK32_SPI_CONTROL0_CLOCK_PHASE;
  828. }
  829. if ((Spi->Flags & RESOURCE_SPB_SPI_START_HIGH) != 0) {
  830. Control |= RK32_SPI_CONTROL0_CLOCK_INACTIVE_HIGH;
  831. }
  832. if ((Spi->Header.Flags & RESOURCE_SPB_DATA_SLAVE) != 0) {
  833. Control |= RK32_SPI_CONTROL0_SLAVE_MODE;
  834. }
  835. KeAcquireQueuedLock(Controller->Lock);
  836. Rk32SpiEnableController(Controller, FALSE);
  837. RK32_WRITE_SPI(Controller, Rk32SpiControl0, Control);
  838. Controller->Control = Control;
  839. Value = (RK32_SPI_FIFO_DEPTH / 2) - 1;
  840. RK32_WRITE_SPI(Controller, Rk32SpiTxFifoThreshold, Value);
  841. //
  842. // Trigger an interrupt as soon as there is any data in the RX FIFO.
  843. //
  844. RK32_WRITE_SPI(Controller, Rk32SpiRxFifoThreshold, 0);
  845. //
  846. // Determine the divisor. Make sure it's even by rounding up, as devices
  847. // can usually handle speeds that are a little too slow, but not a little
  848. // too fast.
  849. //
  850. Divisor = RK32_SPI_INPUT_CLOCK / Spi->Speed;
  851. Divisor = (Divisor + 1) & ~0x1;
  852. RK32_WRITE_SPI(Controller, Rk32SpiBaudRateSelect, Divisor);
  853. RK32_WRITE_SPI(Controller, Rk32SpiSlaveEnable, Spi->DeviceSelect);
  854. KeReleaseQueuedLock(Controller->Lock);
  855. return STATUS_SUCCESS;
  856. }
  857. KSTATUS
  858. Rk32SpiSubmitTransfer (
  859. PVOID Context,
  860. PSPB_TRANSFER Transfer
  861. )
  862. /*++
  863. Routine Description:
  864. This routine is called to execute a single transfer on the Simple
  865. Peripheral Bus. The host controller is responsible for implementing the
  866. delay set in the transfer.
  867. Arguments:
  868. Context - Supplies the host controller context.
  869. Transfer - Supplies a pointer to the transfer to begin executing. The
  870. controller can return immediately, and should call
  871. SpbProcessCompletedTransfer when the transfer completes.
  872. Return Value:
  873. Status code indicating whether or not the transfer was successfully
  874. started.
  875. --*/
  876. {
  877. PRK32_SPI_CONTROLLER Controller;
  878. KSTATUS Status;
  879. KSTATUS TotalStatus;
  880. Controller = Context;
  881. KeAcquireQueuedLock(Controller->Lock);
  882. TotalStatus = STATUS_SUCCESS;
  883. do {
  884. Rk32SpiSetupTransfer(Controller, Transfer);
  885. //
  886. // Begin transferring data. If the transfer fills the FIFOs, then
  887. // break out and wait for the interrupt to fire to put more data in.
  888. //
  889. Status = Rk32SpiTransferData(Controller, Transfer);
  890. if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
  891. break;
  892. }
  893. ASSERT(Controller->Transfer == NULL);
  894. //
  895. // The transfer completed entirely, so complete this one and go get a
  896. // new one.
  897. //
  898. Transfer = SpbTransferCompletion(Controller->SpbController,
  899. Transfer,
  900. Status);
  901. if (!KSUCCESS(Status)) {
  902. if (KSUCCESS(TotalStatus)) {
  903. TotalStatus = Status;
  904. }
  905. }
  906. } while (Transfer != NULL);
  907. KeReleaseQueuedLock(Controller->Lock);
  908. return TotalStatus;
  909. }
  910. VOID
  911. Rk32SpiLockBus (
  912. PVOID Context,
  913. PRESOURCE_SPB_DATA Configuration
  914. )
  915. /*++
  916. Routine Description:
  917. This routine is called when the bus is being locked for a particular
  918. transfer set or directly via the interface. The software synchronization
  919. portion of locking the bus is handled by the SPB library, this routine
  920. only needs to do hardware-specific actions (like selecting or deselecting
  921. device lines).
  922. Arguments:
  923. Context - Supplies the host controller context.
  924. Configuration - Supplies a pointer to the configuration of the handle that
  925. locked this bus. The configure bus function will still be called, this
  926. is only passed for reference if bus-specific actions need to be
  927. performed (like selecting or deselecting the device).
  928. Return Value:
  929. None.
  930. --*/
  931. {
  932. PRK32_SPI_CONTROLLER Controller;
  933. PRESOURCE_SPB_SPI SpiData;
  934. Controller = Context;
  935. SpiData = PARENT_STRUCTURE(Configuration, RESOURCE_SPB_SPI, Header);
  936. ASSERT(SpiData->Header.BusType == ResourceSpbBusSpi);
  937. //
  938. // Select the device.
  939. //
  940. RK32_WRITE_SPI(Controller, Rk32SpiSlaveEnable, SpiData->DeviceSelect);
  941. return;
  942. }
  943. VOID
  944. Rk32SpiUnlockBus (
  945. PVOID Context
  946. )
  947. /*++
  948. Routine Description:
  949. This routine is called when the bus is being unlocked.
  950. Arguments:
  951. Context - Supplies the host controller context.
  952. Return Value:
  953. None.
  954. --*/
  955. {
  956. PRK32_SPI_CONTROLLER Controller;
  957. Controller = Context;
  958. //
  959. // Deselect the device.
  960. //
  961. RK32_WRITE_SPI(Controller, Rk32SpiSlaveEnable, 0);
  962. return;
  963. }
  964. KSTATUS
  965. Rk32SpiSetupTransfer (
  966. PRK32_SPI_CONTROLLER Controller,
  967. PSPB_TRANSFER Transfer
  968. )
  969. /*++
  970. Routine Description:
  971. This routine is called to execute a single transfer on the Simple
  972. Peripheral Bus. The host controller is responsible for implementing the
  973. delay set in the transfer.
  974. Arguments:
  975. Controller - Supplies a pointer to the controller.
  976. Transfer - Supplies a pointer to the transfer to begin executing. The
  977. controller can return immediately, and should call
  978. SpbProcessCompletedTransfer when the transfer completes.
  979. Return Value:
  980. Status code indicating whether or not the transfer was successfully
  981. started.
  982. --*/
  983. {
  984. ULONG Control;
  985. Transfer->ReceiveSizeCompleted = 0;
  986. Transfer->TransmitSizeCompleted = 0;
  987. Rk32SpiEnableController(Controller, FALSE);
  988. //
  989. // Set up the transfer direction.
  990. //
  991. Control = Controller->Control;
  992. Control &= ~RK32_SPI_CONTROL0_TRANSCEIVE_MASK;
  993. switch (Transfer->Direction) {
  994. case SpbTransferDirectionIn:
  995. Control |= RK32_SPI_CONTROL0_RECEIVE_ONLY;
  996. break;
  997. case SpbTransferDirectionOut:
  998. Control |= RK32_SPI_CONTROL0_TRANSMIT_ONLY;
  999. break;
  1000. case SpbTransferDirectionBoth:
  1001. Control |= RK32_SPI_CONTROL0_TRANSMIT_AND_RECEIVE;
  1002. break;
  1003. default:
  1004. ASSERT(FALSE);
  1005. return STATUS_INVALID_PARAMETER;
  1006. }
  1007. if (Control != Controller->Control) {
  1008. RK32_WRITE_SPI(Controller, Rk32SpiControl0, Control);
  1009. Controller->Control = Control;
  1010. }
  1011. RK32_WRITE_SPI(Controller, Rk32SpiControl1, Transfer->Size - 1);
  1012. ASSERT(Controller->Transfer == NULL);
  1013. Controller->Transfer = Transfer;
  1014. Rk32SpiEnableController(Controller, TRUE);
  1015. if (Transfer->MicrosecondDelay != 0) {
  1016. KeDelayExecution(FALSE, FALSE, Transfer->MicrosecondDelay);
  1017. }
  1018. return STATUS_SUCCESS;
  1019. }
  1020. KSTATUS
  1021. Rk32SpiTransferData (
  1022. PRK32_SPI_CONTROLLER Controller,
  1023. PSPB_TRANSFER Transfer
  1024. )
  1025. /*++
  1026. Routine Description:
  1027. This routine transfers data to and from the SPI controller.
  1028. Arguments:
  1029. Controller - Supplies a pointer to the controller.
  1030. Transfer - Supplies a pointer to the transfer to execute.
  1031. Return Value:
  1032. STATUS_MORE_PROCESSING_REQUIRED if more data needs to be sent before the
  1033. transfer is complete.
  1034. STATUS_SUCCESS if the data was transferred successfully.
  1035. Other status codes if the transfer failed.
  1036. --*/
  1037. {
  1038. UCHAR Buffer[RK32_SPI_FIFO_DEPTH];
  1039. SPB_TRANSFER_DIRECTION Direction;
  1040. ULONG Index;
  1041. UINTN Offset;
  1042. ULONG Size;
  1043. KSTATUS Status;
  1044. BOOL TransferDone;
  1045. Direction = Transfer->Direction;
  1046. TransferDone = FALSE;
  1047. Status = STATUS_SUCCESS;
  1048. //
  1049. // Send some data if needed.
  1050. //
  1051. if ((Direction == SpbTransferDirectionOut) ||
  1052. (Direction == SpbTransferDirectionBoth)) {
  1053. Size = RK32_SPI_FIFO_DEPTH -
  1054. RK32_READ_SPI(Controller, Rk32SpiTxFifoLevel);
  1055. //
  1056. // If the transfer has completed, finish it now that everything is out
  1057. // on the wire.
  1058. //
  1059. if ((Transfer->TransmitSizeCompleted == Transfer->Size) &&
  1060. (Size == RK32_SPI_FIFO_DEPTH)) {
  1061. if (Direction == SpbTransferDirectionOut) {
  1062. TransferDone = TRUE;
  1063. goto TransferDataEnd;
  1064. }
  1065. }
  1066. if (Size > Transfer->Size - Transfer->TransmitSizeCompleted) {
  1067. Size = Transfer->Size - Transfer->TransmitSizeCompleted;
  1068. }
  1069. Offset = Transfer->Offset + Transfer->TransmitSizeCompleted;
  1070. Status = MmCopyIoBufferData(Transfer->IoBuffer,
  1071. Buffer,
  1072. Offset,
  1073. Size,
  1074. FALSE);
  1075. if (!KSUCCESS(Status)) {
  1076. TransferDone = TRUE;
  1077. goto TransferDataEnd;
  1078. }
  1079. for (Index = 0; Index < Size; Index += 1) {
  1080. RK32_WRITE_SPI(Controller,
  1081. Rk32SpiTxFifoData,
  1082. Buffer[Transfer->TransmitSizeCompleted + Index]);
  1083. }
  1084. Transfer->TransmitSizeCompleted += Size;
  1085. //
  1086. // Fire an interrupt when the transmit queue is empty again, as
  1087. // more things need to be sent.
  1088. //
  1089. Controller->InterruptMask |= RK32_SPI_INTERRUPT_TX_EMPTY;
  1090. }
  1091. //
  1092. // Receive some data if needed.
  1093. //
  1094. if ((Direction == SpbTransferDirectionIn) ||
  1095. (Direction == SpbTransferDirectionBoth)) {
  1096. Size = RK32_READ_SPI(Controller, Rk32SpiRxFifoLevel);
  1097. while (Size != 0) {
  1098. if (Size > RK32_SPI_FIFO_DEPTH) {
  1099. Size = RK32_SPI_FIFO_DEPTH;
  1100. }
  1101. if (Size > Transfer->Size - Transfer->ReceiveSizeCompleted) {
  1102. Size = Transfer->Size - Transfer->ReceiveSizeCompleted;
  1103. }
  1104. for (Index = 0; Index < Size; Index += 1) {
  1105. Buffer[Index] = RK32_READ_SPI(Controller, Rk32SpiRxFifoData);
  1106. }
  1107. Offset = Transfer->Offset + Transfer->ReceiveSizeCompleted;
  1108. Status = MmCopyIoBufferData(Transfer->IoBuffer,
  1109. Buffer,
  1110. Offset,
  1111. Size,
  1112. TRUE);
  1113. if (!KSUCCESS(Status)) {
  1114. TransferDone = TRUE;
  1115. goto TransferDataEnd;
  1116. }
  1117. Transfer->ReceiveSizeCompleted += Size;
  1118. if (Transfer->ReceiveSizeCompleted >= Transfer->Size) {
  1119. TransferDone = TRUE;
  1120. goto TransferDataEnd;
  1121. }
  1122. Size = RK32_READ_SPI(Controller, Rk32SpiRxFifoLevel);
  1123. }
  1124. }
  1125. TransferDataEnd:
  1126. if (TransferDone != FALSE) {
  1127. //
  1128. // Disable the TX-empty interrupt, otherwise it would just keep firing.
  1129. //
  1130. Controller->InterruptMask &= ~RK32_SPI_INTERRUPT_TX_EMPTY;
  1131. Controller->Transfer = NULL;
  1132. }
  1133. //
  1134. // Refresh the mask, as the ISR disables interrupts in the mask.
  1135. //
  1136. RK32_WRITE_SPI(Controller,
  1137. Rk32SpiInterruptMask,
  1138. Controller->InterruptMask);
  1139. if ((KSUCCESS(Status)) && (TransferDone == FALSE)) {
  1140. Status = STATUS_MORE_PROCESSING_REQUIRED;
  1141. }
  1142. return Status;
  1143. }
  1144. VOID
  1145. Rk32SpiEnableController (
  1146. PRK32_SPI_CONTROLLER Controller,
  1147. BOOL Enable
  1148. )
  1149. /*++
  1150. Routine Description:
  1151. This routine makes sure that the SPI controller is enabled and active.
  1152. Arguments:
  1153. Controller - Supplies a pointer to the controller to initialize.
  1154. Enable - Supplies a boolean indicating whether to enable (TRUE) or disable
  1155. (FALSE) SPI bus access.
  1156. Return Value:
  1157. None.
  1158. --*/
  1159. {
  1160. RK32_WRITE_SPI(Controller, Rk32SpiEnable, Enable);
  1161. if (Enable != FALSE) {
  1162. Controller->InterruptMask = RK32_SPI_INTERRUPT_DEFAULT_MASK;
  1163. } else {
  1164. Controller->InterruptMask = 0;
  1165. }
  1166. RK32_WRITE_SPI(Controller, Rk32SpiInterruptMask, Controller->InterruptMask);
  1167. return;
  1168. }