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", ®Pbase, 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