• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 CanCntlrOnNewMsg(&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     switch (mode) {
181         case CAN_BUS_LOOPBACK:
182             virtualCan->workMode = CAN_BUS_LOOPBACK;
183             break;
184         default:
185             return HDF_ERR_NOT_SUPPORT;
186     }
187     return HDF_SUCCESS;
188 }
189 
VirtualCanSetCfg(struct CanCntlr * cntlr,const struct CanConfig * cfg)190 static int32_t VirtualCanSetCfg(struct CanCntlr *cntlr, const struct CanConfig *cfg)
191 {
192     int32_t ret;
193     struct VirtualCanCntlr *virtualCan = NULL;
194 
195     virtualCan = (struct VirtualCanCntlr *)cntlr->device.priv;
196     if (virtualCan == NULL) {
197         HDF_LOGE("%s: private data is null", __func__);
198         return HDF_ERR_INVALID_OBJECT;
199     }
200 
201     virtualCan->busState = CAN_BUS_RESET;
202     ret = VirtualCanSetBitRate(virtualCan, cfg->speed);
203     if (ret != HDF_SUCCESS) {
204         HDF_LOGE("%s: set speed failed", __func__);
205         return ret;
206     }
207 
208     ret = VirtualCanSetMode(virtualCan, cfg->mode);
209     if (ret != HDF_SUCCESS) {
210         HDF_LOGE("%s: set mode failed", __func__);
211         return ret;
212     }
213 
214     virtualCan->busState = CAN_BUS_READY;
215     return HDF_SUCCESS;
216 }
217 
VirtualCanGetCfg(struct CanCntlr * cntlr,struct CanConfig * cfg)218 static int32_t VirtualCanGetCfg(struct CanCntlr *cntlr, struct CanConfig *cfg)
219 {
220     struct VirtualCanCntlr *virtualCan = NULL;
221 
222     virtualCan = (struct VirtualCanCntlr *)cntlr->device.priv;
223     if (virtualCan == NULL) {
224         HDF_LOGE("%s: private data is null", __func__);
225         return HDF_ERR_INVALID_OBJECT;
226     }
227 
228     cfg->speed = virtualCan->bitRate;
229     cfg->mode = virtualCan->workMode;
230     return HDF_SUCCESS;
231 }
232 
233 struct CanCntlrMethod g_virtualCanMethod = {
234     .sendMsg = VirtualCanSendMsg,
235     .setCfg = VirtualCanSetCfg,
236     .getCfg = VirtualCanGetCfg,
237 };
238 
239 /*
240  * ! this function will not be invoked when polciy is 0
241  * ! no need to make any changes here
242  */
HdfVirtualCanBind(struct HdfDeviceObject * device)243 static int32_t HdfVirtualCanBind(struct HdfDeviceObject *device)
244 {
245     return CanServiceBind(device);
246 }
247 
VirtualCanSetDefault(struct VirtualCanCntlr * virtualCan)248 static void VirtualCanSetDefault(struct VirtualCanCntlr *virtualCan)
249 {
250     virtualCan->cntlr.number = CAN_VIRTUAL_BUS_NUM_DFT;
251     virtualCan->workMode = CAN_BUS_LOOPBACK;
252     virtualCan->bitRate = CAN_SPEED_10K;
253 }
254 
VirtualCanInit(struct VirtualCanCntlr * virtualCan)255 static int32_t VirtualCanInit(struct VirtualCanCntlr *virtualCan)
256 {
257     int32_t ret;
258 
259     HDF_LOGI("%s: enter", __func__);
260     if (virtualCan == NULL) {
261         return HDF_ERR_INVALID_OBJECT;
262     }
263 
264     VirtualCanSetDefault(virtualCan);
265 
266     ret = VirtualReadConfigFromHcs(virtualCan);
267     if (ret != HDF_SUCCESS) {
268         HDF_LOGW("VirtualUartInit: read hcs config failed");
269     }
270 
271     ret = VirtualCanSetBitRate(virtualCan, virtualCan->bitRate);
272     if (ret != HDF_SUCCESS) {
273         HDF_LOGE("%s: set bit rate failed", __func__);
274         return ret;
275     }
276 
277     ret = VirtualCanSetMode(virtualCan, virtualCan->workMode);
278     if (ret != HDF_SUCCESS) {
279         HDF_LOGE("%s: set mode failed", __func__);
280         return ret;
281     }
282 
283     return HDF_SUCCESS;
284 }
285 
HdfVirtualCanInit(struct HdfDeviceObject * device)286 static int32_t HdfVirtualCanInit(struct HdfDeviceObject *device)
287 {
288     int32_t ret;
289     struct VirtualCanCntlr *virtualCan = NULL;
290 
291     HDF_LOGI("%s: entry", __func__);
292     if (device == NULL) {
293         HDF_LOGE("%s: device is null", __func__);
294         return HDF_ERR_INVALID_OBJECT;
295     }
296 
297     virtualCan = (struct VirtualCanCntlr *)OsalMemCalloc(sizeof(*virtualCan));
298     if (virtualCan == NULL) {
299         return HDF_ERR_MALLOC_FAIL;
300     }
301 
302     virtualCan->busState = CAN_BUS_RESET;
303     ret = VirtualCanInit(virtualCan);
304     if (ret != HDF_SUCCESS) {
305         OsalMemFree(virtualCan);
306         HDF_LOGE("%s: can init error: %d", __func__, ret);
307         return ret;
308     }
309     virtualCan->busState = CAN_BUS_READY;
310 
311     virtualCan->cntlr.ops = &g_virtualCanMethod;
312     virtualCan->cntlr.device.priv = virtualCan;
313     ret = CanCntlrAdd(&virtualCan->cntlr);
314     if (ret != HDF_SUCCESS) {
315         OsalMemFree(virtualCan);
316         HDF_LOGE("%s: add cntlr failed: %d", __func__, ret);
317         return ret;
318     }
319 
320     ret = CanCntlrSetHdfDev(&virtualCan->cntlr, device);
321     if (ret != HDF_SUCCESS) {
322         HDF_LOGW("%s: can controller attach failed:%d", __func__, ret);
323     }
324 
325     return HDF_SUCCESS;
326 }
327 
VirtualCanDeinit(struct VirtualCanCntlr * virtualCan)328 static int32_t VirtualCanDeinit(struct VirtualCanCntlr *virtualCan)
329 {
330     (void)virtualCan;
331     return HDF_SUCCESS;
332 }
333 
HdfVirtualCanRelease(struct HdfDeviceObject * device)334 static void HdfVirtualCanRelease(struct HdfDeviceObject *device)
335 {
336     struct VirtualCanCntlr *virtualCan = NULL;
337 
338     HDF_LOGI("%s: entry", __func__);
339     if (device == NULL) {
340         HDF_LOGE("%s: device is null", __func__);
341         return;
342     }
343 
344     virtualCan = (struct VirtualCanCntlr *)CanCntlrFromHdfDev(device);
345     if (virtualCan == NULL) {
346         HDF_LOGE("%s: platform device not bind", __func__);
347         return;
348     }
349 
350     CanServiceRelease(device);
351     (void)CanCntlrDel(&virtualCan->cntlr);
352     VirtualCanDeinit(virtualCan);
353     OsalMemFree(virtualCan);
354 }
355 
356 static struct HdfDriverEntry g_hdfCanDriver = {
357     .moduleVersion = 1,
358     .moduleName = "can_driver_virtual",
359     .Bind = HdfVirtualCanBind,
360     .Init = HdfVirtualCanInit,
361     .Release = HdfVirtualCanRelease,
362 };
363 
CanVirtualGetEntry(void)364 struct HdfDriverEntry *CanVirtualGetEntry(void)
365 {
366     return &g_hdfCanDriver;
367 }
368 
369 HDF_INIT(g_hdfCanDriver);
370