1 /*
2 * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hdf_device_desc.h"
17 #include "hdf_log.h"
18 #include "spi_core.h"
19 #include "gd32f4xx_spi.h"
20 #include "spi_if.h"
21 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
22 #include "hcs_macro.h"
23 #include "hdf_config_macro.h"
24 #else
25 #include "device_resource_if.h"
26 #endif
27
28 #define BITWORD_EIGHT 8
29 #define BITWORD_SIXTEEN 16
30 #define PER_MS_IN_SEC 1000
31 #define SPI_CLK 100000000
32 #define WAIT_TIME_MAX 10000
33 #define SPICFG_MODE 0x0000
34 #define SPI_SOFT 0
35
36 #define GPIO_REG_BASE 0x40020000
37 #define GPIO_REG_STEP 0x00000400
38 #define GPIO_BIT_PER_GROUP 16
39
40 typedef enum {
41 BAUD_RATE_DIV2 = 2,
42 BAUD_RATE_DIV4 = 4,
43 BAUD_RATE_DIV8 = 8,
44 BAUD_RATE_DIV16 = 16,
45 BAUD_RATE_DIV32 = 32,
46 BAUD_RATE_DIV64 = 64,
47 BAUD_RATE_DIV128 = 128,
48 BAUD_RATE_DIV256 = 256,
49 } SPI_BAUD_RATE;
50
51 typedef enum {
52 SPI_PORT1 = 0,
53 SPI_PORT2,
54 SPI_PORT3,
55 SPI_PORT4,
56 SPI_PORT5,
57 SPI_PORT6,
58 SPI_PORT_MAX,
59 } SPI_GROUPS;
60
61 typedef struct {
62 uint32_t speed;
63 uint8_t num;
64 uint8_t csPin;
65 uint8_t dataSize;
66 uint8_t misoPin;
67 uint8_t mosiPin;
68 uint8_t clkPin;
69 uint8_t csSoft;
70 uint8_t transMode;
71 uint8_t mode;
72 uint8_t afPin;
73 uint8_t enableQuad;
74 } SpiResource;
75
76 typedef struct {
77 uint32_t spiId;
78 SpiResource resource;
79 } SpiDevice;
80
81 static uint32_t g_spiGroupMaps[SPI_PORT_MAX] = {
82 SPI0, SPI1, SPI2, SPI3, SPI4, SPI5,
83 };
84
85 static uint32_t g_rcuSpiGroupMaps[SPI_PORT_MAX] = {
86 RCU_SPI0, RCU_SPI1, RCU_SPI2, RCU_SPI3, RCU_SPI4, RCU_SPI5,
87 };
88
ToGpioPeriph(uint16_t local)89 static inline uint32_t ToGpioPeriph(uint16_t local)
90 {
91 uint32_t gpioPeriph = 0;
92
93 gpioPeriph = GPIO_REG_BASE + (local / GPIO_BIT_PER_GROUP) * GPIO_REG_STEP;
94
95 return gpioPeriph;
96 }
97
ToGpioPin(uint16_t local)98 static inline uint32_t ToGpioPin(uint16_t local)
99 {
100 uint32_t pinNum = 0;
101
102 pinNum = local % GPIO_BIT_PER_GROUP;
103
104 return (BIT(pinNum));
105 }
106
ToGpioRcuPeriphNum(uint16_t local)107 static inline rcu_periph_enum ToGpioRcuPeriphNum(uint16_t local)
108 {
109 rcu_periph_enum rcuPeriph;
110
111 rcuPeriph = (rcu_periph_enum)(RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, local / GPIO_BIT_PER_GROUP));
112
113 return rcuPeriph;
114 }
115
EnableSpiClock(uint32_t spiNum)116 static void EnableSpiClock(uint32_t spiNum)
117 {
118 switch (spiNum) {
119 case SPI_PORT1:
120 spi_enable(SPI0);
121 case SPI_PORT2:
122 spi_enable(SPI1);
123 case SPI_PORT3:
124 spi_enable(SPI2);
125 case SPI_PORT4:
126 spi_enable(SPI3);
127 case SPI_PORT5:
128 spi_enable(SPI4);
129 case SPI_PORT6:
130 spi_enable(SPI5);
131 default:
132 break;
133 }
134 }
135
InitSpiRcu(const SpiResource * resource)136 static void InitSpiRcu(const SpiResource *resource)
137 {
138 rcu_periph_clock_enable(ToGpioRcuPeriphNum(resource->csPin));
139 rcu_periph_clock_enable(g_rcuSpiGroupMaps[resource->csPin % GPIO_BIT_PER_GROUP]);
140 }
141
InitSpiGpio(const SpiResource * resource)142 static void InitSpiGpio(const SpiResource *resource)
143 {
144 gpio_af_set(ToGpioPeriph(resource->misoPin), AF(resource->afPin), ToGpioPin(resource->misoPin));
145 gpio_af_set(ToGpioPeriph(resource->mosiPin), AF(resource->afPin), ToGpioPin(resource->mosiPin));
146 gpio_af_set(ToGpioPeriph(resource->clkPin), AF(resource->afPin), ToGpioPin(resource->clkPin));
147
148 if (resource->enableQuad == TRUE) {
149 gpio_af_set(GPIOG, AF(resource->afPin), GPIO_PIN_10);
150 gpio_af_set(GPIOG, AF(resource->afPin), GPIO_PIN_11);
151 }
152
153 gpio_mode_set(ToGpioPeriph(resource->misoPin), GPIO_MODE_AF, GPIO_PUPD_NONE, ToGpioPin(resource->misoPin));
154 gpio_mode_set(ToGpioPeriph(resource->mosiPin), GPIO_MODE_AF, GPIO_PUPD_NONE, ToGpioPin(resource->mosiPin));
155 gpio_mode_set(ToGpioPeriph(resource->clkPin), GPIO_MODE_AF, GPIO_PUPD_NONE, ToGpioPin(resource->clkPin));
156 if (resource->enableQuad == TRUE) {
157 gpio_output_options_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
158 gpio_output_options_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
159 }
160
161 gpio_output_options_set(ToGpioPeriph(resource->misoPin), GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,
162 ToGpioPin(resource->misoPin));
163 gpio_output_options_set(ToGpioPeriph(resource->mosiPin), GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,
164 ToGpioPin(resource->mosiPin));
165 gpio_output_options_set(ToGpioPeriph(resource->clkPin), GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,
166 ToGpioPin(resource->clkPin));
167 if (resource->enableQuad == TRUE) {
168 gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_10);
169 gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_11);
170 }
171
172 gpio_mode_set(ToGpioPeriph(resource->csPin), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ToGpioPin(resource->csPin));
173 gpio_output_options_set(ToGpioPeriph(resource->csPin), GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
174 ToGpioPin(resource->csPin));
175 }
176
SpiSendRecv(const SpiDevice * spiDevice,uint8_t * txData,uint8_t * rxData,uint16_t len)177 static int32_t SpiSendRecv(const SpiDevice *spiDevice, uint8_t *txData, uint8_t *rxData, uint16_t len)
178 {
179 uint32_t spiId;
180 uint32_t time = 0;
181 SpiResource *resource = NULL;
182 if (spiDevice == NULL || len == 0) {
183 HDF_LOGE("spi input para err");
184 return HDF_ERR_INVALID_PARAM;
185 }
186 spiId = spiDevice->spiId;
187 resource = &spiDevice->resource;
188
189 if ((resource->transMode == SPI_INTERRUPT_TRANSFER) || (resource->transMode == SPI_DMA_TRANSFER)) {
190 HDF_LOGE("%s: transfer mode is not support!", __func__);
191 return HDF_ERR_INVALID_PARAM;
192 } else if (resource->transMode != SPI_POLLING_TRANSFER) {
193 HDF_LOGE("%s: error transfer mode!", __func__);
194 }
195
196 while (len--) {
197 if (txData != NULL) {
198 time = 0;
199 while ((RESET == spi_i2s_flag_get(g_spiGroupMaps[spiId], SPI_FLAG_TBE)) && (time <= WAIT_TIME_MAX)) {
200 time++;
201 }
202 if (time > WAIT_TIME_MAX) {
203 return HDF_FAILURE;
204 }
205 spi_i2s_data_transmit(g_spiGroupMaps[spiId], *txData);
206 txData++;
207 }
208
209 if (rxData != NULL) {
210 time = 0;
211 while ((RESET == spi_i2s_flag_get(g_spiGroupMaps[spiId], SPI_FLAG_RBNE)) && (time <= WAIT_TIME_MAX)) {
212 time++;
213 }
214 if (time > WAIT_TIME_MAX) {
215 return HDF_FAILURE;
216 }
217 *rxData = spi_i2s_data_receive(g_spiGroupMaps[spiId]);
218 rxData++;
219 }
220 }
221
222 return HDF_SUCCESS;
223 }
SpiClkInit(spi_parameter_struct * spi,const SpiResource * resource)224 static void SpiClkInit(spi_parameter_struct *spi, const SpiResource *resource)
225 {
226 if (SPI_CLK / resource->speed <= BAUD_RATE_DIV2) {
227 spi->prescale = SPI_PSC_2;
228 } else if (SPI_CLK / resource->speed <= BAUD_RATE_DIV4) {
229 spi->prescale = SPI_PSC_4;
230 } else if (SPI_CLK / resource->speed <= BAUD_RATE_DIV8) {
231 spi->prescale = SPI_PSC_8;
232 } else if (SPI_CLK / resource->speed <= BAUD_RATE_DIV16) {
233 spi->prescale = SPI_PSC_16;
234 } else if (SPI_CLK / resource->speed <= BAUD_RATE_DIV32) {
235 spi->prescale = SPI_PSC_32;
236 } else if (SPI_CLK / resource->speed <= BAUD_RATE_DIV64) {
237 spi->prescale = SPI_PSC_64;
238 } else if (SPI_CLK / resource->speed <= BAUD_RATE_DIV128) {
239 spi->prescale = SPI_PSC_128;
240 } else if (SPI_CLK / resource->speed > BAUD_RATE_DIV128) {
241 spi->prescale = SPI_PSC_256;
242 }
243 }
SpiStructInit(spi_parameter_struct * spi,const SpiResource * resource)244 static void SpiStructInit(spi_parameter_struct *spi, const SpiResource *resource)
245 {
246 uint32_t temp = 0;
247 spi->device_mode = SPI_MASTER;
248 spi->trans_mode = SPI_TRANSMODE_FULLDUPLEX;
249 if (resource->dataSize == BITWORD_EIGHT) {
250 spi->frame_size = SPI_FRAMESIZE_8BIT;
251 } else {
252 spi->frame_size = SPI_FRAMESIZE_16BIT;
253 }
254 temp = (resource->mode & (SPI_CLK_PHASE | SPI_CLK_POLARITY));
255 switch (temp) {
256 case (SPI_CLK_PHASE | SPI_CLK_POLARITY):
257 spi->clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
258 break;
259 case SPI_CLK_PHASE:
260 spi->clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
261 break;
262 case SPI_CLK_POLARITY:
263 spi->clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
264 break;
265 default:
266 spi->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
267 break;
268 }
269 if (resource->mode & SPI_MODE_LSBFE) {
270 spi->endian = SPI_ENDIAN_LSB;
271 } else {
272 spi->endian = SPI_ENDIAN_MSB;
273 }
274 if (resource->csSoft == SPI_SOFT) {
275 spi->nss = SPI_NSS_SOFT;
276 } else {
277 spi->nss = SPI_NSS_HARD;
278 }
279 SpiClkInit(spi, resource);
280 return;
281 }
282
InitSpiDevice(const SpiDevice * spiDevice)283 static int32_t InitSpiDevice(const SpiDevice *spiDevice)
284 {
285 SpiResource *resource = NULL;
286 spi_parameter_struct spiInitStruct = {0};
287 uint32_t spix;
288
289 if (spiDevice == NULL) {
290 HDF_LOGE("%s: invalid parameter", __func__);
291 return HDF_ERR_INVALID_PARAM;
292 }
293
294 resource = &spiDevice->resource;
295 spix = g_spiGroupMaps[resource->num];
296
297 SpiStructInit(&spiInitStruct, resource);
298 spi_init(spix, &spiInitStruct);
299
300 if (resource->enableQuad == TRUE) {
301 /* quad wire SPI_IO2 and SPI_IO3 pin output enable */
302 spi_quad_io23_output_enable(spix);
303 }
304
305 spi_enable(spix);
306
307 return HDF_SUCCESS;
308 }
309
310 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
311 #define SPI_FIND_CONFIG(node, name, resource, spiDevice) \
312 do { \
313 if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
314 resource->speed = HCS_PROP(node, speed); \
315 resource->num = HCS_PROP(node, num); \
316 resource->csPin = HCS_PROP(node, csPin); \
317 resource->dataSize = HCS_PROP(node, dataSize); \
318 resource->clkPin = HCS_PROP(node, clkPin); \
319 resource->mosiPin = HCS_PROP(node, mosiPin); \
320 resource->misoPin = HCS_PROP(node, misoPin); \
321 resource->afPin = HCS_PROP(node, afPin); \
322 resource->enableQuad = HCS_PROP(node, enableQuad); \
323 resource->csSoft = HCS_PROP(node, csSoft); \
324 resource->transMode = HCS_PROP(node, transMode); \
325 resource->mode = HCS_PROP(node, mode); \
326 spiDevice->spiId = resource->num; \
327 result = HDF_SUCCESS; \
328 } \
329 } while (0)
330
331 #define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
332 #define PLATFORM_SPI_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), spi_config)
GetSpiDeviceResource(SpiDevice * spiDevice,const char * deviceMatchAttr)333 static int32_t GetSpiDeviceResource(SpiDevice *spiDevice, const char *deviceMatchAttr)
334 {
335 int32_t result = HDF_FAILURE;
336 SpiResource *resource = NULL;
337 if (spiDevice == NULL || deviceMatchAttr == NULL) {
338 HDF_LOGE("device or deviceMatchAttr is NULL");
339 return HDF_ERR_INVALID_PARAM;
340 }
341 resource = &spiDevice->resource;
342 #if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, spi_config)
343 HCS_FOREACH_CHILD_VARGS(PLATFORM_SPI_CONFIG, SPI_FIND_CONFIG, deviceMatchAttr, resource, spiDevice);
344 #endif
345 if (result != HDF_SUCCESS) {
346 HDF_LOGE("resourceNode %s is NULL", deviceMatchAttr);
347 }
348 return result;
349 }
350 #else
GetSpiDeviceResource(SpiDevice * spiDevice,const struct DeviceResourceNode * resourceNode)351 static int32_t GetSpiDeviceResource(SpiDevice *spiDevice, const struct DeviceResourceNode *resourceNode)
352 {
353 struct DeviceResourceIface *dri = NULL;
354 SpiResource *resource = NULL;
355
356 if (spiDevice == NULL || resourceNode == NULL) {
357 HDF_LOGE("%s: PARAM is NULL", __func__);
358 return HDF_ERR_INVALID_PARAM;
359 }
360
361 resource = &spiDevice->resource;
362 if (resource == NULL) {
363 HDF_LOGE("%s: resource is NULL", __func__);
364 return HDF_ERR_INVALID_OBJECT;
365 }
366
367 dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
368 if (dri == NULL || dri->GetUint16 == NULL || dri->GetUint8 == NULL || dri->GetUint32 == NULL) {
369 HDF_LOGE("DeviceResourceIface is invalid");
370 return HDF_ERR_INVALID_PARAM;
371 }
372
373 if (dri->GetUint8(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) {
374 HDF_LOGE("get config num failed");
375 return HDF_FAILURE;
376 }
377 if (dri->GetUint8(resourceNode, "csPin", &resource->csPin, 0) != HDF_SUCCESS) {
378 HDF_LOGE("get config csPin failed");
379 return HDF_FAILURE;
380 }
381 if (dri->GetUint32(resourceNode, "speed", &resource->speed, 0) != HDF_SUCCESS) {
382 HDF_LOGE("get config speed failed");
383 return HDF_FAILURE;
384 }
385 if (dri->GetUint32(resourceNode, "dataSize", &resource->dataSize, 0) != HDF_SUCCESS) {
386 HDF_LOGE("get config dataSize failed");
387 return HDF_FAILURE;
388 }
389 if (dri->GetUint32(resourceNode, "clkPin", &resource->clkPin, 0) != HDF_SUCCESS) {
390 HDF_LOGE("get config spiClkPin failed");
391 return HDF_FAILURE;
392 }
393 if (dri->GetUint32(resourceNode, "mosiPin", &resource->mosiPin, 0) != HDF_SUCCESS) {
394 HDF_LOGE("get config spiMosiPin failed");
395 return HDF_FAILURE;
396 }
397 if (dri->GetUint32(resourceNode, "misoPin", &resource->misoPin, 0) != HDF_SUCCESS) {
398 HDF_LOGE("get config spiMisoPin failed");
399 return HDF_FAILURE;
400 }
401 if (dri->GetUint32(resourceNode, "csSoft", &resource->csSoft, 0) != HDF_SUCCESS) {
402 HDF_LOGE("get config spiCsSoft failed");
403 return HDF_FAILURE;
404 }
405 if (dri->GetUint32(resourceNode, "transMode", &resource->transMode, 0) != HDF_SUCCESS) {
406 HDF_LOGE("get config transMode failed");
407 return HDF_FAILURE;
408 }
409 if (dri->GetUint32(resourceNode, "mode", &resource->mode, 0) != HDF_SUCCESS) {
410 HDF_LOGE("get config mode failed");
411 return HDF_FAILURE;
412 }
413 if (dri->GetUint32(resourceNode, "afPin", &resource->afPin, 0) != HDF_SUCCESS) {
414 HDF_LOGE("get config afPin failed");
415 return HDF_FAILURE;
416 }
417 if (dri->GetUint32(resourceNode, "enableQuad", &resource->enableQuad, 0) != HDF_SUCCESS) {
418 HDF_LOGE("get config enableQuad failed");
419 return HDF_FAILURE;
420 }
421
422 spiDevice->spiId = resource->num;
423
424 return HDF_SUCCESS;
425 }
426 #endif
427
AttachSpiDevice(struct SpiCntlr * spiCntlr,const struct HdfDeviceObject * device)428 static int32_t AttachSpiDevice(struct SpiCntlr *spiCntlr, const struct HdfDeviceObject *device)
429 {
430 int32_t ret;
431 SpiDevice *spiDevice = NULL;
432
433 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
434 if (spiCntlr == NULL || device == NULL) {
435 #else
436 if (spiCntlr == NULL || device == NULL || device->property == NULL) {
437 #endif
438 HDF_LOGE("%s: param is NULL", __func__);
439 return HDF_ERR_INVALID_PARAM;
440 }
441
442 spiDevice = (struct SpiDevice *)OsalMemAlloc(sizeof(*spiDevice));
443 if (spiDevice == NULL) {
444 HDF_LOGE("%s: OsalMemAlloc spiDevice error", __func__);
445 return HDF_ERR_MALLOC_FAIL;
446 }
447
448 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
449 ret = GetSpiDeviceResource(spiDevice, device->deviceMatchAttr);
450 #else
451 ret = GetSpiDeviceResource(spiDevice, device->property);
452 #endif
453 if (ret != HDF_SUCCESS) {
454 (void)OsalMemFree(spiDevice);
455 return HDF_FAILURE;
456 }
457
458 spiCntlr->priv = spiDevice;
459 spiCntlr->busNum = spiDevice->spiId;
460
461 InitSpiRcu(&spiDevice->resource);
462 InitSpiGpio(&spiDevice->resource);
463 InitSpiDevice(spiDevice);
464
465 return HDF_SUCCESS;
466 }
467
468 static int32_t SpiDevOpen(struct SpiCntlr *spiCntlr)
469 {
470 HDF_LOGI("Enter %s", __func__);
471 if (spiCntlr == NULL) {
472 HDF_LOGE("spiCntlr is NULL");
473 return HDF_ERR_INVALID_PARAM;
474 }
475 SpiDevice *spiDevice = NULL;
476 spiDevice = (SpiDevice *)spiCntlr->priv;
477 uint32_t spix = g_spiGroupMaps[spiDevice->resource.num];
478 spi_enable(spix);
479
480 return HDF_SUCCESS;
481 }
482
483 static int32_t SpiDevClose(struct SpiCntlr *spiCntlr)
484 {
485 HDF_LOGI("Enter %s", __func__);
486 if (spiCntlr == NULL) {
487 HDF_LOGE("spiCntlr is NULL");
488 return HDF_ERR_INVALID_PARAM;
489 }
490 SpiDevice *spiDevice = NULL;
491 spiDevice = (SpiDevice *)spiCntlr->priv;
492 uint32_t spix = g_spiGroupMaps[spiDevice->resource.num];
493 spi_disable(spix);
494
495 return HDF_SUCCESS;
496 }
497
498 static int32_t SpiDevGetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg)
499 {
500 SpiDevice *spiDevice = NULL;
501 if (spiCntlr == NULL || spiCfg == NULL || spiCntlr->priv == NULL) {
502 HDF_LOGE("%s: spiCntlr is NULL", __func__);
503 return HDF_ERR_INVALID_PARAM;
504 }
505 spiDevice = (SpiDevice *)spiCntlr->priv;
506 if (spiDevice == NULL) {
507 return HDF_DEV_ERR_NO_DEVICE;
508 }
509
510 spiCfg->maxSpeedHz = spiDevice->resource.speed;
511 spiCfg->mode = spiDevice->resource.mode;
512 spiCfg->transferMode = spiDevice->resource.transMode;
513 spiCfg->bitsPerWord = spiDevice->resource.dataSize;
514
515 return HDF_SUCCESS;
516 }
517
518 static int32_t SpiDevSetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg)
519 {
520 SpiDevice *spiDevice = NULL;
521 if (spiCntlr == NULL || spiCfg == NULL || spiCntlr->priv == NULL) {
522 HDF_LOGE("%s: spiCntlr is NULL", __func__);
523 return HDF_ERR_INVALID_PARAM;
524 }
525 spiDevice = (SpiDevice *)spiCntlr->priv;
526 if (spiDevice == NULL) {
527 HDF_LOGE("%s: spiDevice is NULL", __func__);
528 return HDF_DEV_ERR_NO_DEVICE;
529 }
530
531 if ((spiDevice->resource.speed == spiCfg->maxSpeedHz) && (spiDevice->resource.dataSize == spiCfg->bitsPerWord) &&
532 (spiDevice->resource.transMode == spiCfg->transferMode) && (spiDevice->resource.mode == spiCfg->mode)) {
533 return HDF_SUCCESS;
534 }
535
536 spiDevice->resource.speed = spiCfg->maxSpeedHz;
537 spiDevice->resource.dataSize = spiCfg->bitsPerWord;
538 spiDevice->resource.transMode = spiCfg->transferMode;
539 spiDevice->resource.mode = spiCfg->mode;
540
541 return InitSpiDevice(spiDevice);
542 }
543
544 static int32_t SpiDevTransfer(struct SpiCntlr *spiCntlr, struct SpiMsg *spiMsg, uint32_t count)
545 {
546 SpiDevice *spiDevice = NULL;
547 uint32_t ticks = 0;
548 int32_t ret = 0;
549 uint8_t singleCsChange = 0;
550 struct SpiMsg *msg = NULL;
551 msg = (struct SpiMsg *)OsalMemAlloc(sizeof(*msg));
552 if (spiCntlr == NULL || spiCntlr->priv == NULL) {
553 HDF_LOGE("%s: spiCntlr is NULL", __func__);
554 return HDF_ERR_INVALID_PARAM;
555 }
556 spiDevice = (SpiDevice *)spiCntlr->priv;
557 InitSpiDevice(spiDevice);
558
559 for (size_t i = 0; i < count; i++) {
560 msg = &spiMsg[i];
561 gpio_bit_reset(ToGpioPeriph((spiDevice->resource).csPin), ToGpioPin((spiDevice->resource).csPin));
562
563 ret = SpiSendRecv(spiDevice, msg->wbuf, msg->rbuf, msg->len);
564 if (ret != HDF_SUCCESS) {
565 HDF_LOGE("%s: SpiSendRecv failed: ret is %x", __func__, ret);
566 }
567
568 if (msg->keepCs == 0 || singleCsChange) {
569 gpio_bit_reset(ToGpioPeriph((spiDevice->resource).csPin), ToGpioPin((spiDevice->resource).csPin));
570 }
571 if (msg->delayUs > 0) {
572 ticks = (msg->delayUs / PER_MS_IN_SEC);
573 osDelay(ticks);
574 }
575 }
576
577 HDF_LOGD("%s success\n", __func__);
578 return HDF_SUCCESS;
579 }
580
581 struct SpiCntlrMethod g_method = {
582 .Transfer = SpiDevTransfer,
583 .SetCfg = SpiDevSetCfg,
584 .GetCfg = SpiDevGetCfg,
585 .Open = SpiDevOpen,
586 .Close = SpiDevClose,
587 };
588
589 static int32_t SpiDriverBind(struct HdfDeviceObject *device)
590 {
591 struct SpiCntrl *spiCntlr = NULL;
592
593 HDF_LOGI("%s: Enter ", __func__);
594
595 if (device == NULL) {
596 HDF_LOGE("device object is null!");
597 return HDF_ERR_INVALID_PARAM;
598 }
599
600 spiCntlr = SpiCntlrCreate(device);
601 if (spiCntlr == NULL) {
602 HDF_LOGE("SpiCntrlCreate object failed!");
603 return HDF_FAILURE;
604 }
605 HDF_LOGI("%s spi bind success\n", __func__);
606
607 return HDF_SUCCESS;
608 }
609
610 static int32_t SpiDriverInit(struct HdfDeviceObject *device)
611 {
612 int32_t ret;
613 struct SpiCntlr *spiCntlr = NULL;
614
615 if (device == NULL) {
616 HDF_LOGE("device object is null!");
617 return HDF_ERR_INVALID_PARAM;
618 }
619 HDF_LOGI("%s: Enter", __func__);
620
621 spiCntlr = SpiCntlrFromDevice(device);
622 if (spiCntlr == NULL) {
623 HDF_LOGE("%s: spiCntlr is NULL", __func__);
624 return HDF_DEV_ERR_NO_DEVICE;
625 }
626
627 ret = AttachSpiDevice(spiCntlr, device);
628 if (ret != HDF_SUCCESS) {
629 HDF_LOGE("%s: attach error", __func__);
630 return HDF_DEV_ERR_ATTACHDEV_FAIL;
631 }
632
633 spiCntlr->method = &g_method;
634 HDF_LOGI("%s spi%d init success\n", __func__, spiCntlr->busNum);
635
636 return HDF_SUCCESS;
637 }
638
639 static void SpiDriverRelease(struct HdfDeviceObject *device)
640 {
641 struct SpiCntlr *spiCntlr = NULL;
642 SpiDevice *spiDevice = NULL;
643 if (device == NULL) {
644 HDF_LOGE("%s: device is NULL", __func__);
645 return;
646 }
647
648 spiCntlr = SpiCntlrFromDevice(device);
649 if (spiCntlr == NULL || spiCntlr->priv == NULL) {
650 HDF_LOGE("%s: spiCntlr is NULL", __func__);
651 return;
652 }
653
654 spiDevice = (SpiDevice *)spiCntlr->priv;
655 OsalMemFree(spiDevice);
656
657 HDF_LOGD("%s success", __func__);
658 }
659
660 struct HdfDriverEntry g_hdfSpiDevice = {
661 .moduleVersion = 1,
662 .moduleName = "GD_SPI_MODULE_HDF",
663 .Bind = SpiDriverBind,
664 .Init = SpiDriverInit,
665 .Release = SpiDriverRelease,
666 };
667 HDF_INIT(g_hdfSpiDevice);