• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2023 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 
19 #include <string.h>
20 #include <B91/dma.h>
21 #include "hdf_device_desc.h"
22 #include "device_resource_if.h"
23 #include "hdf_log.h"
24 #include "uart/uart_core.h"
25 #include "osal_mem.h"
26 #include "uart_tlsr9518.h"
27 #include "hdf_log_adapter_debug.h" // workaround for log print
28 
29 #define HDF_LOG_TAG uart_telink
30 
31 static int32_t get_config_from_hcs(uart_port_t *port, const struct DeviceResourceNode *node);
32 
33 static int32_t UartHostDevInit(struct UartHost *host);
34 static int32_t UartHostDevDeinit(struct UartHost *host);
35 static int32_t UartHostDevRead(struct UartHost *host, uint8_t *data, uint32_t size);
36 static int32_t UartHostDevWrite(struct UartHost *host, uint8_t *data, uint32_t size);
37 static int32_t UartHostDevSetBaud(struct UartHost *host, uint32_t baudRate);
38 static int32_t UartHostDevGetBaud(struct UartHost *host, uint32_t *baudRate);
39 static int32_t UartHostDevSetAttribute(struct UartHost *host, struct UartAttribute *attribute);
40 static int32_t UartHostDevGetAttribute(struct UartHost *host, struct UartAttribute *attribute);
41 static int32_t UartHostDevSetTransMode(struct UartHost *host, enum UartTransMode mode);
42 
43 struct UartHostMethod g_uartHostMethod = {
44     .Init = UartHostDevInit,
45     .Deinit = UartHostDevDeinit,
46     .Read = UartHostDevRead,
47     .Write = UartHostDevWrite,
48     .SetBaud = UartHostDevSetBaud,
49     .GetBaud = UartHostDevGetBaud,
50     .SetAttribute = UartHostDevSetAttribute,
51     .GetAttribute = UartHostDevGetAttribute,
52     .SetTransMode = UartHostDevSetTransMode,
53 };
54 
uart_device_attach(struct UartHost * host,struct HdfDeviceObject * device)55 static int32_t uart_device_attach(struct UartHost *host, struct HdfDeviceObject *device)
56 {
57     if (device->property == NULL) {
58         HDF_LOGE("%s: device->property is null", __func__);
59         return HDF_FAILURE;
60     }
61 
62     uart_driver_data_t *driver_data = (uart_driver_data_t *)OsalMemCalloc(sizeof(uart_driver_data_t));
63 
64     if (driver_data == NULL) {
65         HDF_LOGE("%s: driver_data memory allocation fail", __func__);
66         return HDF_ERR_MALLOC_FAIL;
67     }
68 
69     uart_port_t *port = (uart_port_t *)OsalMemCalloc(sizeof(uart_port_t));
70 
71     if (port == NULL) {
72         HDF_LOGE("%s: port memory allocation fail", __func__);
73         OsalMemFree(driver_data);
74         return HDF_ERR_MALLOC_FAIL;
75     }
76 
77     port->driver_data = driver_data;
78     driver_data->port = port;
79 
80     int32_t ret = get_config_from_hcs(port, device->property);
81     if (ret != HDF_SUCCESS) {
82         OsalMemFree(driver_data);
83         OsalMemFree(port);
84         return HDF_FAILURE;
85     }
86 
87     host->priv = driver_data;
88     host->num = port->num;
89 
90     return HDF_SUCCESS;
91 }
92 
93 
uart_device_bind(struct HdfDeviceObject * device)94 static int32_t uart_device_bind(struct HdfDeviceObject *device)
95 {
96     if (device == NULL) {
97         HDF_LOGE("%s: invalid parameter", __func__);
98         return HDF_ERR_INVALID_PARAM;
99     }
100 
101     return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
102 }
103 
104 
uart_device_init(struct HdfDeviceObject * device)105 static int32_t uart_device_init(struct HdfDeviceObject *device)
106 {
107     if (device == NULL) {
108         HDF_LOGE("%s: invalid parameter", __func__);
109         return HDF_ERR_INVALID_PARAM;
110     }
111 
112     int32_t ret;
113     struct UartHost *host = UartHostFromDevice(device);
114 
115     if (host == NULL) {
116         HDF_LOGE("%s: host is null", __func__);
117         return HDF_FAILURE;
118     }
119 
120     ret = uart_device_attach(host, device);
121     if (ret != HDF_SUCCESS) {
122         HDF_LOGE("%s: attach failed", __func__);
123         return HDF_FAILURE;
124     }
125 
126     host->method = &g_uartHostMethod;
127 
128     return HDF_SUCCESS;
129 }
130 
131 
uart_device_release(struct HdfDeviceObject * device)132 static void uart_device_release(struct HdfDeviceObject *device)
133 {
134     if (device == NULL) {
135         HDF_LOGE("%s: device is null", __func__);
136         return;
137     }
138 
139     struct UartHost *host = UartHostFromDevice(device);
140 
141     if (host == NULL) {
142         HDF_LOGE("%s: host is null", __func__);
143         return;
144     }
145 
146     if (host->priv != NULL) {
147         uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
148         OsalMemFree(driver_data->port);
149         OsalMemFree(driver_data);
150         host->priv = NULL;
151     }
152 }
153 
154 
155 struct HdfDriverEntry g_uartDevice = {
156     .moduleVersion = 1,
157     .moduleName = "TELINK_HDF_PLATFORM_UART",
158     .Bind = uart_device_bind,
159     .Init = uart_device_init,
160     .Release = uart_device_release,
161 };
162 
163 HDF_INIT(g_uartDevice);
164 
165 
tx_pin_from_str(const char * str)166 static uart_tx_pin_e tx_pin_from_str(const char *str)
167 {
168     if (!strcmp(str, "UART0_TX_PA3")) {
169         return UART0_TX_PA3;
170     } else if (!strcmp(str, "UART0_TX_PB2")) {
171         return UART0_TX_PB2;
172     } else if (!strcmp(str, "UART0_TX_PD2")) {
173         return UART0_TX_PD2;
174     } else if (!strcmp(str, "UART1_TX_PC6")) {
175         return UART1_TX_PC6;
176     } else if (!strcmp(str, "UART1_TX_PD6")) {
177         return UART1_TX_PD6;
178     } else if (!strcmp(str, "UART1_TX_PE0")) {
179         return UART1_TX_PE0;
180     } else {
181         return UART_TX_ENUM_SIZE;
182     }
183 }
184 
185 
rx_pin_from_str(const char * str)186 static uart_rx_pin_e rx_pin_from_str(const char *str)
187 {
188     if (!strcmp(str, "UART0_RX_PA4")) {
189         return UART0_RX_PA4;
190     } else if (!strcmp(str, "UART0_RX_PB3")) {
191         return UART0_RX_PB3;
192     } else if (!strcmp(str, "UART0_RX_PD3")) {
193         return UART0_RX_PD3;
194     } else if (!strcmp(str, "UART1_RX_PC7")) {
195         return UART1_RX_PC7;
196     } else if (!strcmp(str, "UART1_RX_PD7")) {
197         return UART1_RX_PD7;
198     } else if (!strcmp(str, "UART1_RX_PE2")) {
199         return UART1_RX_PE2;
200     } else {
201         return UART_RX_ENUM_SIZE;
202     }
203 }
204 
205 
stop_bit_from_str(const char * str)206 static uint8_t stop_bit_from_str(const char *str)
207 {
208     if (!strcmp(str, "UART_STOP_BIT_ONE")) {
209         return UART_ATTR_STOPBIT_1;
210     } else if (!strcmp(str, "UART_STOP_BIT_ONE_DOT_FIVE")) {
211         return UART_ATTR_STOPBIT_1P5;
212     } else if (!strcmp(str, "UART_STOP_BIT_TWO")) {
213         return UART_ATTR_STOPBIT_2;
214     } else {
215         HDF_LOGW("%s: Uart stop bit config is illegal. Assumed there's 1 stop bit", __func__);
216         return UART_ATTR_STOPBIT_1;
217     }
218 }
219 
220 
parity_from_str(const char * str)221 static uint8_t parity_from_str(const char *str)
222 {
223     if (!strcmp(str, "UART_PARITY_NONE")) {
224         return UART_ATTR_PARITY_NONE;
225     } else if (!strcmp(str, "UART_PARITY_EVEN")) {
226         return UART_ATTR_PARITY_EVEN;
227     } else if (!strcmp(str, "UART_PARITY_ODD")) {
228         return UART_ATTR_PARITY_ODD;
229     } else {
230         HDF_LOGW("%s: Uart parity config is illegal. Assumed there's no parity bit", __func__);
231         return UART_ATTR_PARITY_NONE;
232     }
233 }
234 
235 
get_port_config(const struct DeviceResourceNode * node,const char * str,uint32_t * dst)236 static int32_t get_port_config(const struct DeviceResourceNode *node, const char *str, uint32_t *dst)
237 {
238     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
239 
240     if (iface->GetUint32(node, str, dst, HDF_FAILURE) != HDF_SUCCESS) {
241         HDF_LOGE("%s: Failed to get port config", __func__);
242         return HDF_FAILURE;
243     }
244 
245     return HDF_SUCCESS;
246 }
247 
248 
get_config_from_hcs(uart_port_t * port,const struct DeviceResourceNode * node)249 static int32_t get_config_from_hcs(uart_port_t *port, const struct DeviceResourceNode *node)
250 {
251     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
252 
253     if (iface == NULL || iface->GetUint32 == NULL || iface->GetString == NULL) {
254         HDF_LOGE("%s: Interface is invalid", __func__);
255         return HDF_FAILURE;
256     }
257 
258     int32_t ret = get_port_config(node, "port", &port->num);
259     ret |= get_port_config(node, "regPbase", &port->addr);
260     ret |= get_port_config(node, "irqNum", &port->interrupt);
261 
262     uart_driver_data_t *driver_data = port->driver_data;
263 
264     if (iface->GetUint32(node, "baudrate", &driver_data->baudrate, HDF_FAILURE) != HDF_SUCCESS) {
265         HDF_LOGE("%s: Failed to read baudrate", __func__);
266         return HDF_FAILURE;
267     }
268 
269     char *tmp;
270     if (iface->GetString(node, "tx_pin", &tmp, "HDF_FAILURE") != HDF_SUCCESS) {
271         HDF_LOGE("%s: Failed to read tx pin", __func__);
272         return HDF_FAILURE;
273     }
274     driver_data->tx = tx_pin_from_str(tmp);
275     if (driver_data->tx >= UART_TX_ENUM_SIZE) {
276         HDF_LOGE("%s: Tx pin config is illegal", __func__);
277         return HDF_FAILURE;
278     }
279 
280     if (iface->GetString(node, "rx_pin", &tmp, "HDF_FAILURE") != HDF_SUCCESS) {
281         HDF_LOGE("%s: Failed to read rx pin", __func__);
282         return HDF_FAILURE;
283     }
284     driver_data->rx = rx_pin_from_str(tmp);
285     if (driver_data->rx >= UART_RX_ENUM_SIZE) {
286         HDF_LOGE("%s: Rx pin config is illegal", __func__);
287         return HDF_FAILURE;
288     }
289 
290     if (iface->GetString(node, "stop_bits", &tmp, "HDF_FAILURE") != HDF_SUCCESS) {
291         HDF_LOGE("%s: Failed to read stop bits", __func__);
292         return HDF_FAILURE;
293     }
294     driver_data->uattr.stopBits = stop_bit_from_str(tmp);
295 
296     if (iface->GetString(node, "parity", &tmp, "HDF_FAILURE") != HDF_SUCCESS) {
297         HDF_LOGE("%s: Failed to read parity", __func__);
298         return HDF_FAILURE;
299     }
300     driver_data->uattr.parity = parity_from_str(tmp);
301 
302     return (ret == HDF_SUCCESS) ? HDF_SUCCESS : HDF_FAILURE;
303 }
304 
305 
306 // Uart Host methods -----------------------------------------------------------
307 
UartHostDevInit(struct UartHost * host)308 static int32_t UartHostDevInit(struct UartHost *host)
309 {
310     if (host == NULL) {
311         HDF_LOGE("%s: invalid parameter", __func__);
312         return HDF_ERR_INVALID_PARAM;
313     }
314 
315     uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
316     if (driver_data == NULL) {
317         HDF_LOGE("%s: Failed to get driver data from uart host", __func__);
318         return HDF_FAILURE;
319     }
320 
321     uart_dma_init(driver_data);
322     driver_data->port->enable = 1;
323 
324     return HDF_SUCCESS;
325 }
326 
327 
UartHostDevDeinit(struct UartHost * host)328 static int32_t UartHostDevDeinit(struct UartHost *host)
329 {
330     if (host == NULL) {
331         HDF_LOGE("%s: invalid parameter", __func__);
332         return HDF_ERR_INVALID_PARAM;
333     }
334 
335     uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
336     if (driver_data == NULL) {
337         HDF_LOGE("%s: Failed to get driver data from uart host", __func__);
338         return HDF_FAILURE;
339     }
340 
341     driver_data->port->enable = 0;
342 
343     return HDF_SUCCESS;
344 }
345 
346 
UartHostDevRead(struct UartHost * host,uint8_t * data,uint32_t size)347 static int32_t UartHostDevRead(struct UartHost *host, uint8_t *data, uint32_t size)
348 {
349     HDF_LOGD("%s: not implemented yet", __func__);
350     return HDF_FAILURE;
351 }
352 
353 
UartHostDevWrite(struct UartHost * host,uint8_t * data,uint32_t size)354 static int32_t UartHostDevWrite(struct UartHost *host, uint8_t *data, uint32_t size)
355 {
356     uint8_t ret = uart_send_dma(host->num, data, size);
357     return (ret == 1) ? HDF_SUCCESS : HDF_FAILURE;
358 }
359 
360 
UartHostDevSetBaud(struct UartHost * host,uint32_t baudRate)361 static int32_t UartHostDevSetBaud(struct UartHost *host, uint32_t baudRate)
362 {
363     if (host == NULL) {
364         HDF_LOGE("%s: UartHost is NULL!", __func__);
365         return HDF_ERR_INVALID_PARAM;
366     }
367 
368     uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
369     driver_data->baudrate = baudRate;
370 
371     uart_dma_init(driver_data);
372 
373     return HDF_SUCCESS;
374 }
375 
376 
UartHostDevGetBaud(struct UartHost * host,uint32_t * baudRate)377 static int32_t UartHostDevGetBaud(struct UartHost *host, uint32_t *baudRate)
378 {
379     if (host == NULL || baudRate == NULL) {
380         HDF_LOGE("%s: UartHost is NULL!", __func__);
381         return HDF_ERR_INVALID_PARAM;
382     }
383 
384     uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
385     *baudRate = driver_data->baudrate;
386 
387     return HDF_SUCCESS;
388 }
389 
390 
UartHostDevSetAttribute(struct UartHost * host,struct UartAttribute * attribute)391 static int32_t UartHostDevSetAttribute(struct UartHost *host, struct UartAttribute *attribute)
392 {
393     if (host == NULL || attribute == NULL) {
394         HDF_LOGE("%s: UartHost is NULL!", __func__);
395         return HDF_ERR_INVALID_PARAM;
396     }
397 
398     uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
399     driver_data->uattr = *attribute;
400 
401     uart_dma_init(driver_data);
402 
403     return HDF_SUCCESS;
404 }
405 
406 
UartHostDevGetAttribute(struct UartHost * host,struct UartAttribute * attribute)407 static int32_t UartHostDevGetAttribute(struct UartHost *host, struct UartAttribute *attribute)
408 {
409     if (host == NULL || attribute == NULL) {
410         HDF_LOGE("%s: UartHost is NULL!", __func__);
411         return HDF_ERR_INVALID_PARAM;
412     }
413 
414     uart_driver_data_t *driver_data = (uart_driver_data_t *)host->priv;
415     *attribute = driver_data->uattr;
416 
417     return HDF_SUCCESS;
418 }
419 
420 
UartHostDevSetTransMode(struct UartHost * host,enum UartTransMode mode)421 static int32_t UartHostDevSetTransMode(struct UartHost *host, enum UartTransMode mode)
422 {
423     HDF_LOGD("%s: not implemented yet", __func__);
424     return HDF_FAILURE;
425 }
426