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", &regPbase, 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