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