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