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