• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "device_resource_if.h"
10 #include "buf_fifo.h"
11 #include "hdf_device_desc.h"
12 #include "hdf_log.h"
13 #include "hisoc/uart.h"
14 #include "osal_io.h"
15 #include "osal_mem.h"
16 #include "uart_core.h"
17 #include "uart_dev_sample.h"
18 #include "uart_dispatch_sample.h"
19 #include "uart_pl011_sample.h"
20 
21 #define HDF_LOG_TAG uart_sample
22 #define UART_RX_FIFO_SIZE 128
23 
24 static uint8_t g_fifoBuffer[UART_RX_FIFO_SIZE] = {0};
25 
26 /* HdfDriverEntry method definitions */
27 static int32_t SampleUartDriverBind(struct HdfDeviceObject *device);
28 static int32_t SampleUartDriverInit(struct HdfDeviceObject *device);
29 static void SampleUartDriverRelease(struct HdfDeviceObject *device);
30 
31 /* HdfDriverEntry definitions */
32 struct HdfDriverEntry g_sampleUartDriverEntry = {
33     .moduleVersion = 1,
34     .moduleName = "UART_SAMPLE",
35     .Bind = SampleUartDriverBind,
36     .Init = SampleUartDriverInit,
37     .Release = SampleUartDriverRelease,
38 };
39 
40 // Initialize HdfDriverEntry
41 HDF_INIT(g_sampleUartDriverEntry);
42 
43 /* UartHostMethod method definitions */
44 static int32_t SampleUartHostInit(struct UartHost *host);
45 static int32_t SampleUartHostDeinit(struct UartHost *host);
46 static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size);
47 static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate);
48 static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate);
49 
50 /* UartHostMethod definitions */
51 struct UartHostMethod g_sampleUartHostMethod = {
52     .Init = SampleUartHostInit,
53     .Deinit = SampleUartHostDeinit,
54     .Read = NULL,
55     .Write = SampleUartHostWrite,
56     .SetBaud = SampleUartHostSetBaud,
57     .GetBaud = SampleUartHostGetBaud,
58     .SetAttribute = NULL,
59     .GetAttribute = NULL,
60     .SetTransMode = NULL,
61 };
62 
63 /* UartHostMethod implementations */
SampleUartHostInit(struct UartHost * host)64 static int32_t SampleUartHostInit(struct UartHost *host)
65 {
66     HDF_LOGD("%s: Enter", __func__);
67     if (host == NULL) {
68         HDF_LOGW("%s: invalid parameter", __func__);
69         return HDF_ERR_INVALID_PARAM;
70     }
71     return HDF_SUCCESS;
72 }
73 
SampleUartHostDeinit(struct UartHost * host)74 static int32_t SampleUartHostDeinit(struct UartHost *host)
75 {
76     HDF_LOGD("%s: Enter", __func__);
77     if (host == NULL) {
78         HDF_LOGW("%s: invalid parameter", __func__);
79         return HDF_ERR_INVALID_PARAM;
80     }
81     return HDF_SUCCESS;
82 }
83 
SampleUartHostWrite(struct UartHost * host,uint8_t * data,uint32_t size)84 static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size)
85 {
86     uint32_t idx;
87     struct UartRegisterMap *regMap = NULL;
88     struct UartDevice *device = NULL;
89     HDF_LOGD("%s: Enter", __func__);
90 
91     if (host == NULL || data == NULL || size == 0) {
92         HDF_LOGW("%s: invalid parameter", __func__);
93         return HDF_ERR_INVALID_PARAM;
94     }
95     device = (struct UartDevice *)host->priv;
96     if (device == NULL) {
97         HDF_LOGW("%s: device is NULL", __func__);
98         return HDF_ERR_INVALID_PARAM;
99     }
100     regMap = (struct UartRegisterMap *)device->resource.physBase;
101     for (idx = 0; idx < size; idx++) {
102         UartPl011Write(regMap, data[idx]);
103     }
104     return HDF_SUCCESS;
105 }
106 
SampleUartHostSetBaud(struct UartHost * host,uint32_t baudRate)107 static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate)
108 {
109     struct UartDevice *device = NULL;
110     struct UartRegisterMap *regMap = NULL;
111     UartPl011Error err;
112     HDF_LOGD("%s: Enter", __func__);
113 
114     if (host == NULL) {
115         HDF_LOGW("%s: invalid parameter", __func__);
116         return HDF_ERR_INVALID_PARAM;
117     }
118     device = (struct UartDevice *)host->priv;
119     if (device == NULL) {
120         HDF_LOGW("%s: device is NULL", __func__);
121         return HDF_ERR_INVALID_PARAM;
122     }
123     regMap = (struct UartRegisterMap *)device->resource.physBase;
124     if (device->state != UART_DEVICE_INITIALIZED) {
125         return UART_PL011_ERR_NOT_INIT;
126     }
127     if (baudRate == 0) {
128         return UART_PL011_ERR_INVALID_BAUD;
129     }
130     err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate);
131     if (err == UART_PL011_ERR_NONE) {
132         device->baudrate = baudRate;
133     }
134     return err;
135 }
136 
SampleUartHostGetBaud(struct UartHost * host,uint32_t * baudRate)137 static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate)
138 {
139     struct UartDevice *device = NULL;
140     HDF_LOGD("%s: Enter", __func__);
141 
142     if (host == NULL) {
143         HDF_LOGW("%s: invalid parameter", __func__);
144         return HDF_ERR_INVALID_PARAM;
145     }
146     device = (struct UartDevice *)host->priv;
147     if (device == NULL) {
148         HDF_LOGW("%s: device is NULL", __func__);
149         return HDF_ERR_INVALID_PARAM;
150     }
151     *baudRate = device->baudrate;
152     return HDF_SUCCESS;
153 }
154 
InitUartDevice(struct UartDevice * device)155 static int InitUartDevice(struct UartDevice *device)
156 {
157     UartPl011Error err;
158     struct UartResource *resource = &device->resource;
159     struct UartRegisterMap *regMap = (struct UartRegisterMap *)resource->physBase;
160     if ((resource->uartClk == 0) || (resource->baudrate == 0)) {
161         return HDF_ERR_INVALID_PARAM;
162     }
163     /* Updating the system clock */
164     device->uartClk = resource->uartClk;
165     uart_clk_cfg(0, true);
166     /* clear and reset registers. */
167     UartPl011ResetRegisters(regMap);
168     /* set baud rate as device config */
169     err = UartPl011SetBaudrate(regMap, resource->uartClk, resource->baudrate);
170     if (err != UART_PL011_ERR_NONE) {
171         return HDF_FAILURE;
172     }
173     /* set the data format as device config */
174     UartPl011SetDataFormat(regMap, resource->wlen, resource->parity, resource->stopBit);
175     /* Enabling the FIFOs */
176     UartPl011EnableFifo(regMap);
177     UartPl011Enable(regMap);
178     BufferFifoInit(&device->rxFifo, g_fifoBuffer, UART_RX_FIFO_SIZE);
179     device->state = UART_DEVICE_INITIALIZED;
180     return HDF_SUCCESS;
181 }
182 
GetUartDeviceResource(struct UartDevice * device,const struct DeviceResourceNode * resourceNode)183 static uint32_t GetUartDeviceResource(
184     struct UartDevice *device, const struct DeviceResourceNode *resourceNode)
185 {
186     struct UartResource *resource = &device->resource;
187     struct DeviceResourceIface *dri = NULL;
188     dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
189     if (dri == NULL || dri->GetUint32 == NULL) {
190         HDF_LOGE("DeviceResourceIface is invalid");
191         return HDF_FAILURE;
192     }
193 
194     if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) {
195         HDF_LOGE("uart config read num fail");
196         return HDF_FAILURE;
197     }
198     if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) {
199         HDF_LOGE("uart config read base fail");
200         return HDF_FAILURE;
201     }
202     resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48);
203     if (resource->physBase == 0) {
204         HDF_LOGE("uart config fail to remap physBase");
205         return HDF_FAILURE;
206     }
207     if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) {
208         HDF_LOGE("uart config read irqNum fail");
209         return HDF_FAILURE;
210     }
211     if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) {
212         HDF_LOGE("uart config read baudrate fail");
213         return HDF_FAILURE;
214     }
215     if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) {
216         HDF_LOGE("uart config read wlen fail");
217         return HDF_FAILURE;
218     }
219     if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) {
220         HDF_LOGE("uart config read parity fail");
221         return HDF_FAILURE;
222     }
223     if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) {
224         HDF_LOGE("uart config read stopBit fail");
225         return HDF_FAILURE;
226     }
227     if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) {
228         HDF_LOGE("uart config read uartClk fail");
229         return HDF_FAILURE;
230     }
231     return HDF_SUCCESS;
232 }
233 
AttachUartDevice(struct UartHost * host,struct HdfDeviceObject * device)234 static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device)
235 {
236     int32_t ret;
237     struct UartDevice *uartDevice = NULL;
238     if (device->property == NULL) {
239         HDF_LOGW("%s: property is NULL", __func__);
240         return HDF_FAILURE;
241     }
242     uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice));
243     if (uartDevice == NULL) {
244         HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__);
245         return HDF_ERR_MALLOC_FAIL;
246     }
247     ret = GetUartDeviceResource(uartDevice, device->property);
248     if (ret != HDF_SUCCESS) {
249         (void)OsalMemFree(uartDevice);
250         return HDF_FAILURE;
251     }
252     host->num = uartDevice->resource.num;
253     host->priv = uartDevice;
254     AddUartDevice(host);
255     return InitUartDevice(uartDevice);
256 }
257 
DeinitUartDevice(struct UartDevice * device)258 static void DeinitUartDevice(struct UartDevice *device)
259 {
260     struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase;
261     /* wait for uart enter idle. */
262     while (UartPl011IsBusy(regMap)) { }
263     UartPl011ResetRegisters(regMap);
264     uart_clk_cfg(0, false);
265     OsalIoUnmap((void *)device->resource.physBase);
266     device->state = UART_DEVICE_UNINITIALIZED;
267 }
268 
DetachUartDevice(struct UartHost * host)269 static void DetachUartDevice(struct UartHost *host)
270 {
271     struct UartDevice *uartDevice = NULL;
272 
273     if (host->priv == NULL) {
274         HDF_LOGW("%s: invalid parameter", __func__);
275         return;
276     }
277     uartDevice = host->priv;
278     DeinitUartDevice(uartDevice);
279     (void)OsalMemFree(uartDevice);
280     host->priv = NULL;
281 }
282 
283 /* HdfDriverEntry implementations */
SampleUartDriverBind(struct HdfDeviceObject * device)284 static int32_t SampleUartDriverBind(struct HdfDeviceObject *device)
285 {
286     struct UartHost *uartHost = NULL;
287     HDF_LOGD("%s: Enter", __func__);
288 
289     if (device == NULL) {
290         return HDF_ERR_INVALID_OBJECT;
291     }
292 
293     uartHost = UartHostCreate(device);
294     if (uartHost == NULL) {
295         HDF_LOGE("%s: UartHostCreate failed", __func__);
296         return HDF_FAILURE;
297     }
298     uartHost->service.Dispatch = SampleDispatch;
299     return HDF_SUCCESS;
300 }
301 
SampleUartDriverInit(struct HdfDeviceObject * device)302 static int32_t SampleUartDriverInit(struct HdfDeviceObject *device)
303 {
304     int32_t ret;
305     struct UartHost *host = NULL;
306     HDF_LOGD("%s: Enter", __func__);
307 
308     if (device == NULL) {
309         HDF_LOGE("%s: device is NULL", __func__);
310         return HDF_ERR_INVALID_OBJECT;
311     }
312     host = UartHostFromDevice(device);
313     if (host == NULL) {
314         HDF_LOGE("%s: host is NULL", __func__);
315         return HDF_FAILURE;
316     }
317     ret = AttachUartDevice(host, device);
318     if (ret != HDF_SUCCESS) {
319         HDF_LOGE("%s: attach error", __func__);
320         return HDF_FAILURE;
321     }
322     host->method = &g_sampleUartHostMethod;
323     return ret;
324 }
325 
SampleUartDriverRelease(struct HdfDeviceObject * device)326 static void SampleUartDriverRelease(struct HdfDeviceObject *device)
327 {
328     struct UartHost *host = NULL;
329     HDF_LOGD("%s: Enter", __func__);
330 
331     if (device == NULL) {
332         HDF_LOGE("%s: device is NULL", __func__);
333         return;
334     }
335     host = UartHostFromDevice(device);
336     if (host == NULL) {
337         HDF_LOGE("%s: host is NULL", __func__);
338         return;
339     }
340     if (host->priv != NULL) {
341         DetachUartDevice(host);
342     }
343     UartHostDestroy(host);
344 }
345