1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF 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 "securec.h"
10 #include "hdf_device_desc.h"
11 #include "device_resource_if.h"
12 #include "osal_mem.h"
13 #include "hdf_base.h"
14 #include "hdf_log.h"
15 #include "spi_test.h"
16
17 #define HDF_LOG_TAG spi_test_driver_c
18
19 static struct SpiTestConfig g_config;
20
SpiTestDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)21 static int32_t SpiTestDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
22 {
23 HDF_LOGD("%s: enter!", __func__);
24 if (cmd != 0) {
25 return HDF_ERR_NOT_SUPPORT;
26 }
27
28 if (reply == NULL) {
29 HDF_LOGE("%s: reply is null!", __func__);
30 return HDF_ERR_INVALID_PARAM;
31 }
32 HDF_LOGE("%s: sizeof(g_config): %d, len: %d", __func__, sizeof(g_config), g_config.len);
33 if (!HdfSbufWriteBuffer(reply, &g_config, sizeof(g_config))) {
34 HDF_LOGE("%s: write config failed", __func__);
35 return HDF_ERR_IO;
36 }
37 if (!HdfSbufWriteBuffer(reply, g_config.wbuf, g_config.len)) {
38 HDF_LOGE("%s: write config failed", __func__);
39 return HDF_ERR_IO;
40 }
41
42 return HDF_SUCCESS;
43 }
44
SpiTestInitFromHcs(struct SpiTestConfig * config,const struct DeviceResourceNode * node)45 static int32_t SpiTestInitFromHcs(struct SpiTestConfig *config, const struct DeviceResourceNode *node)
46 {
47 int32_t ret;
48 struct DeviceResourceIface *face = NULL;
49
50 face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
51 if (face == NULL) {
52 HDF_LOGE("%s: face is null", __func__);
53 return HDF_FAILURE;
54 }
55 if (face->GetUint32 == NULL || face->GetUint8Array == NULL) {
56 HDF_LOGE("%s: GetUint32 or GetUint32Array not support", __func__);
57 return HDF_ERR_NOT_SUPPORT;
58 }
59 ret = face->GetUint32(node, "bus", &config->bus, 0);
60 if (ret != HDF_SUCCESS) {
61 HDF_LOGE("%s: read bus fail", __func__);
62 return HDF_FAILURE;
63 }
64 ret = face->GetUint32(node, "cs", &config->cs, 0);
65 if (ret != HDF_SUCCESS) {
66 HDF_LOGE("%s: read cs fail", __func__);
67 return HDF_FAILURE;
68 }
69 ret = face->GetUint32(node, "len", &config->len, 0);
70 if (ret != HDF_SUCCESS) {
71 HDF_LOGE("%s: read len fail", __func__);
72 return HDF_FAILURE;
73 }
74 config->wbuf = (uint8_t *)OsalMemCalloc(config->len);
75 if (config->wbuf == NULL) {
76 HDF_LOGE("%s: wbuf OsalMemCalloc error\n", __func__);
77 return HDF_ERR_MALLOC_FAIL;
78 }
79
80 ret = face->GetUint8Array(node, "wbuf", g_config.wbuf, config->len, 0);
81 if (ret != HDF_SUCCESS) {
82 HDF_LOGE("%s: read wbuf fail", __func__);
83 OsalMemFree(config->wbuf);
84 return HDF_FAILURE;
85 }
86
87 return HDF_SUCCESS;
88 }
89
SpiTestBind(struct HdfDeviceObject * device)90 static int32_t SpiTestBind(struct HdfDeviceObject *device)
91 {
92 int32_t ret;
93 struct IDeviceIoService *service = NULL;
94
95 service = (struct IDeviceIoService *)OsalMemCalloc(sizeof(*service));
96 if (service == NULL) {
97 HDF_LOGE("%s: malloc service failed!", __func__);
98 return HDF_ERR_MALLOC_FAIL;
99 }
100
101 if (device == NULL || device->property == NULL) {
102 HDF_LOGE("%s: device or config is null!", __func__);
103 return HDF_ERR_IO;
104 }
105
106 ret = SpiTestInitFromHcs(&g_config, device->property);
107 if (ret != HDF_SUCCESS) {
108 HDF_LOGE("%s: read config failed", __func__);
109 return ret;
110 }
111
112 service->Dispatch = SpiTestDispatch;
113 device->service = service;
114
115 return HDF_SUCCESS;
116 }
117
SpiTestInit(struct HdfDeviceObject * device)118 static int32_t SpiTestInit(struct HdfDeviceObject *device)
119 {
120 (void)device;
121 return HDF_SUCCESS;
122 }
123
SpiTestRelease(struct HdfDeviceObject * device)124 static void SpiTestRelease(struct HdfDeviceObject *device)
125 {
126 if (device != NULL && device != NULL) {
127 OsalMemFree(device->service);
128 device->service = NULL;
129 }
130 return;
131 }
132
133 struct HdfDriverEntry g_spiTestEntry = {
134 .moduleVersion = 1,
135 .Bind = SpiTestBind,
136 .Init = SpiTestInit,
137 .Release = SpiTestRelease,
138 .moduleName = "PLATFORM_SPI_TEST",
139 };
140 HDF_INIT(g_spiTestEntry);
141