1d6aed566Sopenharmony_ci/*
2d6aed566Sopenharmony_ci * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3d6aed566Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d6aed566Sopenharmony_ci * you may not use this file except in compliance with the License.
5d6aed566Sopenharmony_ci * You may obtain a copy of the License at
6d6aed566Sopenharmony_ci *
7d6aed566Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d6aed566Sopenharmony_ci *
9d6aed566Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d6aed566Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d6aed566Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d6aed566Sopenharmony_ci * See the License for the specific language governing permissions and
13d6aed566Sopenharmony_ci * limitations under the License.
14d6aed566Sopenharmony_ci */
15d6aed566Sopenharmony_ci
16d6aed566Sopenharmony_ci#include "los_event.h"
17d6aed566Sopenharmony_ci#include "device_resource_if.h"
18d6aed566Sopenharmony_ci#include "hdf_base.h"
19d6aed566Sopenharmony_ci#include "hdf_log.h"
20d6aed566Sopenharmony_ci#include "osal_io.h"
21d6aed566Sopenharmony_ci#include "osal_mem.h"
22d6aed566Sopenharmony_ci#include "osal_time.h"
23d6aed566Sopenharmony_ci#include "uart_core.h"
24d6aed566Sopenharmony_ci#include "uart_dev.h"
25d6aed566Sopenharmony_ci#include "uart_if.h"
26d6aed566Sopenharmony_ci#include "uart_pl011.h"
27d6aed566Sopenharmony_ci
28d6aed566Sopenharmony_ci#define HDF_LOG_TAG uart_hi35xx
29d6aed566Sopenharmony_ci
30d6aed566Sopenharmony_cistatic int32_t Hi35xxRead(struct UartHost *host, uint8_t *data, uint32_t size)
31d6aed566Sopenharmony_ci{
32d6aed566Sopenharmony_ci    int32_t ret;
33d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
34d6aed566Sopenharmony_ci
35d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
36d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
37d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
38d6aed566Sopenharmony_ci    }
39d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
40d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
41d6aed566Sopenharmony_ci        return HDF_FAILURE;
42d6aed566Sopenharmony_ci    }
43d6aed566Sopenharmony_ci    if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) {
44d6aed566Sopenharmony_ci        (void)LOS_EventRead(&udd->wait.stEvent, 0x1, LOS_WAITMODE_OR, LOS_WAIT_FOREVER);
45d6aed566Sopenharmony_ci    }
46d6aed566Sopenharmony_ci    ret = Pl011Read(udd, (char *)data, size);
47d6aed566Sopenharmony_ci    if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) {
48d6aed566Sopenharmony_ci        (void)LOS_EventClear(&udd->wait.stEvent, ~(0x1));
49d6aed566Sopenharmony_ci    }
50d6aed566Sopenharmony_ci    return ret;
51d6aed566Sopenharmony_ci}
52d6aed566Sopenharmony_ci
53d6aed566Sopenharmony_cistatic int32_t Hi35xxWrite(struct UartHost *host, uint8_t *data, uint32_t size)
54d6aed566Sopenharmony_ci{
55d6aed566Sopenharmony_ci    int32_t ret;
56d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
57d6aed566Sopenharmony_ci
58d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
59d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
60d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
61d6aed566Sopenharmony_ci    }
62d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
63d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
64d6aed566Sopenharmony_ci        return HDF_FAILURE;
65d6aed566Sopenharmony_ci    }
66d6aed566Sopenharmony_ci    if (udd->ops->StartTx != NULL) {
67d6aed566Sopenharmony_ci        ret = udd->ops->StartTx(udd, (char *)data, size);
68d6aed566Sopenharmony_ci    } else {
69d6aed566Sopenharmony_ci        ret = HDF_ERR_NOT_SUPPORT;
70d6aed566Sopenharmony_ci        HDF_LOGE("%s: not support", __func__);
71d6aed566Sopenharmony_ci    }
72d6aed566Sopenharmony_ci    return ret;
73d6aed566Sopenharmony_ci}
74d6aed566Sopenharmony_ci
75d6aed566Sopenharmony_cistatic int32_t Hi35xxGetBaud(struct UartHost *host, uint32_t *baudRate)
76d6aed566Sopenharmony_ci{
77d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
78d6aed566Sopenharmony_ci
79d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL || baudRate == NULL) {
80d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
81d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
82d6aed566Sopenharmony_ci    }
83d6aed566Sopenharmony_ci
84d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
85d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
86d6aed566Sopenharmony_ci        return HDF_FAILURE;
87d6aed566Sopenharmony_ci    }
88d6aed566Sopenharmony_ci    *baudRate = udd->baudrate;
89d6aed566Sopenharmony_ci    return HDF_SUCCESS;
90d6aed566Sopenharmony_ci}
91d6aed566Sopenharmony_ci
92d6aed566Sopenharmony_cistatic int32_t Hi35xxSetBaud(struct UartHost *host, uint32_t baudRate)
93d6aed566Sopenharmony_ci{
94d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
95d6aed566Sopenharmony_ci
96d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
97d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
98d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
99d6aed566Sopenharmony_ci    }
100d6aed566Sopenharmony_ci
101d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
102d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
103d6aed566Sopenharmony_ci        return HDF_FAILURE;
104d6aed566Sopenharmony_ci    }
105d6aed566Sopenharmony_ci    if ((baudRate > 0) && (baudRate <= CONFIG_MAX_BAUDRATE)) {
106d6aed566Sopenharmony_ci        udd->baudrate = baudRate;
107d6aed566Sopenharmony_ci        if (udd->ops->Config == NULL) {
108d6aed566Sopenharmony_ci            HDF_LOGE("%s: not support", __func__);
109d6aed566Sopenharmony_ci            return HDF_ERR_NOT_SUPPORT;
110d6aed566Sopenharmony_ci        }
111d6aed566Sopenharmony_ci        if (udd->ops->Config(udd) != HDF_SUCCESS) {
112d6aed566Sopenharmony_ci            HDF_LOGE("%s: config baudrate %d failed", __func__, baudRate);
113d6aed566Sopenharmony_ci            return HDF_FAILURE;
114d6aed566Sopenharmony_ci        }
115d6aed566Sopenharmony_ci    } else {
116d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid baudrate, which is:%d", __func__, baudRate);
117d6aed566Sopenharmony_ci        return HDF_FAILURE;
118d6aed566Sopenharmony_ci    }
119d6aed566Sopenharmony_ci    return HDF_SUCCESS;
120d6aed566Sopenharmony_ci}
121d6aed566Sopenharmony_ci
122d6aed566Sopenharmony_cistatic int32_t Hi35xxGetAttribute(struct UartHost *host, struct UartAttribute *attribute)
123d6aed566Sopenharmony_ci{
124d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
125d6aed566Sopenharmony_ci
126d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL || attribute == NULL) {
127d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
128d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
129d6aed566Sopenharmony_ci    }
130d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
131d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
132d6aed566Sopenharmony_ci        return HDF_FAILURE;
133d6aed566Sopenharmony_ci    }
134d6aed566Sopenharmony_ci    attribute->cts = udd->attr.cts;
135d6aed566Sopenharmony_ci    attribute->dataBits = udd->attr.dataBits;
136d6aed566Sopenharmony_ci    attribute->fifoRxEn = udd->attr.fifoRxEn;
137d6aed566Sopenharmony_ci    attribute->fifoTxEn = udd->attr.fifoTxEn;
138d6aed566Sopenharmony_ci    attribute->parity = udd->attr.parity;
139d6aed566Sopenharmony_ci    attribute->rts = udd->attr.rts;
140d6aed566Sopenharmony_ci    attribute->stopBits = udd->attr.stopBits;
141d6aed566Sopenharmony_ci    return HDF_SUCCESS;
142d6aed566Sopenharmony_ci}
143d6aed566Sopenharmony_ci
144d6aed566Sopenharmony_cistatic int32_t Hi35xxSetAttribute(struct UartHost *host, struct UartAttribute *attribute)
145d6aed566Sopenharmony_ci{
146d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
147d6aed566Sopenharmony_ci
148d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL || attribute == NULL) {
149d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
150d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
151d6aed566Sopenharmony_ci    }
152d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
153d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
154d6aed566Sopenharmony_ci        return HDF_FAILURE;
155d6aed566Sopenharmony_ci    }
156d6aed566Sopenharmony_ci    udd->attr.cts = attribute->cts;
157d6aed566Sopenharmony_ci    udd->attr.dataBits = attribute->dataBits;
158d6aed566Sopenharmony_ci    udd->attr.fifoRxEn = attribute->fifoRxEn;
159d6aed566Sopenharmony_ci    udd->attr.fifoTxEn = attribute->fifoTxEn;
160d6aed566Sopenharmony_ci    udd->attr.parity = attribute->parity;
161d6aed566Sopenharmony_ci    udd->attr.rts = attribute->rts;
162d6aed566Sopenharmony_ci    udd->attr.stopBits = attribute->stopBits;
163d6aed566Sopenharmony_ci    if (udd->ops->Config == NULL) {
164d6aed566Sopenharmony_ci        HDF_LOGE("%s: not support", __func__);
165d6aed566Sopenharmony_ci        return HDF_ERR_NOT_SUPPORT;
166d6aed566Sopenharmony_ci    }
167d6aed566Sopenharmony_ci    if (udd->ops->Config(udd) != HDF_SUCCESS) {
168d6aed566Sopenharmony_ci        HDF_LOGE("%s: config failed", __func__);
169d6aed566Sopenharmony_ci        return HDF_FAILURE;
170d6aed566Sopenharmony_ci    }
171d6aed566Sopenharmony_ci    return HDF_SUCCESS;
172d6aed566Sopenharmony_ci}
173d6aed566Sopenharmony_ci
174d6aed566Sopenharmony_cistatic int32_t Hi35xxSetTransMode(struct UartHost *host, enum UartTransMode mode)
175d6aed566Sopenharmony_ci{
176d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
177d6aed566Sopenharmony_ci
178d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
179d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
180d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
181d6aed566Sopenharmony_ci    }
182d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
183d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
184d6aed566Sopenharmony_ci        return HDF_FAILURE;
185d6aed566Sopenharmony_ci    }
186d6aed566Sopenharmony_ci    if (mode == UART_MODE_RD_BLOCK) {
187d6aed566Sopenharmony_ci        udd->flags |= UART_FLG_RD_BLOCK;
188d6aed566Sopenharmony_ci    } else if (mode == UART_MODE_RD_NONBLOCK) {
189d6aed566Sopenharmony_ci        udd->flags &= ~UART_FLG_RD_BLOCK;
190d6aed566Sopenharmony_ci        (void)LOS_EventWrite(&udd->wait.stEvent, 0x1);
191d6aed566Sopenharmony_ci    }
192d6aed566Sopenharmony_ci    return HDF_SUCCESS;
193d6aed566Sopenharmony_ci}
194d6aed566Sopenharmony_ci
195d6aed566Sopenharmony_cistatic int32_t Hi35xxInit(struct UartHost *host)
196d6aed566Sopenharmony_ci{
197d6aed566Sopenharmony_ci    int32_t ret = 0;
198d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
199d6aed566Sopenharmony_ci    struct wait_queue_head *wait = NULL;
200d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
201d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
202d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
203d6aed566Sopenharmony_ci    }
204d6aed566Sopenharmony_ci
205d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
206d6aed566Sopenharmony_ci    wait = &udd->wait;
207d6aed566Sopenharmony_ci    if (udd->state == UART_STATE_NOT_OPENED) {
208d6aed566Sopenharmony_ci        udd->state = UART_STATE_OPENING;
209d6aed566Sopenharmony_ci        (void)LOS_EventInit(&wait->stEvent);
210d6aed566Sopenharmony_ci        spin_lock_init(&wait->lock);
211d6aed566Sopenharmony_ci        LOS_ListInit(&wait->poll_queue);
212d6aed566Sopenharmony_ci        udd->rxTransfer = (struct UartTransfer *)OsalMemCalloc(sizeof(struct UartTransfer));
213d6aed566Sopenharmony_ci        if (udd->rxTransfer == NULL) {
214d6aed566Sopenharmony_ci            HDF_LOGE("%s: alloc transfer failed", __func__);
215d6aed566Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
216d6aed566Sopenharmony_ci        }
217d6aed566Sopenharmony_ci        if (udd->ops->StartUp == NULL) {
218d6aed566Sopenharmony_ci            HDF_LOGE("%s: not support", __func__);
219d6aed566Sopenharmony_ci            ret = HDF_ERR_NOT_SUPPORT;
220d6aed566Sopenharmony_ci            goto FREE_TRANSFER;
221d6aed566Sopenharmony_ci        }
222d6aed566Sopenharmony_ci        if (udd->ops->StartUp(udd) != HDF_SUCCESS) {
223d6aed566Sopenharmony_ci            HDF_LOGE("%s: StartUp failed", __func__);
224d6aed566Sopenharmony_ci            ret = HDF_FAILURE;
225d6aed566Sopenharmony_ci            goto FREE_TRANSFER;
226d6aed566Sopenharmony_ci        }
227d6aed566Sopenharmony_ci    }
228d6aed566Sopenharmony_ci    udd->state = UART_STATE_USEABLE;
229d6aed566Sopenharmony_ci    udd->count++;
230d6aed566Sopenharmony_ci    return HDF_SUCCESS;
231d6aed566Sopenharmony_ci
232d6aed566Sopenharmony_ciFREE_TRANSFER:
233d6aed566Sopenharmony_ci    (void)OsalMemFree(udd->rxTransfer);
234d6aed566Sopenharmony_ci    udd->rxTransfer = NULL;
235d6aed566Sopenharmony_ci    return ret;
236d6aed566Sopenharmony_ci}
237d6aed566Sopenharmony_ci
238d6aed566Sopenharmony_cistatic int32_t Hi35xxDeinit(struct UartHost *host)
239d6aed566Sopenharmony_ci{
240d6aed566Sopenharmony_ci    struct wait_queue_head *wait = NULL;
241d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
242d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
243d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
244d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
245d6aed566Sopenharmony_ci    }
246d6aed566Sopenharmony_ci
247d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
248d6aed566Sopenharmony_ci    if ((--udd->count) != 0) {
249d6aed566Sopenharmony_ci        return HDF_SUCCESS;
250d6aed566Sopenharmony_ci    }
251d6aed566Sopenharmony_ci    wait = &udd->wait;
252d6aed566Sopenharmony_ci    if (udd->flags & UART_FLG_DMA_RX) {
253d6aed566Sopenharmony_ci        if (udd->ops->DmaShutDown != NULL) {
254d6aed566Sopenharmony_ci            udd->ops->DmaShutDown(udd, UART_DMA_DIR_RX);
255d6aed566Sopenharmony_ci        }
256d6aed566Sopenharmony_ci    }
257d6aed566Sopenharmony_ci    if (udd->flags & UART_FLG_DMA_TX) {
258d6aed566Sopenharmony_ci        if (udd->ops->DmaShutDown != NULL) {
259d6aed566Sopenharmony_ci            udd->ops->DmaShutDown(udd, UART_DMA_DIR_TX);
260d6aed566Sopenharmony_ci        }
261d6aed566Sopenharmony_ci    }
262d6aed566Sopenharmony_ci    LOS_ListDelete(&wait->poll_queue);
263d6aed566Sopenharmony_ci    LOS_EventDestroy(&wait->stEvent);
264d6aed566Sopenharmony_ci    if (udd->ops->ShutDown != NULL) {
265d6aed566Sopenharmony_ci        udd->ops->ShutDown(udd);
266d6aed566Sopenharmony_ci    }
267d6aed566Sopenharmony_ci    if (udd->rxTransfer != NULL) {
268d6aed566Sopenharmony_ci        (void)OsalMemFree(udd->rxTransfer);
269d6aed566Sopenharmony_ci        udd->rxTransfer = NULL;
270d6aed566Sopenharmony_ci    }
271d6aed566Sopenharmony_ci    udd->state = UART_STATE_NOT_OPENED;
272d6aed566Sopenharmony_ci    return HDF_SUCCESS;
273d6aed566Sopenharmony_ci}
274d6aed566Sopenharmony_ci
275d6aed566Sopenharmony_cistatic int32_t Hi35xxPollEvent(struct UartHost *host, void *filep, void *table)
276d6aed566Sopenharmony_ci{
277d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
278d6aed566Sopenharmony_ci
279d6aed566Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
280d6aed566Sopenharmony_ci        HDF_LOGE("%s: host is NULL", __func__);
281d6aed566Sopenharmony_ci        return HDF_FAILURE;
282d6aed566Sopenharmony_ci    }
283d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
284d6aed566Sopenharmony_ci    if (UART_STATE_USEABLE != udd->state) {
285d6aed566Sopenharmony_ci        return -EFAULT;
286d6aed566Sopenharmony_ci    }
287d6aed566Sopenharmony_ci
288d6aed566Sopenharmony_ci    poll_wait((struct file *)filep, &udd->wait, (poll_table *)table);
289d6aed566Sopenharmony_ci
290d6aed566Sopenharmony_ci    if (!PL011UartRxBufEmpty(udd)) {
291d6aed566Sopenharmony_ci        return POLLIN | POLLRDNORM;
292d6aed566Sopenharmony_ci    }
293d6aed566Sopenharmony_ci    return 0;
294d6aed566Sopenharmony_ci}
295d6aed566Sopenharmony_ci
296d6aed566Sopenharmony_cistruct UartHostMethod g_uartHostMethod = {
297d6aed566Sopenharmony_ci    .Init = Hi35xxInit,
298d6aed566Sopenharmony_ci    .Deinit = Hi35xxDeinit,
299d6aed566Sopenharmony_ci    .Read = Hi35xxRead,
300d6aed566Sopenharmony_ci    .Write = Hi35xxWrite,
301d6aed566Sopenharmony_ci    .SetBaud = Hi35xxSetBaud,
302d6aed566Sopenharmony_ci    .GetBaud = Hi35xxGetBaud,
303d6aed566Sopenharmony_ci    .SetAttribute = Hi35xxSetAttribute,
304d6aed566Sopenharmony_ci    .GetAttribute = Hi35xxGetAttribute,
305d6aed566Sopenharmony_ci    .SetTransMode = Hi35xxSetTransMode,
306d6aed566Sopenharmony_ci    .pollEvent = Hi35xxPollEvent,
307d6aed566Sopenharmony_ci};
308d6aed566Sopenharmony_ci
309d6aed566Sopenharmony_cistatic int32_t UartGetConfigFromHcs(struct UartPl011Port *port, const struct DeviceResourceNode *node)
310d6aed566Sopenharmony_ci{
311d6aed566Sopenharmony_ci    uint32_t tmp, regPbase, iomemCount;
312d6aed566Sopenharmony_ci    struct UartDriverData *udd = port->udd;
313d6aed566Sopenharmony_ci    struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
314d6aed566Sopenharmony_ci    if (iface == NULL || iface->GetUint32 == NULL) {
315d6aed566Sopenharmony_ci        HDF_LOGE("%s: face is invalid", __func__);
316d6aed566Sopenharmony_ci        return HDF_FAILURE;
317d6aed566Sopenharmony_ci    }
318d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) {
319d6aed566Sopenharmony_ci        HDF_LOGE("%s: read busNum fail", __func__);
320d6aed566Sopenharmony_ci        return HDF_FAILURE;
321d6aed566Sopenharmony_ci    }
322d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "baudrate", &udd->baudrate, 0) != HDF_SUCCESS) {
323d6aed566Sopenharmony_ci        HDF_LOGE("%s: read numCs fail", __func__);
324d6aed566Sopenharmony_ci        return HDF_FAILURE;
325d6aed566Sopenharmony_ci    }
326d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "fifoRxEn", &tmp, 0) != HDF_SUCCESS) {
327d6aed566Sopenharmony_ci        HDF_LOGE("%s: read speed fail", __func__);
328d6aed566Sopenharmony_ci        return HDF_FAILURE;
329d6aed566Sopenharmony_ci    }
330d6aed566Sopenharmony_ci    udd->attr.fifoRxEn = tmp;
331d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "fifoTxEn", &tmp, 0) != HDF_SUCCESS) {
332d6aed566Sopenharmony_ci        HDF_LOGE("%s: read fifoSize fail", __func__);
333d6aed566Sopenharmony_ci        return HDF_FAILURE;
334d6aed566Sopenharmony_ci    }
335d6aed566Sopenharmony_ci    udd->attr.fifoTxEn = tmp;
336d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "flags", &udd->flags, 0) != HDF_SUCCESS) {
337d6aed566Sopenharmony_ci        HDF_LOGE("%s: read clkRate fail", __func__);
338d6aed566Sopenharmony_ci        return HDF_FAILURE;
339d6aed566Sopenharmony_ci    }
340d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "regPbase", &regPbase, 0) != HDF_SUCCESS) {
341d6aed566Sopenharmony_ci        HDF_LOGE("%s: read mode fail", __func__);
342d6aed566Sopenharmony_ci        return HDF_FAILURE;
343d6aed566Sopenharmony_ci    }
344d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "iomemCount", &iomemCount, 0) != HDF_SUCCESS) {
345d6aed566Sopenharmony_ci        HDF_LOGE("%s: read bitsPerWord fail", __func__);
346d6aed566Sopenharmony_ci        return HDF_FAILURE;
347d6aed566Sopenharmony_ci    }
348d6aed566Sopenharmony_ci    port->physBase = (unsigned long)OsalIoRemap(regPbase, iomemCount);
349d6aed566Sopenharmony_ci    if (iface->GetUint32(node, "interrupt", &port->irqNum, 0) != HDF_SUCCESS) {
350d6aed566Sopenharmony_ci        HDF_LOGE("%s: read comMode fail", __func__);
351d6aed566Sopenharmony_ci        return HDF_FAILURE;
352d6aed566Sopenharmony_ci    }
353d6aed566Sopenharmony_ci    return 0;
354d6aed566Sopenharmony_ci}
355d6aed566Sopenharmony_ci
356d6aed566Sopenharmony_cistatic int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device)
357d6aed566Sopenharmony_ci{
358d6aed566Sopenharmony_ci    int32_t ret;
359d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
360d6aed566Sopenharmony_ci    struct UartPl011Port *port = NULL;
361d6aed566Sopenharmony_ci
362d6aed566Sopenharmony_ci    if (device->property == NULL) {
363d6aed566Sopenharmony_ci        HDF_LOGE("%s: property is null", __func__);
364d6aed566Sopenharmony_ci        return HDF_FAILURE;
365d6aed566Sopenharmony_ci    }
366d6aed566Sopenharmony_ci    udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));
367d6aed566Sopenharmony_ci    if (udd == NULL) {
368d6aed566Sopenharmony_ci        HDF_LOGE("%s: OsalMemCalloc udd error", __func__);
369d6aed566Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
370d6aed566Sopenharmony_ci    }
371d6aed566Sopenharmony_ci    port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port));
372d6aed566Sopenharmony_ci    if (port == NULL) {
373d6aed566Sopenharmony_ci        HDF_LOGE("%s: OsalMemCalloc port error", __func__);
374d6aed566Sopenharmony_ci        (void)OsalMemFree(udd);
375d6aed566Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
376d6aed566Sopenharmony_ci    }
377d6aed566Sopenharmony_ci    udd->ops = Pl011GetOps();
378d6aed566Sopenharmony_ci    udd->recv = PL011UartRecvNotify;
379d6aed566Sopenharmony_ci    udd->count = 0;
380d6aed566Sopenharmony_ci    port->udd = udd;
381d6aed566Sopenharmony_ci    ret = UartGetConfigFromHcs(port, device->property);
382d6aed566Sopenharmony_ci    if (ret != 0 || port->physBase == 0) {
383d6aed566Sopenharmony_ci        (void)OsalMemFree(port);
384d6aed566Sopenharmony_ci        (void)OsalMemFree(udd);
385d6aed566Sopenharmony_ci        return HDF_FAILURE;
386d6aed566Sopenharmony_ci    }
387d6aed566Sopenharmony_ci    udd->private = port;
388d6aed566Sopenharmony_ci    host->priv = udd;
389d6aed566Sopenharmony_ci    host->num = udd->num;
390d6aed566Sopenharmony_ci    UartAddDev(host);
391d6aed566Sopenharmony_ci    return HDF_SUCCESS;
392d6aed566Sopenharmony_ci}
393d6aed566Sopenharmony_ci
394d6aed566Sopenharmony_cistatic void Hi35xxDetach(struct UartHost *host)
395d6aed566Sopenharmony_ci{
396d6aed566Sopenharmony_ci    struct UartDriverData *udd = NULL;
397d6aed566Sopenharmony_ci    struct UartPl011Port *port = NULL;
398d6aed566Sopenharmony_ci
399d6aed566Sopenharmony_ci    if (host->priv == NULL) {
400d6aed566Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
401d6aed566Sopenharmony_ci        return;
402d6aed566Sopenharmony_ci    }
403d6aed566Sopenharmony_ci    udd = host->priv;
404d6aed566Sopenharmony_ci    if (udd->state != UART_STATE_NOT_OPENED) {
405d6aed566Sopenharmony_ci        HDF_LOGE("%s: uart driver data state invalid", __func__);
406d6aed566Sopenharmony_ci        return;
407d6aed566Sopenharmony_ci    }
408d6aed566Sopenharmony_ci    UartRemoveDev(host);
409d6aed566Sopenharmony_ci    port = udd->private;
410d6aed566Sopenharmony_ci    if (port != NULL) {
411d6aed566Sopenharmony_ci        if (port->physBase != 0) {
412d6aed566Sopenharmony_ci            OsalIoUnmap((void *)port->physBase);
413d6aed566Sopenharmony_ci        }
414d6aed566Sopenharmony_ci        (void)OsalMemFree(port);
415d6aed566Sopenharmony_ci        udd->private = NULL;
416d6aed566Sopenharmony_ci    }
417d6aed566Sopenharmony_ci    (void)OsalMemFree(udd);
418d6aed566Sopenharmony_ci    host->priv = NULL;
419d6aed566Sopenharmony_ci}
420d6aed566Sopenharmony_ci
421d6aed566Sopenharmony_cistatic int32_t HdfUartDeviceBind(struct HdfDeviceObject *device)
422d6aed566Sopenharmony_ci{
423d6aed566Sopenharmony_ci    HDF_LOGI("%s: entry", __func__);
424d6aed566Sopenharmony_ci    if (device == NULL) {
425d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
426d6aed566Sopenharmony_ci    }
427d6aed566Sopenharmony_ci    return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
428d6aed566Sopenharmony_ci}
429d6aed566Sopenharmony_ci
430d6aed566Sopenharmony_ciint32_t HdfUartDeviceInit(struct HdfDeviceObject *device)
431d6aed566Sopenharmony_ci{
432d6aed566Sopenharmony_ci    int32_t ret;
433d6aed566Sopenharmony_ci    struct UartHost *host = NULL;
434d6aed566Sopenharmony_ci
435d6aed566Sopenharmony_ci    HDF_LOGI("%s: entry", __func__);
436d6aed566Sopenharmony_ci    if (device == NULL) {
437d6aed566Sopenharmony_ci        HDF_LOGE("%s: device is null", __func__);
438d6aed566Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
439d6aed566Sopenharmony_ci    }
440d6aed566Sopenharmony_ci    host = UartHostFromDevice(device);
441d6aed566Sopenharmony_ci    if (host == NULL) {
442d6aed566Sopenharmony_ci        HDF_LOGE("%s: host is null", __func__);
443d6aed566Sopenharmony_ci        return HDF_FAILURE;
444d6aed566Sopenharmony_ci    }
445d6aed566Sopenharmony_ci    ret = Hi35xxAttach(host, device);
446d6aed566Sopenharmony_ci    if (ret != HDF_SUCCESS) {
447d6aed566Sopenharmony_ci        HDF_LOGE("%s: attach error", __func__);
448d6aed566Sopenharmony_ci        return HDF_FAILURE;
449d6aed566Sopenharmony_ci    }
450d6aed566Sopenharmony_ci    host->method = &g_uartHostMethod;
451d6aed566Sopenharmony_ci    return ret;
452d6aed566Sopenharmony_ci}
453d6aed566Sopenharmony_ci
454d6aed566Sopenharmony_civoid HdfUartDeviceRelease(struct HdfDeviceObject *device)
455d6aed566Sopenharmony_ci{
456d6aed566Sopenharmony_ci    struct UartHost *host = NULL;
457d6aed566Sopenharmony_ci
458d6aed566Sopenharmony_ci    HDF_LOGI("%s: entry", __func__);
459d6aed566Sopenharmony_ci    if (device == NULL) {
460d6aed566Sopenharmony_ci        HDF_LOGE("%s: device is null", __func__);
461d6aed566Sopenharmony_ci        return;
462d6aed566Sopenharmony_ci    }
463d6aed566Sopenharmony_ci    host = UartHostFromDevice(device);
464d6aed566Sopenharmony_ci    if (host == NULL) {
465d6aed566Sopenharmony_ci        HDF_LOGE("%s: host is null", __func__);
466d6aed566Sopenharmony_ci        return;
467d6aed566Sopenharmony_ci    }
468d6aed566Sopenharmony_ci    if (host->priv != NULL) {
469d6aed566Sopenharmony_ci        Hi35xxDetach(host);
470d6aed566Sopenharmony_ci    }
471d6aed566Sopenharmony_ci    UartHostDestroy(host);
472d6aed566Sopenharmony_ci}
473d6aed566Sopenharmony_ci
474d6aed566Sopenharmony_cistruct HdfDriverEntry g_hdfUartDevice = {
475d6aed566Sopenharmony_ci    .moduleVersion = 1,
476d6aed566Sopenharmony_ci    .moduleName = "HDF_PLATFORM_UART",
477d6aed566Sopenharmony_ci    .Bind = HdfUartDeviceBind,
478d6aed566Sopenharmony_ci    .Init = HdfUartDeviceInit,
479d6aed566Sopenharmony_ci    .Release = HdfUartDeviceRelease,
480d6aed566Sopenharmony_ci};
481d6aed566Sopenharmony_ci
482d6aed566Sopenharmony_ciHDF_INIT(g_hdfUartDevice);
483