• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3  *
4  * This file is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "spi_bes.h"
10 #include <stdlib.h>
11 #include <string.h>
12 #include "spi_core.h"
13 #include "hal_cache.h"
14 #include "hal_trace.h"
15 #include "hdf_log.h"
16 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
17 #include "hcs_macro.h"
18 #include "hdf_config_macro.h"
19 #else
20 #include "device_resource_if.h"
21 #endif
22 
23 #define SPI_DMA_MAX 4095
24 #define DEC_NUM 10
25 #define GROUP_PIN_NUM 8
26 #define TIMEOUT 1000
27 #define SPI_PIN_0 0
28 #define SPI_PIN_1 1
29 #define SPI_PIN_2 2
30 #define SPI_PIN_3 3
31 #define DRIVER_LEVEL 3
32 #define MAX_SPI_NUMBER 2
33 #define MAX_SPI_SPEED 26000000
34 static void Spi0DmaIrq(int error);
35 static void Spi1DmaIrq(int error);
36 
37 static struct SPI_CTX_OBJ_T spiCtx[MAX_SPI_NUMBER] = {
38     {
39         .spiPinCS0 = 0,
40 #if defined (LOSCFG_SOC_SERIES_BES2700)
41         .spiFunDI0 = HAL_IOMUX_FUNC_SYS_SPI_DI0,
42         .spiFunCLK = HAL_IOMUX_FUNC_SYS_SPI_CLK,
43         .spiFunCS0 = HAL_IOMUX_FUNC_SYS_SPI_CS0,
44         .spiFunDIO = HAL_IOMUX_FUNC_SYS_SPI_DIO,
45 #elif defined (LOSCFG_SOC_SERIES_BES2600)
46         .spiFunDI0 = HAL_IOMUX_FUNC_SPI_DI0,
47         .spiFunCLK = HAL_IOMUX_FUNC_SPI_CLK,
48         .spiFunCS0 = HAL_IOMUX_FUNC_SPI_CS0,
49         .spiFunDIO = HAL_IOMUX_FUNC_SPI_DIO,
50 #endif
51         .sem = { NULL },
52         .mutex = { NULL },
53         .SpiOpen = hal_spi_open,
54         .SpiDmaSend = hal_spi_dma_send,
55         .SpiDmaRecv = hal_spi_dma_recv,
56         .SpiSend = hal_spi_send,
57         .SpiRecv = hal_spi_recv,
58         .SpiDmaIrq = Spi0DmaIrq,
59         .SpiClose = hal_spi_close
60     },
61     {
62         .spiPinCS0 = 0,
63 #if defined (LOSCFG_SOC_SERIES_BES2700)
64         .spiFunDI0 = HAL_IOMUX_FUNC_SYS_SPILCD_DI0,
65         .spiFunCLK = HAL_IOMUX_FUNC_SYS_SPILCD_CLK,
66         .spiFunCS0 = HAL_IOMUX_FUNC_SYS_SPILCD_CS0,
67         .spiFunDIO = HAL_IOMUX_FUNC_SYS_SPILCD_DIO,
68 #elif defined (LOSCFG_SOC_SERIES_BES2600)
69         .spiFunDI0 = HAL_IOMUX_FUNC_SPILCD_DI0,
70         .spiFunCLK = HAL_IOMUX_FUNC_SPILCD_CLK,
71         .spiFunCS0 = HAL_IOMUX_FUNC_SPILCD_CS0,
72         .spiFunDIO = HAL_IOMUX_FUNC_SPILCD_DIO,
73 #endif
74         .sem = { NULL },
75         .mutex = { NULL },
76         .SpiOpen = hal_spilcd_open,
77         .SpiDmaSend = hal_spilcd_dma_send,
78         .SpiDmaRecv = hal_spilcd_dma_recv,
79         .SpiSend = hal_spilcd_send,
80         .SpiRecv = hal_spilcd_recv,
81         .SpiDmaIrq = Spi1DmaIrq,
82         .SpiClose = hal_spilcd_close
83     }
84 };
85 
86 static struct HAL_IOMUX_PIN_FUNCTION_MAP pinMuxSpi[] = {
87     {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL },
88     {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL },
89     {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL },
90     {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL },
91 };
92 
Spi0DmaIrq(int error)93 void Spi0DmaIrq(int error)
94 {
95     if (HDF_SUCCESS != OsalSemPost(&spiCtx[0].sem)) {
96         HDF_LOGE("spi0dmairq OsalSemPost failed!\r\n");
97         return;
98     }
99 }
100 
Spi1DmaIrq(int error)101 void Spi1DmaIrq(int error)
102 {
103     if (HDF_SUCCESS != OsalSemPost(&spiCtx[1].sem)) {
104         HDF_LOGE("spi1dmairq OsalSemPost failed!\r\n");
105         return;
106     }
107 }
108 
SpiIomuxInit(struct SpiDevice * spiDevice)109 static void SpiIomuxInit(struct SpiDevice *spiDevice)
110 {
111     struct HAL_SPI_CFG_T *spiDevCfg = NULL;
112     struct SpiResource *resource = NULL;
113     uint32_t spiPort;
114     HDF_LOGI("%s: Enter\r\n", __func__);
115 
116     if (spiDevice == NULL) {
117         HDF_LOGE("%s %d: invalid parameter\r\n", __func__, __LINE__);
118         return;
119     }
120 
121     resource = &spiDevice->resource;
122     if (resource == NULL) {
123         HDF_LOGE("%s %d:resource is null\r\n", __func__, __LINE__);
124         return;
125     }
126     spiDevCfg = &spiDevice->spiDevCfg;
127     if (spiDevCfg == NULL) {
128         HDF_LOGE("%s %d:spiconfig is null\r\n", __func__, __LINE__);
129         return;
130     }
131     spiDevCfg->rate = resource->speed;
132 
133     spiPort = spiDevice->spiId;
134 
135     pinMuxSpi[SPI_PIN_0].pin = resource->spiMisoPin;
136     pinMuxSpi[SPI_PIN_1].pin = resource->spiClkPin;
137     pinMuxSpi[SPI_PIN_2].pin = resource->spiCsPin;
138     pinMuxSpi[SPI_PIN_3].pin = resource->spiMosiPin;
139 
140     spiCtx[spiPort].spiPinCS0 = resource->spiCsPin;
141 
142     pinMuxSpi[SPI_PIN_0].function = spiCtx[spiPort].spiFunDI0;
143     pinMuxSpi[SPI_PIN_1].function = spiCtx[spiPort].spiFunCLK;
144 
145     if (resource->spiCsSoft) {
146         spiCtx[spiPort].spiFunCS0 = HAL_IOMUX_FUNC_AS_GPIO;
147     }
148 
149     pinMuxSpi[SPI_PIN_2].function = spiCtx[spiPort].spiFunCS0;
150     pinMuxSpi[SPI_PIN_3].function = spiCtx[spiPort].spiFunDIO;
151 
152     hal_iomux_set_io_drv(pinMuxSpi[SPI_PIN_0].pin, DRIVER_LEVEL);
153     hal_iomux_set_io_drv(pinMuxSpi[SPI_PIN_1].pin, DRIVER_LEVEL);
154     hal_iomux_set_io_drv(pinMuxSpi[SPI_PIN_2].pin, DRIVER_LEVEL);
155     hal_iomux_set_io_drv(pinMuxSpi[SPI_PIN_3].pin, DRIVER_LEVEL);
156 
157     hal_iomux_init(pinMuxSpi, ARRAY_SIZE(pinMuxSpi));
158 }
159 
SpiDevCfgInit(struct HAL_SPI_CFG_T * spiDevCfg,struct SpiResource * resource)160 static int32_t SpiDevCfgInit(struct HAL_SPI_CFG_T *spiDevCfg, struct SpiResource *resource)
161 {
162     if (spiDevCfg == NULL || resource == NULL) {
163         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
164         return HDF_ERR_INVALID_PARAM;
165     }
166     switch (resource->mode) {
167         case SPI_WORK_MODE_0:
168             spiDevCfg->clk_delay_half = false;
169             spiDevCfg->clk_polarity = false;
170             break;
171         case SPI_WORK_MODE_1:
172             spiDevCfg->clk_delay_half = true;
173             spiDevCfg->clk_polarity = false;
174             break;
175         case SPI_WORK_MODE_2:
176             spiDevCfg->clk_delay_half = false;
177             spiDevCfg->clk_polarity = true;
178             break;
179         case SPI_WORK_MODE_3:
180             spiDevCfg->clk_delay_half = true;
181             spiDevCfg->clk_polarity = true;
182             break;
183         default:
184             spiDevCfg->clk_delay_half = true;
185             spiDevCfg->clk_polarity = true;
186     }
187     spiDevCfg->slave = 0;
188     if (resource->transmode == SPI_TRANSFER_DMA) {
189         spiDevCfg->dma_rx = true;
190         spiDevCfg->dma_tx = true;
191     } else {
192         spiDevCfg->dma_rx = false;
193         spiDevCfg->dma_tx = false;
194     }
195     spiDevCfg->cs = 0;
196     spiDevCfg->rx_bits = resource->dataSize;
197     spiDevCfg->tx_bits = resource->dataSize;
198     spiDevCfg->rx_frame_bits = 0;
199     return HDF_SUCCESS;
200 }
201 /**
202  * Spi send
203  *
204  * @param[in]  spiId   the spi bus id
205  * @param[in]  data     spi send data
206  * @param[in]  size     spi send data size
207  * @param[in]  timeOut  timeOut in milisecond, set this value to HAL_WAIT_FOREVER
208  *                      if you want to wait forever
209  *
210  * @return  0 : on success, EIO : if the SPI device could not be initialised
211  */
212 
213 #ifdef HalSpiSend
214 #undef HalSpiSend
215 #endif
HalSpiSend(struct SpiDevice * spiDevice,const uint8_t * data,uint16_t size,uint32_t timeOut)216 int32_t HalSpiSend(struct SpiDevice *spiDevice, const uint8_t *data, uint16_t size, uint32_t timeOut)
217 {
218     int32_t ret;
219     uint32_t spiId;
220     uint32_t len = size;
221     struct SpiResource *resource = NULL;
222     int32_t status = HDF_FAILURE;
223 
224     if (spiDevice == NULL || data == NULL || size == 0) {
225         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
226         return HDF_ERR_INVALID_PARAM;
227     }
228 
229     spiId = spiDevice->spiId;
230     resource = &spiDevice->resource;
231     if (resource == NULL) {
232         HDF_LOGE("resource is null\r\n");
233         return HDF_ERR_INVALID_OBJECT;
234     }
235     status = OsalMutexLock(&spiCtx[spiId].mutex);
236     if (HDF_SUCCESS != status) {
237         HDF_LOGE("%s spi_mutex wait error = 0x%X!\r\n", __func__, status);
238         return HDF_ERR_TIMEOUT;
239     }
240 #ifdef LOSCFG_SOC_SERIES_BES2700
241     hal_cache_sync_all(HAL_CACHE_ID_D_CACHE);
242 #endif
243     if (resource->transmode == SPI_TRANSFER_DMA) {
244         ret = spiCtx[spiId].SpiDmaSend(data, len, spiCtx[spiId].SpiDmaIrq);
245         if (OsalSemWait(&spiCtx[spiId].sem, timeOut) != HDF_SUCCESS) {
246             HDF_LOGE("spi dma send timeOut\r\n");
247             goto OUT;
248         }
249     } else {
250         ret = spiCtx[spiId].SpiSend(data, len);
251     }
252 
253     if (ret != 0) {
254         HDF_LOGE("spi tail send fail %d, size %u\r\n", ret, len);
255         goto OUT;
256     }
257 OUT:
258     OsalMutexUnlock(&spiCtx[spiId].mutex);
259     return ret;
260 }
261 
262 #ifdef HalSpiRecv
263 #undef HalSpiRecv
264 #endif
265 
266 /**
267  * SpiRecv
268  *
269  * @param[in]   spiId   the spi bus id
270  * @param[out]  data     spi recv data
271  * @param[in]   size     spi recv data size
272  * @param[in]   timeOut  timeOut in milisecond, set this value to HAL_WAIT_FOREVER
273  *                       if you want to wait forever
274  *
275  * @return  0 : on success, EIO : if the SPI device could not be initialised
276  */
HalSpiRecv(struct SpiDevice * spiDevice,uint8_t * data,uint16_t size,uint32_t timeOut)277 static int32_t HalSpiRecv(struct SpiDevice *spiDevice, uint8_t *data, uint16_t size, uint32_t timeOut)
278 {
279     int32_t ret;
280     int32_t len = (int32_t)size;
281     uint32_t remainder;
282     int32_t status = HDF_FAILURE;
283     uint8_t *cmd = NULL;
284     uint32_t spiId;
285     struct SpiResource *resource = NULL;
286     if (spiDevice == NULL || data == NULL || size == 0) {
287         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
288         return HDF_ERR_INVALID_PARAM;
289     }
290 
291     spiId = spiDevice->spiId;
292     resource = &spiDevice->resource;
293     if (resource == NULL) {
294         HDF_LOGE("resource is null\r\n");
295         return HDF_ERR_INVALID_OBJECT;
296     }
297     cmd = (uint8_t *)0x20020000; // 0x20020000 : non secure sram base. tx buf is useless, use sram instead of malloc.
298 
299     status = OsalMutexLock(&spiCtx[spiId].mutex);
300     if (status != HDF_SUCCESS) {
301         HDF_LOGE("%s spi_mutex wait error = 0x%X!\r\n", __func__, status);
302         return HDF_ERR_TIMEOUT;
303     }
304 #ifdef LOSCFG_SOC_SERIES_BES2700
305     hal_cache_sync_all(HAL_CACHE_ID_D_CACHE);
306 #endif
307     do {
308         remainder = len <= SPI_DMA_MAX ? len : SPI_DMA_MAX;
309         if (resource->transmode == SPI_TRANSFER_DMA) {
310             ret = spiCtx[spiId].SpiDmaRecv(cmd, data, remainder, spiCtx[spiId].SpiDmaIrq);
311             if (OsalSemWait(&spiCtx[spiId].sem, timeOut) <= 0) {
312                 HDF_LOGE("SPI Read timeOut!\r\n");
313                 goto OUT;
314             }
315         } else {
316             ret = spiCtx[spiId].SpiRecv(cmd, data, remainder);
317         }
318 
319         len -= remainder;
320         data += remainder;
321 
322         if (ret != 0) {
323             HDF_LOGE("spi tail fail %ld, size %ld\r\n", ret, len);
324             goto OUT;
325         }
326     } while (len);
327 OUT:
328     OsalMutexUnlock(&spiCtx[spiId].mutex);
329     return ret;
330 }
331 
332 #ifdef HalSpiSendRecv
333 #undef HalSpiSendRecv
334 #endif
HalSpiSendRecv(struct SpiDevice * spiDevice,uint8_t * txData,uint16_t txSize,uint8_t * rxData,uint16_t rxSize)335 static int32_t HalSpiSendRecv(struct SpiDevice *spiDevice, uint8_t *txData, uint16_t txSize, uint8_t *rxData,
336                               uint16_t rxSize)
337 {
338     int32_t ret;
339     int32_t status;
340     uint32_t spiId;
341     struct SpiResource *resource = NULL;
342     if (spiDevice == NULL || txData == NULL || txSize == 0 || rxData == NULL || rxSize == 0) {
343         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
344         return HDF_ERR_INVALID_PARAM;
345     }
346     spiId = spiDevice->spiId;
347     resource = &spiDevice->resource;
348     status = OsalMutexLock(&spiCtx[spiId].mutex);
349     if (HDF_SUCCESS != status) {
350         HDF_LOGE("%s OsalMutexLock error = 0x%X!\r\n", __func__, status);
351         return HDF_ERR_TIMEOUT;
352     }
353 #ifdef LOSCFG_SOC_SERIES_BES2700
354     hal_cache_sync_all(HAL_CACHE_ID_D_CACHE);
355 #endif
356     if (resource->transmode == SPI_TRANSFER_DMA) {
357         ret = spiCtx[spiId].SpiDmaRecv(txData, rxData, rxSize, spiCtx[spiId].SpiDmaIrq);
358         if (OsalSemWait(&spiCtx[spiId].sem, TIMEOUT) <= 0) {
359             HDF_LOGE("%s:SPI Read timeOut!\r\n", __func__);
360             goto OUT;
361         }
362     } else {
363         ret = spiCtx[spiId].SpiRecv(txData, rxData, rxSize);
364     }
365     if (ret) {
366         HDF_LOGE("spi dma tail fail %d\r\n", ret);
367     }
368 OUT:
369     OsalMutexUnlock(&spiCtx[spiId].mutex);
370     return ret;
371 }
372 
InitSpiDevice(struct SpiDevice * spiDevice)373 static int32_t InitSpiDevice(struct SpiDevice *spiDevice)
374 {
375     uint32_t spiPort;
376     int32_t ret;
377     struct HAL_SPI_CFG_T *spiDevCfg = NULL;
378     struct SpiResource *resource = NULL;
379     if (spiDevice == NULL) {
380         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
381         return HDF_ERR_INVALID_PARAM;
382     }
383 
384     resource = &spiDevice->resource;
385     spiDevCfg = &spiDevice->spiDevCfg;
386     spiPort = spiDevice->spiId;
387 
388     SpiIomuxInit(spiDevice);
389     ret = SpiDevCfgInit(spiDevCfg, resource);
390     if (ret != HDF_SUCCESS) {
391         HDF_LOGE("%s: SPI config init failed\r\n", __func__);
392         return HDF_FAILURE;
393     }
394     /* spi open move to hdf open api */
395     /* if cs use as gpio ,pull up at first */
396     if (spiCtx[spiPort].spiFunCS0 == HAL_IOMUX_FUNC_AS_GPIO) {
397         hal_gpio_pin_set_dir(spiCtx[spiPort].spiPinCS0, HAL_GPIO_DIR_OUT, 1);
398     }
399 
400     if (&spiCtx[spiPort].sem == NULL) {
401         if (OsalSemInit(&spiCtx[spiPort].sem, 0) != HDF_SUCCESS) {
402             HDF_LOGE("spiDmaSemaphore create failed!\r\n");
403             return HDF_FAILURE;
404         }
405     }
406 
407     if (&spiCtx[spiPort].mutex == NULL) {
408         if (OsalMutexInit(&spiCtx[spiPort].mutex) != HDF_SUCCESS) {
409             HDF_LOGE("spi Mutex create failed!\r\n");
410             return HDF_FAILURE;
411         }
412     }
413     return HDF_SUCCESS;
414 }
415 
416 /* get spi config from hcs file */
GetSpiDeviceIomuxConfig(struct SpiResource * resource,const struct DeviceResourceNode * resourceNode)417 static int32_t GetSpiDeviceIomuxConfig(struct SpiResource *resource, const struct DeviceResourceNode *resourceNode)
418 {
419     struct DeviceResourceIface *dri = NULL;
420     if (resource == NULL || resourceNode == NULL) {
421         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
422         return HDF_ERR_INVALID_PARAM;
423     }
424     dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);   // open HDF
425     if (dri == NULL || dri->GetUint32 == NULL) {
426         HDF_LOGE("DeviceResourceIface is invalid\r\n");
427         return HDF_ERR_INVALID_PARAM;
428     }
429     if (dri->GetUint32(resourceNode, "spiClkPin", &resource->spiClkPin, 0) != HDF_SUCCESS) {
430         HDF_LOGE("spi config read spiClkPin fail\r\n");
431         return HDF_FAILURE;
432     }
433 
434     if (dri->GetUint32(resourceNode, "spiMosiPin", &resource->spiMosiPin, 0) != HDF_SUCCESS) {
435         HDF_LOGE("spi config read spiMosiPin fail\r\n");
436         return HDF_FAILURE;
437     }
438 
439     if (dri->GetUint32(resourceNode, "spiMisoPin", &resource->spiMisoPin, 0) != HDF_SUCCESS) {
440         HDF_LOGE("spi config read spiMisoPin fail\r\n");
441         return HDF_FAILURE;
442     }
443 
444     if (dri->GetUint32(resourceNode, "spiCsPin", &resource->spiCsPin, 0) != HDF_SUCCESS) {
445         HDF_LOGE("spi config read spiCsPin fail\r\n");
446         return HDF_FAILURE;
447     }
448     return HDF_SUCCESS;
449 }
450 
GetSpiDeviceConfig(struct SpiResource * resource,const struct DeviceResourceNode * resourceNode)451 static int32_t GetSpiDeviceConfig(struct SpiResource *resource, const struct DeviceResourceNode *resourceNode)
452 {
453     struct DeviceResourceIface *dri = NULL;
454     if (resource == NULL || resourceNode == NULL) {
455         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
456         return HDF_ERR_INVALID_PARAM;
457     }
458     dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);   // open HDF
459     if (dri == NULL || dri->GetUint32 == NULL) {
460         HDF_LOGE("DeviceResourceIface is invalid\r\n");
461         return HDF_ERR_INVALID_PARAM;
462     }
463 
464     if (dri->GetUint32(resourceNode, "busNum", &resource->num, 0) != HDF_SUCCESS) {
465         HDF_LOGE("spi config read num fail\r\n");
466         return HDF_FAILURE;
467     }
468 
469     if (dri->GetUint32(resourceNode, "speed", &resource->speed, 0) != HDF_SUCCESS) {
470         HDF_LOGE("spi config read base fail\r\n");
471         return HDF_FAILURE;
472     }
473 
474     if (dri->GetUint32(resourceNode, "transmode", &resource->transmode, 0) != HDF_SUCCESS) {
475         HDF_LOGE("spi config read transmode fail\r\n");
476         return HDF_FAILURE;
477     }
478 
479     if (dri->GetUint32(resourceNode, "spiCsSoft", &resource->spiCsSoft, 0) != HDF_SUCCESS) {
480         HDF_LOGE("spi config read spiCsSoft fail\r\n");
481         return HDF_FAILURE;
482     }
483 
484     if (dri->GetUint32(resourceNode, "mode", &resource->mode, 0) != HDF_SUCCESS) {
485         HDF_LOGE("spi config read mode fail\r\n");
486         return HDF_FAILURE;
487     }
488 
489     if (dri->GetUint32(resourceNode, "dataSize", &resource->dataSize, 0) != HDF_SUCCESS) {
490         HDF_LOGE("spi config read dataSize fail\r\n");
491         return HDF_FAILURE;
492     }
493 
494     if (dri->GetUint32(resourceNode, "csNum", &resource->csNum, 0) != HDF_SUCCESS) {
495         HDF_LOGE("spi config read csNum fail\r\n");
496         return HDF_FAILURE;
497     }
498 
499     return GetSpiDeviceIomuxConfig(resource, resourceNode);
500 }
501 
GetSpiDeviceResource(struct SpiDevice * spiDevice,const struct DeviceResourceNode * resourceNode)502 static int32_t GetSpiDeviceResource(struct SpiDevice *spiDevice, const struct DeviceResourceNode *resourceNode)
503 {
504     struct SpiResource *resource = NULL;
505     int32_t ret;
506     if (spiDevice == NULL || resourceNode == NULL) {
507         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
508         return HDF_ERR_INVALID_PARAM;
509     }
510     resource = &spiDevice->resource;
511     if (resource == NULL) {
512         HDF_LOGE("%s: resource is NULL\r\n", __func__);
513         return HDF_ERR_INVALID_OBJECT;
514     }
515     ret = GetSpiDeviceConfig(resource, resourceNode);
516     if (ret != HDF_SUCCESS) {
517         HDF_LOGE("get spi config fail\r\n");
518         return ret;
519     }
520     spiDevice->spiId = resource->num;
521 
522     resource->spiClkPin = (resource->spiClkPin / DEC_NUM) * GROUP_PIN_NUM + (resource->spiClkPin % DEC_NUM);
523 
524     resource->spiMosiPin = (resource->spiMosiPin / DEC_NUM) * GROUP_PIN_NUM + (resource->spiMosiPin % DEC_NUM);
525 
526     resource->spiMisoPin  = ((resource->spiMisoPin / DEC_NUM) * GROUP_PIN_NUM) + (resource->spiMisoPin % DEC_NUM);
527 
528     resource->spiCsPin = ((resource->spiCsPin / DEC_NUM) * GROUP_PIN_NUM) + (resource->spiCsPin % DEC_NUM);
529 
530     return HDF_SUCCESS;
531 }
532 
AttachSpiDevice(struct SpiCntlr * spiCntlr,struct HdfDeviceObject * device)533 int32_t AttachSpiDevice(struct SpiCntlr *spiCntlr, struct HdfDeviceObject *device)
534 {
535     int32_t ret;
536     struct SpiDevice *spiDevice = NULL;
537 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
538     if (spiCntlr == NULL || device == NULL) {
539 #else
540     if (spiCntlr == NULL || device == NULL || device->property == NULL) {
541 #endif
542         HDF_LOGE("%s: property is NULL\r\n", __func__);
543         return HDF_ERR_INVALID_PARAM;
544     }
545 
546     spiDevice = (struct SpiDevice *)OsalMemAlloc(sizeof(struct SpiDevice));
547     if (spiDevice == NULL) {
548         HDF_LOGE("%s: OsalMemAlloc spiDevice error\r\n", __func__);
549         return HDF_ERR_MALLOC_FAIL;
550     }
551 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
552     ret = GetSpiDeviceResource(spiDevice, device->deviceMatchAttr);
553 #else
554     ret = GetSpiDeviceResource(spiDevice, device->property);
555 #endif
556     if (ret != HDF_SUCCESS) {
557         (void)OsalMemFree(spiDevice);
558         return HDF_FAILURE;
559     }
560 
561     spiCntlr->priv = spiDevice;
562     spiCntlr->busNum = spiDevice->spiId;
563     return InitSpiDevice(spiDevice);
564 }
565 /* SPI Method */
566 static int32_t SpiDevGetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg);
567 static int32_t SpiDevSetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg);
568 static int32_t SpiDevTransfer(struct SpiCntlr *spiCntlr, struct SpiMsg *spiMsg, uint32_t count);
569 static int32_t SpiDevOpen(struct SpiCntlr *spiCntlr);
570 static int32_t SpiDevClose(struct SpiCntlr *spiCntlr);
571 
572 struct SpiCntlrMethod g_SpiCntlrMethod = {
573     .GetCfg = SpiDevGetCfg,
574     .SetCfg = SpiDevSetCfg,
575     .Transfer = SpiDevTransfer,
576     .Open = SpiDevOpen,
577     .Close = SpiDevClose,
578 };
579 
580 /* HdfDriverEntry method definitions */
581 static int32_t SpiDriverBind(struct HdfDeviceObject *device);
582 static int32_t SpiDriverInit(struct HdfDeviceObject *device);
583 static void SpiDriverRelease(struct HdfDeviceObject *device);
584 
585 /* HdfDriverEntry definitions */
586 struct HdfDriverEntry g_SpiDriverEntry = {
587     .moduleVersion = 1,
588     .moduleName = "BES_SPI_MODULE_HDF",
589     .Bind = SpiDriverBind,
590     .Init = SpiDriverInit,
591     .Release = SpiDriverRelease,
592 };
593 
594 HDF_INIT(g_SpiDriverEntry);
595 
596 static int32_t SpiDriverBind(struct HdfDeviceObject *device)
597 {
598     struct SpiCntlr *spiCntlr = NULL;
599     if (device == NULL) {
600         HDF_LOGE("Sample device object is null!\r\n");
601         return HDF_ERR_INVALID_PARAM;
602     }
603     HDF_LOGI("Enter %s:\r\n", __func__);
604     spiCntlr = (struct SpiCntlr *)OsalMemAlloc(sizeof(struct SpiCntlr));
605     if (spiCntlr == NULL) {
606         HDF_LOGE("%s: host is NULL\r\n", __func__);
607         return HDF_FAILURE;
608     }
609     device->service = &spiCntlr->service;
610     spiCntlr->device = device;
611     spiCntlr->priv = NULL;
612     return HDF_SUCCESS;
613 }
614 
615 static int32_t SpiDriverInit(struct HdfDeviceObject *device)
616 {
617     int32_t ret;
618     struct SpiCntlr *spiCntlr = NULL;
619 
620     if (device == NULL) {
621         HDF_LOGE("%s: device is NULL\r\n", __func__);
622         return HDF_ERR_INVALID_PARAM;
623     }
624 
625     HDF_LOGI("Enter %s:", __func__);
626     spiCntlr = SpiCntlrFromDevice(device);
627     if (spiCntlr == NULL) {
628         HDF_LOGE("%s: spiCntlr is NULL", __func__);
629         return HDF_DEV_ERR_NO_DEVICE;
630     }
631 
632     ret = AttachSpiDevice(spiCntlr, device); // SpiCntlr add SpiDevice to priv
633     if (ret != HDF_SUCCESS) {
634         HDF_LOGE("%s: attach error\r\n", __func__);
635         return HDF_DEV_ERR_ATTACHDEV_FAIL;
636     }
637 
638     spiCntlr->method = &g_SpiCntlrMethod; // register callback
639 
640     return ret;
641 }
642 
643 static void SpiDriverRelease(struct HdfDeviceObject *device)
644 {
645     struct SpiCntlr *spiCntlr = NULL;
646     struct SpiDevice *spiDevice = NULL;
647 
648     HDF_LOGI("Enter %s\r\n", __func__);
649 
650     if (device == NULL) {
651         HDF_LOGE("%s: device is NULL\r\n", __func__);
652         return;
653     }
654 
655     spiCntlr = SpiCntlrFromDevice(device);
656     if (spiCntlr == NULL) {
657         HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
658         return;
659     }
660 
661     spiDevice = (struct SpiDevice *)spiCntlr->priv;
662     if (spiDevice != NULL) {
663         OsalMemFree(spiDevice);
664     }
665     return;
666 }
667 
668 static int32_t SpiDevOpen(struct SpiCntlr *spiCntlr)
669 {
670     HDF_LOGI("Enter %s\r\n", __func__);
671     int ret;
672     uint32_t spiPort;
673     struct SpiDevice *spiDevice = NULL;
674     struct HAL_SPI_CFG_T *spiDevCfg = NULL;
675     if (spiCntlr == NULL || spiCntlr->priv == NULL) {
676         HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
677         return HDF_ERR_INVALID_PARAM;
678     }
679     spiDevice = (struct SpiDevice *)spiCntlr->priv;
680     spiPort = spiDevice->spiId;
681     spiDevCfg = &spiDevice->spiDevCfg;
682     if (spiDevCfg == NULL) {
683         HDF_LOGE("spi %u config is NULL\r\n", spiPort);
684         return HDF_DEV_ERR_NO_DEVICE;
685     }
686     ret = spiCtx[spiPort].SpiOpen(spiDevCfg);
687     if (ret != 0) {
688         HDF_LOGE("spi %u open error %d\r\n", spiPort, ret);
689         return HDF_FAILURE;
690     }
691     return HDF_SUCCESS;
692 }
693 
694 static int32_t SpiDevClose(struct SpiCntlr *spiCntlr)
695 {
696     int ret;
697     uint32_t spiPort;
698     struct SpiDevice *spiDevice = NULL;
699     struct HAL_SPI_CFG_T *spiDevCfg = NULL;
700     if (spiCntlr == NULL || spiCntlr->priv == NULL) {
701         HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
702         return HDF_ERR_INVALID_PARAM;
703     }
704     spiDevice = (struct SpiDevice *)spiCntlr->priv;
705     spiPort = spiDevice->spiId;
706     spiDevCfg = &spiDevice->spiDevCfg;
707     if (spiDevCfg == NULL) {
708         HDF_LOGE("spi %u config is NULL\r\n", spiPort);
709         return HDF_DEV_ERR_NO_DEVICE;
710     }
711     ret = spiCtx[spiPort].SpiClose(spiDevCfg->cs);
712     if (ret != 0) {
713         HDF_LOGE("spi %ld open error %d\r\n", spiPort, ret);
714         return HDF_FAILURE;
715     }
716     return HDF_SUCCESS;
717 }
718 
719 static int32_t SpiDevGetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg)
720 {
721     struct SpiDevice *spiDevice = NULL;
722     if (spiCntlr == NULL || spiCfg == NULL) {
723         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
724         return HDF_ERR_INVALID_PARAM;
725     }
726     spiDevice = (struct SpiDevice *)spiCntlr->priv;
727     if (spiDevice == NULL) {
728         return HDF_DEV_ERR_NO_DEVICE;
729     }
730     spiCfg->maxSpeedHz = spiDevice->resource.speed;
731     spiCfg->mode = spiDevice->resource.mode;
732     spiCfg->transferMode = spiDevice->resource.transmode;
733     spiCfg->bitsPerWord = spiDevice->resource.dataSize;
734 
735     return HDF_SUCCESS;
736 }
737 
738 static int32_t SpiDevSetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg)
739 {
740     struct SpiDevice *spiDevice = NULL;
741     struct HAL_SPI_CFG_T *spiDevCfg = NULL;
742     if (spiCntlr == NULL || spiCfg == NULL) {
743         HDF_LOGE("%s %d:invalid parameter error\r\n", __func__, __LINE__);
744         return HDF_ERR_INVALID_PARAM;
745     }
746     spiDevice = (struct SpiDevice *)spiCntlr->priv;
747     if (spiDevice == NULL) {
748         return HDF_DEV_ERR_NO_DEVICE;
749     }
750     spiDevCfg = &spiDevice->spiDevCfg;
751     if (spiDevCfg == NULL) {
752         return HDF_ERR_INVALID_OBJECT;
753     }
754     spiDevice->resource.speed = spiCfg->maxSpeedHz;
755     spiDevice->resource.mode = spiCfg->mode;
756     spiDevice->resource.transmode = spiCfg->transferMode;
757     spiDevice->resource.dataSize  = spiCfg->bitsPerWord;
758     spiDevCfg->rate = spiCfg->maxSpeedHz;
759     return InitSpiDevice(spiDevice);
760 }
761 
762 static int32_t SpiDevTransfer(struct SpiCntlr *spiCntlr, struct SpiMsg *spiMsg, uint32_t count)
763 {
764     uint32_t spiId;
765     struct SpiDevice *spiDevice = NULL;
766     struct HAL_SPI_CFG_T *spiDevCfg = NULL;
767     struct SpiMsg *msg = NULL;
768     int32_t ret;
769     if (spiCntlr == NULL || spiCntlr->priv == NULL) {
770         HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
771         return HDF_ERR_INVALID_PARAM;
772     }
773     spiDevice = (struct SpiDevice *)spiCntlr->priv;
774     spiId = spiDevice->spiId;
775     for (size_t i = 0; i < count; i++) {
776         msg = &spiMsg[i];
777         /* pull down cs at first */
778         if (spiDevice->resource.spiCsSoft) {
779             hal_gpio_pin_set_dir(spiCtx[spiId].spiPinCS0, HAL_GPIO_DIR_OUT, 0);
780         }
781 
782         if ((msg->wbuf != NULL) && (msg->rbuf == NULL)) {
783             ret = HalSpiSend(spiDevice, msg->wbuf, msg->len, TIMEOUT);
784         }
785         if ((msg->rbuf != NULL) && (msg->wbuf == NULL)) {
786             ret = HalSpiRecv(spiDevice, msg->rbuf, msg->len, TIMEOUT);
787         }
788         if ((msg->wbuf != NULL) && (msg->rbuf != NULL)) {
789             ret = HalSpiSendRecv(spiDevice, msg->wbuf, msg->len, msg->rbuf, msg->len);
790         }
791 
792         /* pull pull up cs at the end */
793         if (msg->keepCs == 0) {
794             hal_gpio_pin_set_dir(spiCtx[spiId].spiPinCS0, HAL_GPIO_DIR_OUT, 1);
795         }
796         if (ret < 0) {
797             HDF_LOGE("%s send error!\r\n", __func__);
798         }
799         DelayUs(msg->delayUs);
800     }
801     return HDF_SUCCESS;
802 }
803