1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 *
4 * This file 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 <securec.h>
10
11 #include "can/can_core.h"
12 #include "device_resource_if.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15
16 #define HDF_LOG_TAG can_virtual_c
17 #define CAN_VIRTUAL_BUS_NUM_DFT 31
18
19 struct VirtualCanCntlr {
20 struct CanCntlr cntlr;
21 uint8_t workMode;
22 uint32_t bitRate;
23 uint32_t syncJumpWidth;
24 uint32_t timeSeg1;
25 uint32_t timeSeg2;
26 uint32_t prescaler;
27 int32_t busState;
28 };
29
30 enum VIRTUAL_CAN_SPEED {
31 CAN_SPEED_1M = 1000UL * 1000, /* 1 MBit/sec */
32 CAN_SPEED_800K = 1000UL * 800, /* 800 kBit/sec */
33 CAN_SPEED_500K = 1000UL * 500, /* 500 kBit/sec */
34 CAN_SPEED_250K = 1000UL * 250, /* 250 kBit/sec */
35 CAN_SPEED_125K = 1000UL * 125, /* 125 kBit/sec */
36 CAN_SPEED_100K = 1000UL * 100, /* 100 kBit/sec */
37 CAN_SPEED_50K = 1000UL * 50, /* 50 kBit/sec */
38 CAN_SPEED_20K = 1000UL * 20, /* 20 kBit/sec */
39 CAN_SPEED_10K = 1000UL * 10 /* 10 kBit/sec */
40 };
41
VirtualReadConfigFromHcs(struct VirtualCanCntlr * virtualCan)42 static int32_t VirtualReadConfigFromHcs(struct VirtualCanCntlr *virtualCan)
43 {
44 uint32_t value;
45 const struct DeviceResourceNode *node = NULL;
46 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
47
48 if (virtualCan == NULL) {
49 HDF_LOGE("%s: virtual cntlr is null", __func__);
50 return HDF_ERR_INVALID_OBJECT;
51 }
52
53 node = PlatformDeviceGetDrs(&virtualCan->cntlr.device);
54 if (node == NULL) {
55 HDF_LOGE("%s: properity node null", __func__);
56 return HDF_ERR_INVALID_PARAM;
57 }
58
59 if (iface == NULL || iface->GetUint32 == NULL) {
60 HDF_LOGE("%s: face is invalid", __func__);
61 return HDF_ERR_NOT_SUPPORT;
62 }
63
64 if (iface->GetUint32(node, "bus_num", &value, 0) != HDF_SUCCESS) {
65 HDF_LOGE("%s: read bus number failed", __func__);
66 return HDF_FAILURE;
67 }
68 virtualCan->cntlr.number = (int32_t)value;
69
70 if (iface->GetUint8(node, "work_mode", &virtualCan->workMode, 0) != HDF_SUCCESS) {
71 HDF_LOGE("%s: read work mode failed", __func__);
72 return HDF_FAILURE;
73 }
74
75 if (iface->GetUint32(node, "bit_rate", &virtualCan->bitRate, 0) != HDF_SUCCESS) {
76 HDF_LOGE("%s: read bit reate failed", __func__);
77 return HDF_FAILURE;
78 }
79 return HDF_SUCCESS;
80 }
81
VirtualCanMsgLoopBack(struct VirtualCanCntlr * virtualCan,const struct CanMsg * msg)82 static int32_t VirtualCanMsgLoopBack(struct VirtualCanCntlr *virtualCan, const struct CanMsg *msg)
83 {
84 struct CanMsg new;
85
86 HDF_LOGI("VirtualCanMsgLoopBack: begin");
87
88 new = *msg; // Yeah! this is loop back ...
89
90 virtualCan->busState = CAN_BUS_READY;
91 HDF_LOGI("VirtualCanMsgLoopBack: end");
92 return CanCntlrOnNewMsgIrqSafe(&virtualCan->cntlr, &new);
93 }
94
VirtualCanSendMsg(struct CanCntlr * cntlr,const struct CanMsg * msg)95 static int32_t VirtualCanSendMsg(struct CanCntlr *cntlr, const struct CanMsg *msg)
96 {
97 struct VirtualCanCntlr *virtualCan = NULL;
98
99 if (cntlr == NULL) {
100 return HDF_ERR_INVALID_OBJECT;
101 }
102
103 if (msg == NULL) {
104 return HDF_ERR_INVALID_PARAM;
105 }
106
107 virtualCan = (struct VirtualCanCntlr *)cntlr->device.priv;
108 if (virtualCan == NULL) {
109 HDF_LOGE("%s: private data is null", __func__);
110 return HDF_ERR_INVALID_OBJECT;
111 }
112 virtualCan->busState = CAN_BUS_BUSY;
113
114 return VirtualCanMsgLoopBack(virtualCan, msg);
115 }
116
117 struct VirtualSpeedConfigMap {
118 uint32_t speed;
119 uint32_t sjw;
120 uint32_t tsg1;
121 uint32_t tsg2;
122 uint32_t prescaler;
123 };
124
125 #define CAN_CLK 80M
126
127 #define CAN_SJW_2TQ 2
128 #define CAN_BS1_5TQ 5
129 #define CAN_BS1_7TQ 7
130 #define CAN_BS1_13TQ 13
131 #define CAN_BS1_14TQ 14
132 #define CAN_BS2_2TQ 2
133 #define CAN_BS2_5TQ 5
134
135 /*
136 * S(bit rate) = 1 / ((1 + BS1 + BS2) * TQ)
137 * TQ = Prescaler / Fclk
138 * S(bit rate) = Fclk / (Prescaler * (1 + BS1 + BS2))
139 */
140
141 static const struct VirtualSpeedConfigMap g_speedMaps[] = {
142 {CAN_SPEED_1M, CAN_SJW_2TQ, CAN_BS1_5TQ, CAN_BS2_2TQ, 10 },
143 {CAN_SPEED_800K, CAN_SJW_2TQ, CAN_BS1_14TQ, CAN_BS2_5TQ, 5 },
144 {CAN_SPEED_500K, CAN_SJW_2TQ, CAN_BS1_7TQ, CAN_BS2_2TQ, 16 },
145 {CAN_SPEED_250K, CAN_SJW_2TQ, CAN_BS1_13TQ, CAN_BS2_2TQ, 20 },
146 {CAN_SPEED_125K, CAN_SJW_2TQ, CAN_BS1_13TQ, CAN_BS2_2TQ, 40 },
147 {CAN_SPEED_100K, CAN_SJW_2TQ, CAN_BS1_13TQ, CAN_BS2_2TQ, 50 },
148 {CAN_SPEED_50K, CAN_SJW_2TQ, CAN_BS1_13TQ, CAN_BS2_2TQ, 100},
149 {CAN_SPEED_20K, CAN_SJW_2TQ, CAN_BS1_13TQ, CAN_BS2_2TQ, 250},
150 {CAN_SPEED_10K, CAN_SJW_2TQ, CAN_BS1_13TQ, CAN_BS2_2TQ, 500}
151 };
152
VirtualCanSetBitRate(struct VirtualCanCntlr * virtualCan,uint32_t speed)153 static int32_t VirtualCanSetBitRate(struct VirtualCanCntlr *virtualCan, uint32_t speed)
154 {
155 int32_t i;
156 const struct VirtualSpeedConfigMap *cfgMap;
157
158 for (i = 0; i < sizeof(g_speedMaps) / sizeof(g_speedMaps[0]); i++) {
159 if (g_speedMaps[i].speed == speed) {
160 break;
161 }
162 }
163
164 if (i >= (sizeof(g_speedMaps) / sizeof(g_speedMaps[0]))) {
165 HDF_LOGE("%s: speed: %u not support", __func__, speed);
166 return HDF_ERR_NOT_SUPPORT;
167 }
168
169 cfgMap = &g_speedMaps[i];
170 virtualCan->syncJumpWidth = cfgMap->sjw;
171 virtualCan->timeSeg1 = cfgMap->tsg1;
172 virtualCan->timeSeg2 = cfgMap->tsg2;
173 virtualCan->prescaler = cfgMap->prescaler;
174 virtualCan->bitRate = speed;
175 return HDF_SUCCESS;
176 }
177
VirtualCanSetMode(struct VirtualCanCntlr * virtualCan,int32_t mode)178 static int32_t VirtualCanSetMode(struct VirtualCanCntlr *virtualCan, int32_t mode)
179 {
180 if (mode == CAN_BUS_LOOPBACK) {
181 virtualCan->workMode = CAN_BUS_LOOPBACK;
182 return HDF_SUCCESS;
183 } else {
184 return HDF_ERR_NOT_SUPPORT;
185 }
186 }
187
VirtualCanSetCfg(struct CanCntlr * cntlr,const struct CanConfig * cfg)188 static int32_t VirtualCanSetCfg(struct CanCntlr *cntlr, const struct CanConfig *cfg)
189 {
190 int32_t ret;
191 struct VirtualCanCntlr *virtualCan = NULL;
192
193 virtualCan = (struct VirtualCanCntlr *)cntlr->device.priv;
194 if (virtualCan == NULL) {
195 HDF_LOGE("%s: private data is null", __func__);
196 return HDF_ERR_INVALID_OBJECT;
197 }
198
199 virtualCan->busState = CAN_BUS_RESET;
200 ret = VirtualCanSetBitRate(virtualCan, cfg->speed);
201 if (ret != HDF_SUCCESS) {
202 HDF_LOGE("%s: set speed failed", __func__);
203 return ret;
204 }
205
206 ret = VirtualCanSetMode(virtualCan, cfg->mode);
207 if (ret != HDF_SUCCESS) {
208 HDF_LOGE("%s: set mode failed", __func__);
209 return ret;
210 }
211
212 virtualCan->busState = CAN_BUS_READY;
213 return HDF_SUCCESS;
214 }
215
VirtualCanGetCfg(struct CanCntlr * cntlr,struct CanConfig * cfg)216 static int32_t VirtualCanGetCfg(struct CanCntlr *cntlr, struct CanConfig *cfg)
217 {
218 struct VirtualCanCntlr *virtualCan = NULL;
219
220 virtualCan = (struct VirtualCanCntlr *)cntlr->device.priv;
221 if (virtualCan == NULL) {
222 HDF_LOGE("%s: private data is null", __func__);
223 return HDF_ERR_INVALID_OBJECT;
224 }
225
226 cfg->speed = virtualCan->bitRate;
227 cfg->mode = virtualCan->workMode;
228 return HDF_SUCCESS;
229 }
230
231 struct CanCntlrMethod g_virtualCanMethod = {
232 .sendMsg = VirtualCanSendMsg,
233 .setCfg = VirtualCanSetCfg,
234 .getCfg = VirtualCanGetCfg,
235 };
236
237 /*
238 * ! this function will not be invoked when polciy is 0
239 * ! no need to make any changes here
240 */
HdfVirtualCanBind(struct HdfDeviceObject * device)241 static int32_t HdfVirtualCanBind(struct HdfDeviceObject *device)
242 {
243 return CanServiceBind(device);
244 }
245
VirtualCanSetDefault(struct VirtualCanCntlr * virtualCan)246 static void VirtualCanSetDefault(struct VirtualCanCntlr *virtualCan)
247 {
248 virtualCan->cntlr.number = CAN_VIRTUAL_BUS_NUM_DFT;
249 virtualCan->workMode = CAN_BUS_LOOPBACK;
250 virtualCan->bitRate = CAN_SPEED_10K;
251 }
252
VirtualCanInit(struct VirtualCanCntlr * virtualCan)253 static int32_t VirtualCanInit(struct VirtualCanCntlr *virtualCan)
254 {
255 int32_t ret;
256
257 HDF_LOGI("%s: enter", __func__);
258 if (virtualCan == NULL) {
259 return HDF_ERR_INVALID_OBJECT;
260 }
261
262 VirtualCanSetDefault(virtualCan);
263
264 ret = VirtualReadConfigFromHcs(virtualCan);
265 if (ret != HDF_SUCCESS) {
266 HDF_LOGW("VirtualUartInit: read hcs config failed");
267 }
268
269 ret = VirtualCanSetBitRate(virtualCan, virtualCan->bitRate);
270 if (ret != HDF_SUCCESS) {
271 HDF_LOGE("%s: set bit rate failed", __func__);
272 return ret;
273 }
274
275 ret = VirtualCanSetMode(virtualCan, virtualCan->workMode);
276 if (ret != HDF_SUCCESS) {
277 HDF_LOGE("%s: set mode failed", __func__);
278 return ret;
279 }
280
281 return HDF_SUCCESS;
282 }
283
HdfVirtualCanInit(struct HdfDeviceObject * device)284 static int32_t HdfVirtualCanInit(struct HdfDeviceObject *device)
285 {
286 int32_t ret;
287 struct VirtualCanCntlr *virtualCan = NULL;
288
289 HDF_LOGI("%s: entry", __func__);
290 if (device == NULL) {
291 HDF_LOGE("%s: device is null", __func__);
292 return HDF_ERR_INVALID_OBJECT;
293 }
294
295 virtualCan = (struct VirtualCanCntlr *)OsalMemCalloc(sizeof(*virtualCan));
296 if (virtualCan == NULL) {
297 return HDF_ERR_MALLOC_FAIL;
298 }
299
300 virtualCan->busState = CAN_BUS_RESET;
301 ret = VirtualCanInit(virtualCan);
302 if (ret != HDF_SUCCESS) {
303 OsalMemFree(virtualCan);
304 HDF_LOGE("%s: can init error: %d", __func__, ret);
305 return ret;
306 }
307 virtualCan->busState = CAN_BUS_READY;
308
309 virtualCan->cntlr.ops = &g_virtualCanMethod;
310 virtualCan->cntlr.device.priv = virtualCan;
311 ret = CanCntlrAdd(&virtualCan->cntlr);
312 if (ret != HDF_SUCCESS) {
313 OsalMemFree(virtualCan);
314 HDF_LOGE("%s: add cntlr failed: %d", __func__, ret);
315 return ret;
316 }
317
318 ret = CanCntlrSetHdfDev(&virtualCan->cntlr, device);
319 if (ret != HDF_SUCCESS) {
320 HDF_LOGW("%s: can controller attach failed:%d", __func__, ret);
321 }
322
323 return HDF_SUCCESS;
324 }
325
VirtualCanDeinit(struct VirtualCanCntlr * virtualCan)326 static int32_t VirtualCanDeinit(struct VirtualCanCntlr *virtualCan)
327 {
328 (void)virtualCan;
329 return HDF_SUCCESS;
330 }
331
HdfVirtualCanRelease(struct HdfDeviceObject * device)332 static void HdfVirtualCanRelease(struct HdfDeviceObject *device)
333 {
334 struct VirtualCanCntlr *virtualCan = NULL;
335
336 HDF_LOGI("%s: entry", __func__);
337 if (device == NULL) {
338 HDF_LOGE("%s: device is null", __func__);
339 return;
340 }
341
342 virtualCan = (struct VirtualCanCntlr *)CanCntlrFromHdfDev(device);
343 if (virtualCan == NULL) {
344 HDF_LOGE("%s: platform device not bind", __func__);
345 return;
346 }
347
348 CanServiceRelease(device);
349 (void)CanCntlrDel(&virtualCan->cntlr);
350 VirtualCanDeinit(virtualCan);
351 OsalMemFree(virtualCan);
352 }
353
354 static struct HdfDriverEntry g_hdfCanDriver = {
355 .moduleVersion = 1,
356 .moduleName = "can_driver_virtual",
357 .Bind = HdfVirtualCanBind,
358 .Init = HdfVirtualCanInit,
359 .Release = HdfVirtualCanRelease,
360 };
361
CanVirtualGetEntry(void)362 struct HdfDriverEntry *CanVirtualGetEntry(void)
363 {
364 return &g_hdfCanDriver;
365 }
366
367 HDF_INIT(g_hdfCanDriver);
368