• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  *
4  * HDF 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 "dac_core.h"
10 #include "hdf_device_desc.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "osal_spinlock.h"
14 #include "osal_time.h"
15 #include "platform_core.h"
16 #include "platform_trace.h"
17 
18 #define DAC_HANDLE_SHIFT    0xFF00U
19 #define DAC_TRACE_BASIC_PARAM_NUM  2
20 #define DAC_TRACE_PARAM_STOP_NUM   2
21 #define HDF_LOG_TAG dac_core_c
22 
23 struct DacManager {
24     struct IDeviceIoService service;
25     struct HdfDeviceObject *device;
26     struct DacDevice *devices[DAC_DEVICES_MAX];
27     OsalSpinlock spin;
28 };
29 
30 static struct DacManager *g_dacManager = NULL;
31 
DacDeviceLockDefault(struct DacDevice * device)32 static int32_t DacDeviceLockDefault(struct DacDevice *device)
33 {
34     if (device == NULL) {
35         HDF_LOGE("DacDeviceLockDefault: device is null!");
36         return HDF_ERR_INVALID_OBJECT;
37     }
38     return OsalSpinLock(&device->spin);
39 }
40 
DacDeviceUnlockDefault(struct DacDevice * device)41 static void DacDeviceUnlockDefault(struct DacDevice *device)
42 {
43     if (device == NULL) {
44         HDF_LOGE("DacDeviceUnlockDefault: device is null!");
45         return;
46     }
47     (void)OsalSpinUnlock(&device->spin);
48 }
49 
50 static const struct DacLockMethod g_dacLockOpsDefault = {
51     .lock = DacDeviceLockDefault,
52     .unlock = DacDeviceUnlockDefault,
53 };
54 
DacDeviceLock(struct DacDevice * device)55 static inline int32_t DacDeviceLock(struct DacDevice *device)
56 {
57     if (device == NULL) {
58         HDF_LOGE("DacDeviceLock: device is null!");
59         return HDF_ERR_INVALID_OBJECT;
60     }
61     if (device->lockOps == NULL || device->lockOps->lock == NULL) {
62         HDF_LOGE("DacDeviceLock: dac device lock is not support!");
63         return HDF_ERR_NOT_SUPPORT;
64     }
65     return device->lockOps->lock(device);
66 }
67 
DacDeviceUnlock(struct DacDevice * device)68 static inline void DacDeviceUnlock(struct DacDevice *device)
69 {
70     if (device == NULL) {
71         HDF_LOGE("DacDeviceUnlock: device is null!");
72         return;
73     }
74     if (device->lockOps != NULL && device->lockOps->unlock != NULL) {
75         device->lockOps->unlock(device);
76     }
77 }
78 
DacManagerAddDevice(struct DacDevice * device)79 static int32_t DacManagerAddDevice(struct DacDevice *device)
80 {
81     int32_t ret;
82     struct DacManager *manager = g_dacManager;
83 
84     if (device == NULL) {
85         HDF_LOGE("DacManagerAddDevice: device is null!");
86         return HDF_ERR_INVALID_OBJECT;
87     }
88     if (device->devNum >= DAC_DEVICES_MAX) {
89         HDF_LOGE("DacManagerAddDevice: devNum:%u exceed!", device->devNum);
90         return HDF_ERR_INVALID_OBJECT;
91     }
92 
93     if (manager == NULL) {
94         HDF_LOGE("DacManagerAddDevice: get dac manager fail!");
95         return HDF_ERR_NOT_SUPPORT;
96     }
97 
98     if (OsalSpinLockIrq(&manager->spin) != HDF_SUCCESS) {
99         HDF_LOGE("DacManagerAddDevice: lock dac manager fail!");
100         return HDF_ERR_DEVICE_BUSY;
101     }
102 
103     if (manager->devices[device->devNum] != NULL) {
104         HDF_LOGE("DacManagerAddDevice: dac device num:%u alwritey exits!", device->devNum);
105         ret = HDF_FAILURE;
106     } else {
107         manager->devices[device->devNum] = device;
108         ret = HDF_SUCCESS;
109     }
110 
111     (void)OsalSpinUnlockIrq(&manager->spin);
112     return ret;
113 }
114 
DacManagerRemoveDevice(const struct DacDevice * device)115 static void DacManagerRemoveDevice(const struct DacDevice *device)
116 {
117     struct DacManager *manager = g_dacManager;
118 
119     if (device == NULL) {
120         HDF_LOGE("DacManagerRemoveDevice: device is null!");
121         return;
122     }
123     if (device->devNum < 0 || device->devNum >= DAC_DEVICES_MAX) {
124         HDF_LOGE("DacManagerRemoveDevice: invalid devNum:%u!", device->devNum);
125         return;
126     }
127 
128     if (manager == NULL) {
129         HDF_LOGE("DacManagerRemoveDevice: get dac manager fail!");
130         return;
131     }
132 
133     if (OsalSpinLockIrq(&manager->spin) != HDF_SUCCESS) {
134         HDF_LOGE("DacManagerRemoveDevice: lock dac manager fail!");
135         return;
136     }
137 
138     if (manager->devices[device->devNum] != device) {
139         HDF_LOGE("DacManagerRemoveDevice: dac device(%u) not in manager!", device->devNum);
140     } else {
141         manager->devices[device->devNum] = NULL;
142     }
143 
144     (void)OsalSpinUnlockIrq(&manager->spin);
145 }
146 
DacManagerFindDevice(uint32_t number)147 static struct DacDevice *DacManagerFindDevice(uint32_t number)
148 {
149     struct DacDevice *device = NULL;
150     struct DacManager *manager = g_dacManager;
151 
152     if (number >= DAC_DEVICES_MAX) {
153         HDF_LOGE("DacManagerFindDevice: invalid devNum:%u!", number);
154         return NULL;
155     }
156 
157     if (manager == NULL) {
158         HDF_LOGE("DacManagerFindDevice: get dac manager fail!");
159         return NULL;
160     }
161 
162     if (OsalSpinLockIrq(&manager->spin) != HDF_SUCCESS) {
163         HDF_LOGE("DacManagerFindDevice: lock dac manager fail!");
164         return NULL;
165     }
166 
167     device = manager->devices[number];
168     (void)OsalSpinUnlockIrq(&manager->spin);
169 
170     return device;
171 }
172 
DacDeviceAdd(struct DacDevice * device)173 int32_t DacDeviceAdd(struct DacDevice *device)
174 {
175     int32_t ret;
176 
177     if (device == NULL) {
178         HDF_LOGE("DacDeviceAdd: device is null!");
179         return HDF_ERR_INVALID_OBJECT;
180     }
181 
182     if (device->ops == NULL) {
183         HDF_LOGE("DacDeviceAdd: no ops supplied!");
184         return HDF_ERR_INVALID_OBJECT;
185     }
186 
187     if (device->lockOps == NULL) {
188         HDF_LOGI("DacDeviceAdd: use default lockOps!");
189         device->lockOps = &g_dacLockOpsDefault;
190     }
191 
192     if (OsalSpinInit(&device->spin) != HDF_SUCCESS) {
193         HDF_LOGE("DacDeviceAdd: init lock fail!");
194         return HDF_FAILURE;
195     }
196 
197     ret = DacManagerAddDevice(device);
198     if (ret != HDF_SUCCESS) {
199         HDF_LOGE("DacDeviceAdd: dac manager add device fail!");
200         (void)OsalSpinDestroy(&device->spin);
201     }
202     return ret;
203 }
204 
DacDeviceRemove(struct DacDevice * device)205 void DacDeviceRemove(struct DacDevice *device)
206 {
207     if (device == NULL) {
208         HDF_LOGE("DacDeviceRemove: device is null!");
209         return;
210     }
211     DacManagerRemoveDevice(device);
212     (void)OsalSpinDestroy(&device->spin);
213 }
214 
DacDeviceGet(uint32_t number)215 struct DacDevice *DacDeviceGet(uint32_t number)
216 {
217     return DacManagerFindDevice(number);
218 }
219 
DacDevicePut(const struct DacDevice * device)220 void DacDevicePut(const struct DacDevice *device)
221 {
222     (void)device;
223 }
224 
DacDeviceOpen(uint32_t number)225 static struct DacDevice *DacDeviceOpen(uint32_t number)
226 {
227     int32_t ret;
228     struct DacDevice *device = NULL;
229 
230     device = DacDeviceGet(number);
231     if (device == NULL) {
232         HDF_LOGE("DacDeviceOpen: get device fail!");
233         return NULL;
234     }
235 
236     ret = DacDeviceStart(device);
237     if (ret != HDF_SUCCESS) {
238         HDF_LOGE("DacDeviceOpen: start device fail!");
239         return NULL;
240     }
241 
242     return device;
243 }
244 
DacDeviceClose(struct DacDevice * device)245 static void DacDeviceClose(struct DacDevice *device)
246 {
247     if (device == NULL) {
248         HDF_LOGE("DacDeviceClose: device is null!");
249         return;
250     }
251 
252     (void)DacDeviceStop(device);
253     DacDevicePut(device);
254 }
255 
DacDeviceWrite(struct DacDevice * device,uint32_t channel,uint32_t val)256 int32_t DacDeviceWrite(struct DacDevice *device, uint32_t channel, uint32_t val)
257 {
258     int32_t ret;
259 
260     if (device == NULL) {
261         HDF_LOGE("DacDeviceWrite: device is null!");
262         return HDF_ERR_INVALID_OBJECT;
263     }
264 
265     if (device->ops == NULL || device->ops->write == NULL) {
266         HDF_LOGE("DacDeviceWrite: ops or write is null!");
267         return HDF_ERR_NOT_SUPPORT;
268     }
269 
270     if (DacDeviceLock(device) != HDF_SUCCESS) {
271         HDF_LOGE("DacDeviceWrite: lock add device fail!");
272         return HDF_ERR_DEVICE_BUSY;
273     }
274 
275     ret = device->ops->write(device, channel, val);
276     DacDeviceUnlock(device);
277     return ret;
278 }
279 
DacDeviceStart(struct DacDevice * device)280 int32_t DacDeviceStart(struct DacDevice *device)
281 {
282     int32_t ret;
283 
284     if (device == NULL) {
285         HDF_LOGE("DacDeviceStart: device is null!");
286         return HDF_ERR_INVALID_OBJECT;
287     }
288 
289     if (device->ops == NULL || device->ops->start == NULL) {
290         HDF_LOGE("DacDeviceStart: ops or start is null!");
291         return HDF_ERR_NOT_SUPPORT;
292     }
293 
294     if (DacDeviceLock(device) != HDF_SUCCESS) {
295         HDF_LOGE("DacDeviceStart: lock dac device fail!");
296         return HDF_ERR_DEVICE_BUSY;
297     }
298 
299     ret = device->ops->start(device);
300     if (PlatformTraceStart() == HDF_SUCCESS) {
301         unsigned int infos[DAC_TRACE_BASIC_PARAM_NUM];
302         infos[PLATFORM_TRACE_UINT_PARAM_SIZE_1 - 1] = device->devNum;
303         infos[PLATFORM_TRACE_UINT_PARAM_SIZE_2 - 1] = device->chanNum;
304         PlatformTraceAddUintMsg(
305             PLATFORM_TRACE_MODULE_DAC, PLATFORM_TRACE_MODULE_DAC_FUN_START, infos, DAC_TRACE_BASIC_PARAM_NUM);
306         PlatformTraceStop();
307     }
308     DacDeviceUnlock(device);
309     return ret;
310 }
311 
DacDeviceStop(struct DacDevice * device)312 int32_t DacDeviceStop(struct DacDevice *device)
313 {
314     int32_t ret;
315 
316     if (device == NULL) {
317         HDF_LOGE("DacDeviceStop: device is null!");
318         return HDF_ERR_INVALID_OBJECT;
319     }
320 
321     if (device->ops == NULL || device->ops->stop == NULL) {
322         HDF_LOGE("DacDeviceStop: ops or stop is null!");
323         return HDF_ERR_NOT_SUPPORT;
324     }
325 
326     if (DacDeviceLock(device) != HDF_SUCCESS) {
327         HDF_LOGE("DacDeviceStop: lock dac device fail!");
328         return HDF_ERR_DEVICE_BUSY;
329     }
330 
331     ret = device->ops->stop(device);
332     if (PlatformTraceStart() == HDF_SUCCESS) {
333         unsigned int infos[DAC_TRACE_PARAM_STOP_NUM];
334         infos[PLATFORM_TRACE_UINT_PARAM_SIZE_1 - 1] = device->devNum;
335         infos[PLATFORM_TRACE_UINT_PARAM_SIZE_2 - 1] = device->chanNum;
336         PlatformTraceAddUintMsg(
337             PLATFORM_TRACE_MODULE_DAC, PLATFORM_TRACE_MODULE_DAC_FUN_STOP, infos, DAC_TRACE_PARAM_STOP_NUM);
338         PlatformTraceStop();
339         PlatformTraceInfoDump();
340     }
341     DacDeviceUnlock(device);
342     return ret;
343 }
344 
DacManagerIoOpen(struct HdfSBuf * data,struct HdfSBuf * reply)345 static int32_t DacManagerIoOpen(struct HdfSBuf *data, struct HdfSBuf *reply)
346 {
347     uint32_t number;
348 
349     if (data == NULL || reply == NULL) {
350         HDF_LOGE("DacManagerIoOpen: invalid data or reply!");
351         return HDF_ERR_INVALID_PARAM;
352     }
353 
354     if (!HdfSbufReadUint32(data, &number)) {
355         HDF_LOGE("DacManagerIoOpen: read number fail!");
356         return HDF_ERR_IO;
357     }
358 
359     if (number >= DAC_DEVICES_MAX) {
360         HDF_LOGE("DacManagerIoOpen: invalid number %u!", number);
361         return HDF_ERR_INVALID_PARAM;
362     }
363 
364     if (DacDeviceOpen(number) == NULL) {
365         HDF_LOGE("DacManagerIoOpen: get device %u fail!", number);
366         return HDF_ERR_NOT_SUPPORT;
367     }
368 
369     number = (uint32_t)(number + DAC_HANDLE_SHIFT);
370     if (!HdfSbufWriteUint32(reply, (uint32_t)(uintptr_t)number)) {
371         HDF_LOGE("DacManagerIoOpen: write number fail!");
372         return HDF_ERR_IO;
373     }
374     return HDF_SUCCESS;
375 }
376 
DacManagerIoClose(struct HdfSBuf * data,struct HdfSBuf * reply)377 static int32_t DacManagerIoClose(struct HdfSBuf *data, struct HdfSBuf *reply)
378 {
379     uint32_t number;
380 
381     (void)reply;
382     if (data == NULL) {
383         HDF_LOGE("DacManagerIoClose: invalid data!");
384         return HDF_ERR_INVALID_PARAM;
385     }
386 
387     if (!HdfSbufReadUint32(data, &number)) {
388         HDF_LOGE("DacManagerIoClose: read number fail!");
389         return HDF_ERR_IO;
390     }
391 
392     number  = (uint32_t)(number - DAC_HANDLE_SHIFT);
393     if (number >= DAC_DEVICES_MAX) {
394         HDF_LOGE("DacManagerIoClose: invalid number %u!", number);
395         return HDF_ERR_INVALID_PARAM;
396     }
397 
398     DacDeviceClose(DacDeviceGet(number));
399     return HDF_SUCCESS;
400 }
401 
DacManagerIoWrite(struct HdfSBuf * data,struct HdfSBuf * reply)402 static int32_t DacManagerIoWrite(struct HdfSBuf *data, struct HdfSBuf *reply)
403 {
404     int32_t ret;
405     uint32_t channel;
406     uint32_t val;
407     uint32_t number;
408 
409     (void)reply;
410     if (data == NULL) {
411         HDF_LOGE("DacManagerIoWrite: invalid data!");
412         return HDF_ERR_INVALID_PARAM;
413     }
414 
415     if (!HdfSbufReadUint32(data, &number)) {
416         HDF_LOGE("DacManagerIoWrite: read number fail!");
417         return HDF_ERR_IO;
418     }
419 
420     number = (uint32_t)(number - DAC_HANDLE_SHIFT);
421     if (number >= DAC_DEVICES_MAX) {
422         HDF_LOGE("DacManagerIoWrite: invalid number %u!", number);
423         return HDF_ERR_INVALID_PARAM;
424     }
425 
426     if (!HdfSbufReadUint32(data, &channel)) {
427         HDF_LOGE("DacManagerIoWrite: read dac channel fail");
428         return HDF_ERR_IO;
429     }
430 
431     if (!HdfSbufReadUint32(data, &val)) {
432         HDF_LOGE("DacManagerIoWrite: read dac value fail!");
433         return HDF_ERR_IO;
434     }
435 
436     ret = DacDeviceWrite(DacDeviceGet(number), channel, val);
437     if (ret != HDF_SUCCESS) {
438         HDF_LOGE("DacManagerIoWrite: write dac fail, ret: %d!", ret);
439         return ret;
440     }
441 
442     return HDF_SUCCESS;
443 }
444 
DacManagerDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)445 static int32_t DacManagerDispatch(struct HdfDeviceIoClient *client, int cmd,
446     struct HdfSBuf *data, struct HdfSBuf *reply)
447 {
448     (void)client;
449     switch (cmd) {
450         case DAC_IO_OPEN:
451             return DacManagerIoOpen(data, reply);
452         case DAC_IO_CLOSE:
453             return DacManagerIoClose(data, reply);
454         case DAC_IO_WRITE:
455             return DacManagerIoWrite(data, reply);
456         default:
457             HDF_LOGE("DacManagerDispatch: cmd %d is not support!", cmd);
458             return HDF_ERR_NOT_SUPPORT;
459     }
460     return HDF_SUCCESS;
461 }
DacManagerBind(struct HdfDeviceObject * device)462 static int32_t DacManagerBind(struct HdfDeviceObject *device)
463 {
464     (void)device;
465     return HDF_SUCCESS;
466 }
DacManagerInit(struct HdfDeviceObject * device)467 static int32_t DacManagerInit(struct HdfDeviceObject *device)
468 {
469     int32_t ret;
470     struct DacManager *manager = NULL;
471 
472     if (device == NULL) {
473         HDF_LOGE("DacManagerInit: device is null!");
474         return HDF_ERR_INVALID_OBJECT;
475     }
476 
477     manager = (struct DacManager *)OsalMemCalloc(sizeof(*manager));
478     if (manager == NULL) {
479         HDF_LOGE("DacManagerInit: memcalloc manager fail!");
480         return HDF_ERR_MALLOC_FAIL;
481     }
482 
483     ret = OsalSpinInit(&manager->spin);
484     if (ret != HDF_SUCCESS) {
485         HDF_LOGE("DacManagerInit: spinlock init fail!");
486         OsalMemFree(manager);
487         return ret;
488     }
489 
490     manager->device = device;
491     g_dacManager = manager;
492     device->service = &manager->service;
493     device->service->Dispatch = DacManagerDispatch;
494     return HDF_SUCCESS;
495 }
496 
DacManagerRelease(struct HdfDeviceObject * device)497 static void DacManagerRelease(struct HdfDeviceObject *device)
498 {
499     struct DacManager *manager = NULL;
500 
501     if (device == NULL) {
502         HDF_LOGE("DacManagerRelease: device is null!");
503         return;
504     }
505 
506     manager = (struct DacManager *)device->service;
507     if (manager == NULL) {
508         HDF_LOGI("DacManagerRelease: no service bind!");
509         return;
510     }
511 
512     g_dacManager = NULL;
513     OsalMemFree(manager);
514 }
515 
516 struct HdfDriverEntry g_dacManagerEntry = {
517     .moduleVersion = 1,
518     .Bind = DacManagerBind,
519     .Init = DacManagerInit,
520     .Release = DacManagerRelease,
521     .moduleName = "HDF_PLATFORM_DAC_MANAGER",
522 };
523 HDF_INIT(g_dacManagerEntry);
524