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