• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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