11bd4fe43Sopenharmony_ci/* 21bd4fe43Sopenharmony_ci * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 31bd4fe43Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 41bd4fe43Sopenharmony_ci * you may not use this file except in compliance with the License. 51bd4fe43Sopenharmony_ci * You may obtain a copy of the License at 61bd4fe43Sopenharmony_ci * 71bd4fe43Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 81bd4fe43Sopenharmony_ci * 91bd4fe43Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 101bd4fe43Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 111bd4fe43Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121bd4fe43Sopenharmony_ci * See the License for the specific language governing permissions and 131bd4fe43Sopenharmony_ci * limitations under the License. 141bd4fe43Sopenharmony_ci */ 151bd4fe43Sopenharmony_ci 161bd4fe43Sopenharmony_ci#include "los_event.h" 171bd4fe43Sopenharmony_ci#include "device_resource_if.h" 181bd4fe43Sopenharmony_ci#include "hdf_base.h" 191bd4fe43Sopenharmony_ci#include "hdf_log.h" 201bd4fe43Sopenharmony_ci#include "osal_io.h" 211bd4fe43Sopenharmony_ci#include "osal_mem.h" 221bd4fe43Sopenharmony_ci#include "osal_time.h" 231bd4fe43Sopenharmony_ci#include "platform_dumper.h" 241bd4fe43Sopenharmony_ci#include "uart_core.h" 251bd4fe43Sopenharmony_ci#include "uart_dev.h" 261bd4fe43Sopenharmony_ci#include "uart_if.h" 271bd4fe43Sopenharmony_ci#include "uart_pl011.h" 281bd4fe43Sopenharmony_ci 291bd4fe43Sopenharmony_ci#define HDF_LOG_TAG uart_hi35xx 301bd4fe43Sopenharmony_ci 311bd4fe43Sopenharmony_ci#define UART_DUMPER_NAME_PREFIX "uart_dumper_" 321bd4fe43Sopenharmony_ci#define UART_DUMPER_NAME_LEN 64 331bd4fe43Sopenharmony_ci 341bd4fe43Sopenharmony_cistatic void UartDumperDump(struct UartPl011Port *port) 351bd4fe43Sopenharmony_ci{ 361bd4fe43Sopenharmony_ci int32_t ret; 371bd4fe43Sopenharmony_ci struct PlatformDumperData datas[] = { 381bd4fe43Sopenharmony_ci {"UART_DR", PLATFORM_DUMPER_REGISTERL, (void *)port->physBase}, 391bd4fe43Sopenharmony_ci {"UART_RSR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_RSR)}, 401bd4fe43Sopenharmony_ci {"UART_FR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_FR)}, 411bd4fe43Sopenharmony_ci {"UART_IBRD", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IBRD)}, 421bd4fe43Sopenharmony_ci {"UART_FBRD", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_FBRD)}, 431bd4fe43Sopenharmony_ci {"UART_LCR_H", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_LCR_H)}, 441bd4fe43Sopenharmony_ci {"UART_CR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_CR)}, 451bd4fe43Sopenharmony_ci {"UART_IFLS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IFLS)}, 461bd4fe43Sopenharmony_ci {"UART_IMSC", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IMSC)}, 471bd4fe43Sopenharmony_ci {"UART_RIS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_RIS)}, 481bd4fe43Sopenharmony_ci {"UART_MIS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_MIS)}, 491bd4fe43Sopenharmony_ci {"UART_ICR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_ICR)}, 501bd4fe43Sopenharmony_ci {"UART_DMACR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_DMACR)}, 511bd4fe43Sopenharmony_ci }; 521bd4fe43Sopenharmony_ci if (port->dumper == NULL) { 531bd4fe43Sopenharmony_ci HDF_LOGE("%s: uart dumper is NULL", __func__); 541bd4fe43Sopenharmony_ci return; 551bd4fe43Sopenharmony_ci } 561bd4fe43Sopenharmony_ci ret = PlatformDumperAddDatas(port->dumper, datas, sizeof(datas) / sizeof(struct PlatformDumperData)); 571bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 581bd4fe43Sopenharmony_ci return; 591bd4fe43Sopenharmony_ci } 601bd4fe43Sopenharmony_ci (void)PlatformDumperDump(port->dumper); 611bd4fe43Sopenharmony_ci (void)PlatformDumperClearDatas(port->dumper); 621bd4fe43Sopenharmony_ci} 631bd4fe43Sopenharmony_ci 641bd4fe43Sopenharmony_cistatic int32_t UartDumperCreate(struct UartPl011Port *port) 651bd4fe43Sopenharmony_ci{ 661bd4fe43Sopenharmony_ci struct PlatformDumper *dumper = NULL; 671bd4fe43Sopenharmony_ci char *name = NULL; 681bd4fe43Sopenharmony_ci 691bd4fe43Sopenharmony_ci name = (char *)OsalMemCalloc(UART_DUMPER_NAME_LEN); 701bd4fe43Sopenharmony_ci if (name == NULL) { 711bd4fe43Sopenharmony_ci HDF_LOGE("%s: alloc name fail", __func__); 721bd4fe43Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 731bd4fe43Sopenharmony_ci } 741bd4fe43Sopenharmony_ci 751bd4fe43Sopenharmony_ci if (snprintf_s(name, UART_DUMPER_NAME_LEN, UART_DUMPER_NAME_LEN - 1, "%s%d", 761bd4fe43Sopenharmony_ci UART_DUMPER_NAME_PREFIX, port->udd->num) < 0) { 771bd4fe43Sopenharmony_ci HDF_LOGE("%s: snprintf_s name fail!", __func__); 781bd4fe43Sopenharmony_ci OsalMemFree(name); 791bd4fe43Sopenharmony_ci return HDF_ERR_IO; 801bd4fe43Sopenharmony_ci } 811bd4fe43Sopenharmony_ci 821bd4fe43Sopenharmony_ci dumper = PlatformDumperCreate(name); 831bd4fe43Sopenharmony_ci if (dumper == NULL) { 841bd4fe43Sopenharmony_ci HDF_LOGE("%s: get dumper for %s fail!", __func__, name); 851bd4fe43Sopenharmony_ci OsalMemFree(name); 861bd4fe43Sopenharmony_ci return HDF_ERR_IO; 871bd4fe43Sopenharmony_ci } 881bd4fe43Sopenharmony_ci 891bd4fe43Sopenharmony_ci port->dumper = dumper; 901bd4fe43Sopenharmony_ci port->dumperName = name; 911bd4fe43Sopenharmony_ci 921bd4fe43Sopenharmony_ci return HDF_SUCCESS; 931bd4fe43Sopenharmony_ci} 941bd4fe43Sopenharmony_ci 951bd4fe43Sopenharmony_cistatic inline void UartDumperDestroy(struct UartPl011Port *port) 961bd4fe43Sopenharmony_ci{ 971bd4fe43Sopenharmony_ci PlatformDumperDestroy(port->dumper); 981bd4fe43Sopenharmony_ci OsalMemFree(port->dumperName); 991bd4fe43Sopenharmony_ci} 1001bd4fe43Sopenharmony_ci 1011bd4fe43Sopenharmony_cistatic int32_t Hi35xxRead(struct UartHost *host, uint8_t *data, uint32_t size) 1021bd4fe43Sopenharmony_ci{ 1031bd4fe43Sopenharmony_ci int32_t ret; 1041bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 1051bd4fe43Sopenharmony_ci 1061bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 1071bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 1081bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1091bd4fe43Sopenharmony_ci } 1101bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 1111bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE) { 1121bd4fe43Sopenharmony_ci return HDF_FAILURE; 1131bd4fe43Sopenharmony_ci } 1141bd4fe43Sopenharmony_ci if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) { 1151bd4fe43Sopenharmony_ci (void)LOS_EventRead(&udd->wait.stEvent, 0x1, LOS_WAITMODE_OR, LOS_WAIT_FOREVER); 1161bd4fe43Sopenharmony_ci } 1171bd4fe43Sopenharmony_ci ret = Pl011Read(udd, (char *)data, size); 1181bd4fe43Sopenharmony_ci if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) { 1191bd4fe43Sopenharmony_ci (void)LOS_EventClear(&udd->wait.stEvent, ~(0x1)); 1201bd4fe43Sopenharmony_ci } 1211bd4fe43Sopenharmony_ci return ret; 1221bd4fe43Sopenharmony_ci} 1231bd4fe43Sopenharmony_ci 1241bd4fe43Sopenharmony_cistatic int32_t Hi35xxWrite(struct UartHost *host, uint8_t *data, uint32_t size) 1251bd4fe43Sopenharmony_ci{ 1261bd4fe43Sopenharmony_ci int32_t ret; 1271bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 1281bd4fe43Sopenharmony_ci 1291bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 1301bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 1311bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1321bd4fe43Sopenharmony_ci } 1331bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 1341bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE) { 1351bd4fe43Sopenharmony_ci return HDF_FAILURE; 1361bd4fe43Sopenharmony_ci } 1371bd4fe43Sopenharmony_ci if (udd->ops->StartTx != NULL) { 1381bd4fe43Sopenharmony_ci ret = udd->ops->StartTx(udd, (char *)data, size); 1391bd4fe43Sopenharmony_ci } else { 1401bd4fe43Sopenharmony_ci ret = HDF_ERR_NOT_SUPPORT; 1411bd4fe43Sopenharmony_ci HDF_LOGE("%s: not support", __func__); 1421bd4fe43Sopenharmony_ci } 1431bd4fe43Sopenharmony_ci return ret; 1441bd4fe43Sopenharmony_ci} 1451bd4fe43Sopenharmony_ci 1461bd4fe43Sopenharmony_cistatic int32_t Hi35xxGetBaud(struct UartHost *host, uint32_t *baudRate) 1471bd4fe43Sopenharmony_ci{ 1481bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 1491bd4fe43Sopenharmony_ci 1501bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL || baudRate == NULL) { 1511bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 1521bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1531bd4fe43Sopenharmony_ci } 1541bd4fe43Sopenharmony_ci 1551bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 1561bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE) { 1571bd4fe43Sopenharmony_ci return HDF_FAILURE; 1581bd4fe43Sopenharmony_ci } 1591bd4fe43Sopenharmony_ci *baudRate = udd->baudrate; 1601bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1611bd4fe43Sopenharmony_ci} 1621bd4fe43Sopenharmony_ci 1631bd4fe43Sopenharmony_cistatic int32_t Hi35xxSetBaud(struct UartHost *host, uint32_t baudRate) 1641bd4fe43Sopenharmony_ci{ 1651bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 1661bd4fe43Sopenharmony_ci struct UartPl011Port *port = NULL; 1671bd4fe43Sopenharmony_ci 1681bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 1691bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 1701bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1711bd4fe43Sopenharmony_ci } 1721bd4fe43Sopenharmony_ci 1731bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 1741bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE || udd->private == NULL) { 1751bd4fe43Sopenharmony_ci return HDF_FAILURE; 1761bd4fe43Sopenharmony_ci } 1771bd4fe43Sopenharmony_ci port = udd->private; 1781bd4fe43Sopenharmony_ci 1791bd4fe43Sopenharmony_ci if ((baudRate > 0) && (baudRate <= CONFIG_MAX_BAUDRATE)) { 1801bd4fe43Sopenharmony_ci udd->baudrate = baudRate; 1811bd4fe43Sopenharmony_ci if (udd->ops->Config == NULL) { 1821bd4fe43Sopenharmony_ci HDF_LOGE("%s: not support", __func__); 1831bd4fe43Sopenharmony_ci return HDF_ERR_NOT_SUPPORT; 1841bd4fe43Sopenharmony_ci } 1851bd4fe43Sopenharmony_ci if (udd->ops->Config(udd) != HDF_SUCCESS) { 1861bd4fe43Sopenharmony_ci HDF_LOGE("%s: config baudrate %u failed", __func__, baudRate); 1871bd4fe43Sopenharmony_ci UartDumperDump(port); 1881bd4fe43Sopenharmony_ci return HDF_FAILURE; 1891bd4fe43Sopenharmony_ci } 1901bd4fe43Sopenharmony_ci } else { 1911bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid baudrate, which is:%u", __func__, baudRate); 1921bd4fe43Sopenharmony_ci return HDF_FAILURE; 1931bd4fe43Sopenharmony_ci } 1941bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1951bd4fe43Sopenharmony_ci} 1961bd4fe43Sopenharmony_ci 1971bd4fe43Sopenharmony_cistatic int32_t Hi35xxGetAttribute(struct UartHost *host, struct UartAttribute *attribute) 1981bd4fe43Sopenharmony_ci{ 1991bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 2001bd4fe43Sopenharmony_ci 2011bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL || attribute == NULL) { 2021bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 2031bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 2041bd4fe43Sopenharmony_ci } 2051bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 2061bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE) { 2071bd4fe43Sopenharmony_ci return HDF_FAILURE; 2081bd4fe43Sopenharmony_ci } 2091bd4fe43Sopenharmony_ci attribute->cts = udd->attr.cts; 2101bd4fe43Sopenharmony_ci attribute->dataBits = udd->attr.dataBits; 2111bd4fe43Sopenharmony_ci attribute->fifoRxEn = udd->attr.fifoRxEn; 2121bd4fe43Sopenharmony_ci attribute->fifoTxEn = udd->attr.fifoTxEn; 2131bd4fe43Sopenharmony_ci attribute->parity = udd->attr.parity; 2141bd4fe43Sopenharmony_ci attribute->rts = udd->attr.rts; 2151bd4fe43Sopenharmony_ci attribute->stopBits = udd->attr.stopBits; 2161bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2171bd4fe43Sopenharmony_ci} 2181bd4fe43Sopenharmony_ci 2191bd4fe43Sopenharmony_cistatic int32_t Hi35xxSetAttribute(struct UartHost *host, struct UartAttribute *attribute) 2201bd4fe43Sopenharmony_ci{ 2211bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 2221bd4fe43Sopenharmony_ci struct UartPl011Port *port = NULL; 2231bd4fe43Sopenharmony_ci 2241bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL || attribute == NULL) { 2251bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 2261bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 2271bd4fe43Sopenharmony_ci } 2281bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 2291bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE || udd->private == NULL) { 2301bd4fe43Sopenharmony_ci return HDF_FAILURE; 2311bd4fe43Sopenharmony_ci } 2321bd4fe43Sopenharmony_ci 2331bd4fe43Sopenharmony_ci port = udd->private; 2341bd4fe43Sopenharmony_ci udd->attr.cts = attribute->cts; 2351bd4fe43Sopenharmony_ci udd->attr.dataBits = attribute->dataBits; 2361bd4fe43Sopenharmony_ci udd->attr.fifoRxEn = attribute->fifoRxEn; 2371bd4fe43Sopenharmony_ci udd->attr.fifoTxEn = attribute->fifoTxEn; 2381bd4fe43Sopenharmony_ci udd->attr.parity = attribute->parity; 2391bd4fe43Sopenharmony_ci udd->attr.rts = attribute->rts; 2401bd4fe43Sopenharmony_ci udd->attr.stopBits = attribute->stopBits; 2411bd4fe43Sopenharmony_ci if (udd->ops->Config == NULL) { 2421bd4fe43Sopenharmony_ci HDF_LOGE("%s: not support", __func__); 2431bd4fe43Sopenharmony_ci return HDF_ERR_NOT_SUPPORT; 2441bd4fe43Sopenharmony_ci } 2451bd4fe43Sopenharmony_ci if (udd->ops->Config(udd) != HDF_SUCCESS) { 2461bd4fe43Sopenharmony_ci HDF_LOGE("%s: config failed", __func__); 2471bd4fe43Sopenharmony_ci UartDumperDump(port); 2481bd4fe43Sopenharmony_ci return HDF_FAILURE; 2491bd4fe43Sopenharmony_ci } 2501bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2511bd4fe43Sopenharmony_ci} 2521bd4fe43Sopenharmony_ci 2531bd4fe43Sopenharmony_cistatic int32_t Hi35xxSetTransMode(struct UartHost *host, enum UartTransMode mode) 2541bd4fe43Sopenharmony_ci{ 2551bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 2561bd4fe43Sopenharmony_ci 2571bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 2581bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 2591bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 2601bd4fe43Sopenharmony_ci } 2611bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 2621bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_USEABLE) { 2631bd4fe43Sopenharmony_ci return HDF_FAILURE; 2641bd4fe43Sopenharmony_ci } 2651bd4fe43Sopenharmony_ci if (mode == UART_MODE_RD_BLOCK) { 2661bd4fe43Sopenharmony_ci udd->flags |= UART_FLG_RD_BLOCK; 2671bd4fe43Sopenharmony_ci } else if (mode == UART_MODE_RD_NONBLOCK) { 2681bd4fe43Sopenharmony_ci udd->flags &= ~UART_FLG_RD_BLOCK; 2691bd4fe43Sopenharmony_ci (void)LOS_EventWrite(&udd->wait.stEvent, 0x1); 2701bd4fe43Sopenharmony_ci } 2711bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2721bd4fe43Sopenharmony_ci} 2731bd4fe43Sopenharmony_ci 2741bd4fe43Sopenharmony_cistatic int32_t Hi35xxInit(struct UartHost *host) 2751bd4fe43Sopenharmony_ci{ 2761bd4fe43Sopenharmony_ci int32_t ret = 0; 2771bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 2781bd4fe43Sopenharmony_ci struct UartPl011Port *port = NULL; 2791bd4fe43Sopenharmony_ci struct wait_queue_head *wait = NULL; 2801bd4fe43Sopenharmony_ci 2811bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 2821bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 2831bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 2841bd4fe43Sopenharmony_ci } 2851bd4fe43Sopenharmony_ci 2861bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 2871bd4fe43Sopenharmony_ci if (udd->private == NULL) { 2881bd4fe43Sopenharmony_ci HDF_LOGE("%s:udd private is NULL", __func__); 2891bd4fe43Sopenharmony_ci return HDF_FAILURE; 2901bd4fe43Sopenharmony_ci } 2911bd4fe43Sopenharmony_ci port = udd->private; 2921bd4fe43Sopenharmony_ci 2931bd4fe43Sopenharmony_ci wait = &udd->wait; 2941bd4fe43Sopenharmony_ci if (udd->state == UART_STATE_NOT_OPENED) { 2951bd4fe43Sopenharmony_ci udd->state = UART_STATE_OPENING; 2961bd4fe43Sopenharmony_ci (void)LOS_EventInit(&wait->stEvent); 2971bd4fe43Sopenharmony_ci spin_lock_init(&wait->lock); 2981bd4fe43Sopenharmony_ci LOS_ListInit(&wait->poll_queue); 2991bd4fe43Sopenharmony_ci udd->rxTransfer = (struct UartTransfer *)OsalMemCalloc(sizeof(struct UartTransfer)); 3001bd4fe43Sopenharmony_ci if (udd->rxTransfer == NULL) { 3011bd4fe43Sopenharmony_ci HDF_LOGE("%s: alloc transfer failed", __func__); 3021bd4fe43Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 3031bd4fe43Sopenharmony_ci } 3041bd4fe43Sopenharmony_ci if (udd->ops->StartUp == NULL) { 3051bd4fe43Sopenharmony_ci HDF_LOGE("%s: not support", __func__); 3061bd4fe43Sopenharmony_ci ret = HDF_ERR_NOT_SUPPORT; 3071bd4fe43Sopenharmony_ci goto FREE_TRANSFER; 3081bd4fe43Sopenharmony_ci } 3091bd4fe43Sopenharmony_ci if (udd->ops->StartUp(udd) != HDF_SUCCESS) { 3101bd4fe43Sopenharmony_ci HDF_LOGE("%s: StartUp failed", __func__); 3111bd4fe43Sopenharmony_ci UartDumperDump(port); 3121bd4fe43Sopenharmony_ci ret = HDF_FAILURE; 3131bd4fe43Sopenharmony_ci goto FREE_TRANSFER; 3141bd4fe43Sopenharmony_ci } 3151bd4fe43Sopenharmony_ci } 3161bd4fe43Sopenharmony_ci udd->state = UART_STATE_USEABLE; 3171bd4fe43Sopenharmony_ci udd->count++; 3181bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3191bd4fe43Sopenharmony_ci 3201bd4fe43Sopenharmony_ciFREE_TRANSFER: 3211bd4fe43Sopenharmony_ci OsalMemFree(udd->rxTransfer); 3221bd4fe43Sopenharmony_ci udd->rxTransfer = NULL; 3231bd4fe43Sopenharmony_ci return ret; 3241bd4fe43Sopenharmony_ci} 3251bd4fe43Sopenharmony_ci 3261bd4fe43Sopenharmony_cistatic int32_t Hi35xxDeinit(struct UartHost *host) 3271bd4fe43Sopenharmony_ci{ 3281bd4fe43Sopenharmony_ci struct wait_queue_head *wait = NULL; 3291bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 3301bd4fe43Sopenharmony_ci 3311bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 3321bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 3331bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 3341bd4fe43Sopenharmony_ci } 3351bd4fe43Sopenharmony_ci 3361bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 3371bd4fe43Sopenharmony_ci if ((--udd->count) != 0) { 3381bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3391bd4fe43Sopenharmony_ci } 3401bd4fe43Sopenharmony_ci wait = &udd->wait; 3411bd4fe43Sopenharmony_ci if (udd->flags & UART_FLG_DMA_RX) { 3421bd4fe43Sopenharmony_ci if (udd->ops->DmaShutDown != NULL) { 3431bd4fe43Sopenharmony_ci udd->ops->DmaShutDown(udd, UART_DMA_DIR_RX); 3441bd4fe43Sopenharmony_ci } 3451bd4fe43Sopenharmony_ci } 3461bd4fe43Sopenharmony_ci if (udd->flags & UART_FLG_DMA_TX) { 3471bd4fe43Sopenharmony_ci if (udd->ops->DmaShutDown != NULL) { 3481bd4fe43Sopenharmony_ci udd->ops->DmaShutDown(udd, UART_DMA_DIR_TX); 3491bd4fe43Sopenharmony_ci } 3501bd4fe43Sopenharmony_ci } 3511bd4fe43Sopenharmony_ci LOS_ListDelete(&wait->poll_queue); 3521bd4fe43Sopenharmony_ci LOS_EventDestroy(&wait->stEvent); 3531bd4fe43Sopenharmony_ci if (udd->ops->ShutDown != NULL) { 3541bd4fe43Sopenharmony_ci udd->ops->ShutDown(udd); 3551bd4fe43Sopenharmony_ci } 3561bd4fe43Sopenharmony_ci if (udd->rxTransfer != NULL) { 3571bd4fe43Sopenharmony_ci OsalMemFree(udd->rxTransfer); 3581bd4fe43Sopenharmony_ci udd->rxTransfer = NULL; 3591bd4fe43Sopenharmony_ci } 3601bd4fe43Sopenharmony_ci udd->state = UART_STATE_NOT_OPENED; 3611bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3621bd4fe43Sopenharmony_ci} 3631bd4fe43Sopenharmony_ci 3641bd4fe43Sopenharmony_cistatic int32_t Hi35xxPollEvent(struct UartHost *host, void *filep, void *table) 3651bd4fe43Sopenharmony_ci{ 3661bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 3671bd4fe43Sopenharmony_ci 3681bd4fe43Sopenharmony_ci if (host == NULL || host->priv == NULL) { 3691bd4fe43Sopenharmony_ci HDF_LOGE("%s: host is NULL", __func__); 3701bd4fe43Sopenharmony_ci return HDF_FAILURE; 3711bd4fe43Sopenharmony_ci } 3721bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)host->priv; 3731bd4fe43Sopenharmony_ci if (UART_STATE_USEABLE != udd->state) { 3741bd4fe43Sopenharmony_ci return -EFAULT; 3751bd4fe43Sopenharmony_ci } 3761bd4fe43Sopenharmony_ci 3771bd4fe43Sopenharmony_ci poll_wait((struct file *)filep, &udd->wait, (poll_table *)table); 3781bd4fe43Sopenharmony_ci 3791bd4fe43Sopenharmony_ci if (!PL011UartRxBufEmpty(udd)) { 3801bd4fe43Sopenharmony_ci return POLLIN | POLLRDNORM; 3811bd4fe43Sopenharmony_ci } 3821bd4fe43Sopenharmony_ci return 0; 3831bd4fe43Sopenharmony_ci} 3841bd4fe43Sopenharmony_ci 3851bd4fe43Sopenharmony_cistruct UartHostMethod g_uartHostMethod = { 3861bd4fe43Sopenharmony_ci .Init = Hi35xxInit, 3871bd4fe43Sopenharmony_ci .Deinit = Hi35xxDeinit, 3881bd4fe43Sopenharmony_ci .Read = Hi35xxRead, 3891bd4fe43Sopenharmony_ci .Write = Hi35xxWrite, 3901bd4fe43Sopenharmony_ci .SetBaud = Hi35xxSetBaud, 3911bd4fe43Sopenharmony_ci .GetBaud = Hi35xxGetBaud, 3921bd4fe43Sopenharmony_ci .SetAttribute = Hi35xxSetAttribute, 3931bd4fe43Sopenharmony_ci .GetAttribute = Hi35xxGetAttribute, 3941bd4fe43Sopenharmony_ci .SetTransMode = Hi35xxSetTransMode, 3951bd4fe43Sopenharmony_ci .pollEvent = Hi35xxPollEvent, 3961bd4fe43Sopenharmony_ci}; 3971bd4fe43Sopenharmony_ci 3981bd4fe43Sopenharmony_cistatic int32_t UartGetConfigFromHcs(struct UartPl011Port *port, const struct DeviceResourceNode *node) 3991bd4fe43Sopenharmony_ci{ 4001bd4fe43Sopenharmony_ci uint32_t tmp, regPbase, iomemCount; 4011bd4fe43Sopenharmony_ci struct UartDriverData *udd = port->udd; 4021bd4fe43Sopenharmony_ci struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 4031bd4fe43Sopenharmony_ci if (iface == NULL || iface->GetUint32 == NULL) { 4041bd4fe43Sopenharmony_ci HDF_LOGE("%s: face is invalid", __func__); 4051bd4fe43Sopenharmony_ci return HDF_FAILURE; 4061bd4fe43Sopenharmony_ci } 4071bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) { 4081bd4fe43Sopenharmony_ci HDF_LOGE("%s: read busNum fail", __func__); 4091bd4fe43Sopenharmony_ci return HDF_FAILURE; 4101bd4fe43Sopenharmony_ci } 4111bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "baudrate", &udd->baudrate, 0) != HDF_SUCCESS) { 4121bd4fe43Sopenharmony_ci HDF_LOGE("%s: read numCs fail", __func__); 4131bd4fe43Sopenharmony_ci return HDF_FAILURE; 4141bd4fe43Sopenharmony_ci } 4151bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "fifoRxEn", &tmp, 0) != HDF_SUCCESS) { 4161bd4fe43Sopenharmony_ci HDF_LOGE("%s: read speed fail", __func__); 4171bd4fe43Sopenharmony_ci return HDF_FAILURE; 4181bd4fe43Sopenharmony_ci } 4191bd4fe43Sopenharmony_ci udd->attr.fifoRxEn = tmp; 4201bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "fifoTxEn", &tmp, 0) != HDF_SUCCESS) { 4211bd4fe43Sopenharmony_ci HDF_LOGE("%s: read fifoSize fail", __func__); 4221bd4fe43Sopenharmony_ci return HDF_FAILURE; 4231bd4fe43Sopenharmony_ci } 4241bd4fe43Sopenharmony_ci udd->attr.fifoTxEn = tmp; 4251bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "flags", &udd->flags, 0) != HDF_SUCCESS) { 4261bd4fe43Sopenharmony_ci HDF_LOGE("%s: read clkRate fail", __func__); 4271bd4fe43Sopenharmony_ci return HDF_FAILURE; 4281bd4fe43Sopenharmony_ci } 4291bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "regPbase", ®Pbase, 0) != HDF_SUCCESS) { 4301bd4fe43Sopenharmony_ci HDF_LOGE("%s: read mode fail", __func__); 4311bd4fe43Sopenharmony_ci return HDF_FAILURE; 4321bd4fe43Sopenharmony_ci } 4331bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "iomemCount", &iomemCount, 0) != HDF_SUCCESS) { 4341bd4fe43Sopenharmony_ci HDF_LOGE("%s: read bitsPerWord fail", __func__); 4351bd4fe43Sopenharmony_ci return HDF_FAILURE; 4361bd4fe43Sopenharmony_ci } 4371bd4fe43Sopenharmony_ci port->physBase = (unsigned long)OsalIoRemap(regPbase, iomemCount); 4381bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "interrupt", &port->irqNum, 0) != HDF_SUCCESS) { 4391bd4fe43Sopenharmony_ci HDF_LOGE("%s: read comMode fail", __func__); 4401bd4fe43Sopenharmony_ci return HDF_FAILURE; 4411bd4fe43Sopenharmony_ci } 4421bd4fe43Sopenharmony_ci return 0; 4431bd4fe43Sopenharmony_ci} 4441bd4fe43Sopenharmony_ci 4451bd4fe43Sopenharmony_cistatic int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device) 4461bd4fe43Sopenharmony_ci{ 4471bd4fe43Sopenharmony_ci int32_t ret; 4481bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 4491bd4fe43Sopenharmony_ci struct UartPl011Port *port = NULL; 4501bd4fe43Sopenharmony_ci 4511bd4fe43Sopenharmony_ci if (device->property == NULL) { 4521bd4fe43Sopenharmony_ci HDF_LOGE("%s: property is null", __func__); 4531bd4fe43Sopenharmony_ci return HDF_FAILURE; 4541bd4fe43Sopenharmony_ci } 4551bd4fe43Sopenharmony_ci udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd)); 4561bd4fe43Sopenharmony_ci if (udd == NULL) { 4571bd4fe43Sopenharmony_ci HDF_LOGE("%s: OsalMemCalloc udd error", __func__); 4581bd4fe43Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 4591bd4fe43Sopenharmony_ci } 4601bd4fe43Sopenharmony_ci port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port)); 4611bd4fe43Sopenharmony_ci if (port == NULL) { 4621bd4fe43Sopenharmony_ci HDF_LOGE("%s: OsalMemCalloc port error", __func__); 4631bd4fe43Sopenharmony_ci OsalMemFree(udd); 4641bd4fe43Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 4651bd4fe43Sopenharmony_ci } 4661bd4fe43Sopenharmony_ci udd->ops = Pl011GetOps(); 4671bd4fe43Sopenharmony_ci udd->recv = PL011UartRecvNotify; 4681bd4fe43Sopenharmony_ci udd->count = 0; 4691bd4fe43Sopenharmony_ci port->udd = udd; 4701bd4fe43Sopenharmony_ci ret = UartGetConfigFromHcs(port, device->property); 4711bd4fe43Sopenharmony_ci if (ret != 0 || port->physBase == 0) { 4721bd4fe43Sopenharmony_ci OsalMemFree(port); 4731bd4fe43Sopenharmony_ci OsalMemFree(udd); 4741bd4fe43Sopenharmony_ci return HDF_FAILURE; 4751bd4fe43Sopenharmony_ci } 4761bd4fe43Sopenharmony_ci udd->private = port; 4771bd4fe43Sopenharmony_ci host->priv = udd; 4781bd4fe43Sopenharmony_ci host->num = udd->num; 4791bd4fe43Sopenharmony_ci UartAddDev(host); 4801bd4fe43Sopenharmony_ci ret = UartDumperCreate(port); 4811bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4821bd4fe43Sopenharmony_ci HDF_LOGE("%s: create dumper failed:%d", __func__, ret); 4831bd4fe43Sopenharmony_ci OsalMemFree(port); 4841bd4fe43Sopenharmony_ci OsalMemFree(udd); 4851bd4fe43Sopenharmony_ci return ret; 4861bd4fe43Sopenharmony_ci } 4871bd4fe43Sopenharmony_ci UartDumperDump(port); 4881bd4fe43Sopenharmony_ci return HDF_SUCCESS; 4891bd4fe43Sopenharmony_ci} 4901bd4fe43Sopenharmony_ci 4911bd4fe43Sopenharmony_cistatic void Hi35xxDetach(struct UartHost *host) 4921bd4fe43Sopenharmony_ci{ 4931bd4fe43Sopenharmony_ci struct UartDriverData *udd = NULL; 4941bd4fe43Sopenharmony_ci struct UartPl011Port *port = NULL; 4951bd4fe43Sopenharmony_ci 4961bd4fe43Sopenharmony_ci if (host->priv == NULL) { 4971bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid parameter", __func__); 4981bd4fe43Sopenharmony_ci return; 4991bd4fe43Sopenharmony_ci } 5001bd4fe43Sopenharmony_ci udd = host->priv; 5011bd4fe43Sopenharmony_ci if (udd->state != UART_STATE_NOT_OPENED) { 5021bd4fe43Sopenharmony_ci HDF_LOGE("%s: uart driver data state invalid", __func__); 5031bd4fe43Sopenharmony_ci return; 5041bd4fe43Sopenharmony_ci } 5051bd4fe43Sopenharmony_ci UartRemoveDev(host); 5061bd4fe43Sopenharmony_ci port = udd->private; 5071bd4fe43Sopenharmony_ci if (port != NULL) { 5081bd4fe43Sopenharmony_ci UartDumperDestroy(port); 5091bd4fe43Sopenharmony_ci if (port->physBase != 0) { 5101bd4fe43Sopenharmony_ci OsalIoUnmap((void *)port->physBase); 5111bd4fe43Sopenharmony_ci } 5121bd4fe43Sopenharmony_ci OsalMemFree(port); 5131bd4fe43Sopenharmony_ci udd->private = NULL; 5141bd4fe43Sopenharmony_ci } 5151bd4fe43Sopenharmony_ci OsalMemFree(udd); 5161bd4fe43Sopenharmony_ci host->priv = NULL; 5171bd4fe43Sopenharmony_ci} 5181bd4fe43Sopenharmony_ci 5191bd4fe43Sopenharmony_cistatic int32_t HdfUartDeviceBind(struct HdfDeviceObject *device) 5201bd4fe43Sopenharmony_ci{ 5211bd4fe43Sopenharmony_ci HDF_LOGI("%s: entry", __func__); 5221bd4fe43Sopenharmony_ci if (device == NULL) { 5231bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 5241bd4fe43Sopenharmony_ci } 5251bd4fe43Sopenharmony_ci return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS; 5261bd4fe43Sopenharmony_ci} 5271bd4fe43Sopenharmony_ci 5281bd4fe43Sopenharmony_ciint32_t HdfUartDeviceInit(struct HdfDeviceObject *device) 5291bd4fe43Sopenharmony_ci{ 5301bd4fe43Sopenharmony_ci int32_t ret; 5311bd4fe43Sopenharmony_ci struct UartHost *host = NULL; 5321bd4fe43Sopenharmony_ci 5331bd4fe43Sopenharmony_ci if (device == NULL) { 5341bd4fe43Sopenharmony_ci HDF_LOGE("%s: device is null", __func__); 5351bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 5361bd4fe43Sopenharmony_ci } 5371bd4fe43Sopenharmony_ci host = UartHostFromDevice(device); 5381bd4fe43Sopenharmony_ci if (host == NULL) { 5391bd4fe43Sopenharmony_ci HDF_LOGE("%s: host is null", __func__); 5401bd4fe43Sopenharmony_ci return HDF_FAILURE; 5411bd4fe43Sopenharmony_ci } 5421bd4fe43Sopenharmony_ci ret = Hi35xxAttach(host, device); 5431bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 5441bd4fe43Sopenharmony_ci HDF_LOGE("%s: attach error", __func__); 5451bd4fe43Sopenharmony_ci return HDF_FAILURE; 5461bd4fe43Sopenharmony_ci } 5471bd4fe43Sopenharmony_ci host->method = &g_uartHostMethod; 5481bd4fe43Sopenharmony_ci HDF_LOGI("%s: uart device init success.", __func__); 5491bd4fe43Sopenharmony_ci return ret; 5501bd4fe43Sopenharmony_ci} 5511bd4fe43Sopenharmony_ci 5521bd4fe43Sopenharmony_civoid HdfUartDeviceRelease(struct HdfDeviceObject *device) 5531bd4fe43Sopenharmony_ci{ 5541bd4fe43Sopenharmony_ci struct UartHost *host = NULL; 5551bd4fe43Sopenharmony_ci 5561bd4fe43Sopenharmony_ci HDF_LOGI("%s: entry", __func__); 5571bd4fe43Sopenharmony_ci if (device == NULL) { 5581bd4fe43Sopenharmony_ci HDF_LOGE("%s: device is null", __func__); 5591bd4fe43Sopenharmony_ci return; 5601bd4fe43Sopenharmony_ci } 5611bd4fe43Sopenharmony_ci host = UartHostFromDevice(device); 5621bd4fe43Sopenharmony_ci if (host == NULL) { 5631bd4fe43Sopenharmony_ci HDF_LOGE("%s: host is null", __func__); 5641bd4fe43Sopenharmony_ci return; 5651bd4fe43Sopenharmony_ci } 5661bd4fe43Sopenharmony_ci if (host->priv != NULL) { 5671bd4fe43Sopenharmony_ci Hi35xxDetach(host); 5681bd4fe43Sopenharmony_ci } 5691bd4fe43Sopenharmony_ci UartHostDestroy(host); 5701bd4fe43Sopenharmony_ci} 5711bd4fe43Sopenharmony_ci 5721bd4fe43Sopenharmony_cistruct HdfDriverEntry g_hdfUartDevice = { 5731bd4fe43Sopenharmony_ci .moduleVersion = 1, 5741bd4fe43Sopenharmony_ci .moduleName = "HDF_PLATFORM_UART", 5751bd4fe43Sopenharmony_ci .Bind = HdfUartDeviceBind, 5761bd4fe43Sopenharmony_ci .Init = HdfUartDeviceInit, 5771bd4fe43Sopenharmony_ci .Release = HdfUartDeviceRelease, 5781bd4fe43Sopenharmony_ci}; 5791bd4fe43Sopenharmony_ci 5801bd4fe43Sopenharmony_ciHDF_INIT(g_hdfUartDevice); 581