1 /*
2 * Copyright (c) 2020-2021 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("%s: snprintf_s failed", __func__);
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 return HDF_ERR_INVALID_PARAM;
45 }
46 client = (struct SpiClient *)handle;
47 return SpiCntlrTransfer(client->cntlr, client->csNum, msgs, count);
48 }
49
SpiRead(DevHandle handle,uint8_t * buf,uint32_t len)50 int32_t SpiRead(DevHandle handle, uint8_t *buf, uint32_t len)
51 {
52 struct SpiMsg msg = {0};
53
54 msg.wbuf = NULL;
55 msg.rbuf = buf;
56 msg.len = len;
57 return SpiTransfer(handle, &msg, 1);
58 }
59
SpiWrite(DevHandle handle,uint8_t * buf,uint32_t len)60 int32_t SpiWrite(DevHandle handle, uint8_t *buf, uint32_t len)
61 {
62 struct SpiMsg msg = {0};
63
64 msg.wbuf = buf;
65 msg.rbuf = NULL;
66 msg.len = len;
67 return SpiTransfer(handle, &msg, 1);
68 }
69
SpiSetCfg(DevHandle handle,struct SpiCfg * cfg)70 int32_t SpiSetCfg(DevHandle handle, struct SpiCfg *cfg)
71 {
72 struct SpiClient *client = NULL;
73
74 if (handle == NULL) {
75 return HDF_ERR_INVALID_OBJECT;
76 }
77 client = (struct SpiClient *)handle;
78 return SpiCntlrSetCfg(client->cntlr, client->csNum, cfg);
79 }
80
SpiGetCfg(DevHandle handle,struct SpiCfg * cfg)81 int32_t SpiGetCfg(DevHandle handle, struct SpiCfg *cfg)
82 {
83 struct SpiClient *client = NULL;
84
85 if (handle == NULL) {
86 return HDF_ERR_INVALID_OBJECT;
87 }
88 client = (struct SpiClient *)handle;
89 return SpiCntlrGetCfg(client->cntlr, client->csNum, cfg);
90 }
91
SpiClose(DevHandle handle)92 void SpiClose(DevHandle handle)
93 {
94 int32_t ret;
95 struct SpiClient *client = NULL;
96
97 if (handle == NULL) {
98 HDF_LOGE("%s: handle is NULL", __func__);
99 return;
100 }
101
102 client = (struct SpiClient *)handle;
103 ret = SpiCntlrClose(client->cntlr, client->csNum);
104 if (ret != HDF_SUCCESS) {
105 HDF_LOGE("%s: error, ret is %d", __func__, ret);
106 }
107 OsalMemFree(handle);
108 }
109
SpiOpen(const struct SpiDevInfo * info)110 DevHandle SpiOpen(const struct SpiDevInfo *info)
111 {
112 int32_t ret;
113 struct SpiClient *object = NULL;
114 struct SpiCntlr *cntlr = NULL;
115
116 if (info == NULL) {
117 return NULL;
118 }
119 cntlr = SpiGetCntlrByBusNum(info->busNum);
120 if (cntlr == NULL) {
121 HDF_LOGE("%s: cntlr is null", __func__);
122 return NULL;
123 }
124
125 object = (struct SpiClient *)OsalMemCalloc(sizeof(*object));
126 if (object == NULL) {
127 HDF_LOGE("%s: object malloc error", __func__);
128 return NULL;
129 }
130
131 ret = SpiCntlrOpen(cntlr, info->csNum);
132 if (ret != HDF_SUCCESS) {
133 HDF_LOGE("%s: SpiCntlrOpen error, ret is %d", __func__, ret);
134 OsalMemFree(object);
135 return NULL;
136 }
137
138 object->cntlr = cntlr;
139 object->csNum = info->csNum;
140 return (DevHandle)object;
141 }
142