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