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