1 /*
2 * Copyright (c) 2020-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 "spi_if.h"
10 #include "devsvc_manager_clnt.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "securec.h"
14 #include "spi_core.h"
15
16 #define HDF_LOG_TAG spi_if
17 #define HOST_NAME_LEN 32
18
19 struct SpiClient {
20 struct SpiCntlr *cntlr;
21 uint32_t csNum;
22 };
23
SpiGetCntlrByBusNum(uint32_t num)24 static struct SpiCntlr *SpiGetCntlrByBusNum(uint32_t num)
25 {
26 int ret;
27 char name[HOST_NAME_LEN + 1] = {0};
28 struct SpiCntlr *cntlr = NULL;
29
30 ret = snprintf_s(name, HOST_NAME_LEN + 1, HOST_NAME_LEN, "HDF_PLATFORM_SPI_%u", num);
31 if (ret < 0) {
32 HDF_LOGE("SpiGetCntlrByBusNum: snprintf_s fail!");
33 return NULL;
34 }
35 cntlr = (struct SpiCntlr *)DevSvcManagerClntGetService(name);
36 return cntlr;
37 }
38
SpiTransfer(DevHandle handle,struct SpiMsg * msgs,uint32_t count)39 int32_t SpiTransfer(DevHandle handle, struct SpiMsg *msgs, uint32_t count)
40 {
41 struct SpiClient *client = NULL;
42
43 if (handle == NULL) {
44 HDF_LOGE("SpiTransfer: handle is null!");
45 return HDF_ERR_INVALID_PARAM;
46 }
47 client = (struct SpiClient *)handle;
48 return SpiCntlrTransfer(client->cntlr, client->csNum, msgs, count);
49 }
50
SpiRead(DevHandle handle,uint8_t * buf,uint32_t len)51 int32_t SpiRead(DevHandle handle, uint8_t *buf, uint32_t len)
52 {
53 struct SpiMsg msg = {0};
54
55 msg.wbuf = NULL;
56 msg.rbuf = buf;
57 msg.len = len;
58 return SpiTransfer(handle, &msg, 1);
59 }
60
SpiWrite(DevHandle handle,uint8_t * buf,uint32_t len)61 int32_t SpiWrite(DevHandle handle, uint8_t *buf, uint32_t len)
62 {
63 struct SpiMsg msg = {0};
64
65 msg.wbuf = buf;
66 msg.rbuf = NULL;
67 msg.len = len;
68 return SpiTransfer(handle, &msg, 1);
69 }
70
SpiSetCfg(DevHandle handle,struct SpiCfg * cfg)71 int32_t SpiSetCfg(DevHandle handle, struct SpiCfg *cfg)
72 {
73 struct SpiClient *client = NULL;
74
75 if (handle == NULL) {
76 HDF_LOGE("SpiSetCfg: handle is null!");
77 return HDF_ERR_INVALID_OBJECT;
78 }
79 client = (struct SpiClient *)handle;
80 return SpiCntlrSetCfg(client->cntlr, client->csNum, cfg);
81 }
82
SpiGetCfg(DevHandle handle,struct SpiCfg * cfg)83 int32_t SpiGetCfg(DevHandle handle, struct SpiCfg *cfg)
84 {
85 struct SpiClient *client = NULL;
86
87 if (handle == NULL) {
88 HDF_LOGE("SpiGetCfg: handle is null!");
89 return HDF_ERR_INVALID_OBJECT;
90 }
91 client = (struct SpiClient *)handle;
92 return SpiCntlrGetCfg(client->cntlr, client->csNum, cfg);
93 }
94
SpiClose(DevHandle handle)95 void SpiClose(DevHandle handle)
96 {
97 int32_t ret;
98 struct SpiClient *client = NULL;
99
100 if (handle == NULL) {
101 HDF_LOGE("SpiClose: handle is null!");
102 return;
103 }
104
105 client = (struct SpiClient *)handle;
106 ret = SpiCntlrClose(client->cntlr, client->csNum);
107 if (ret != HDF_SUCCESS) {
108 HDF_LOGE("SpiClose: error, ret is %d!", ret);
109 }
110 OsalMemFree(handle);
111 }
112
SpiOpen(const struct SpiDevInfo * info)113 DevHandle SpiOpen(const struct SpiDevInfo *info)
114 {
115 int32_t ret;
116 struct SpiClient *object = NULL;
117 struct SpiCntlr *cntlr = NULL;
118
119 if (info == NULL) {
120 HDF_LOGE("SpiOpen: info is null!");
121 return NULL;
122 }
123 cntlr = SpiGetCntlrByBusNum(info->busNum);
124 if (cntlr == NULL) {
125 HDF_LOGE("SpiOpen: cntlr is null!");
126 return NULL;
127 }
128
129 object = (struct SpiClient *)OsalMemCalloc(sizeof(*object));
130 if (object == NULL) {
131 HDF_LOGE("SpiOpen: object malloc error!");
132 return NULL;
133 }
134
135 ret = SpiCntlrOpen(cntlr, info->csNum);
136 if (ret != HDF_SUCCESS) {
137 HDF_LOGE("SpiOpen: spi cntlr open error, ret is %d!", ret);
138 OsalMemFree(object);
139 return NULL;
140 }
141
142 object->cntlr = cntlr;
143 object->csNum = info->csNum;
144 return (DevHandle)object;
145 }
146