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(struct DacDevice * device)111 static void DacManagerRemoveDevice(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 < 0 || 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(struct DacDevice * device)215 void DacDevicePut(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 < 0 || number >= DAC_DEVICES_MAX || reply == NULL) {
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 if (data == NULL) {
360 HDF_LOGE("%s: invalid data", __func__);
361 return HDF_ERR_INVALID_PARAM;
362 }
363
364 if (!HdfSbufReadUint32(data, &number)) {
365 HDF_LOGE("%s: read number failed!", __func__);
366 return HDF_ERR_IO;
367 }
368
369 number = (uint32_t)(number - DAC_HANDLE_SHIFT);
370 if (number < 0 || number >= DAC_DEVICES_MAX) {
371 HDF_LOGE("%s: invalid number %u", __func__, number);
372 return HDF_ERR_INVALID_PARAM;
373 }
374
375 DacDeviceClose(DacDeviceGet(number));
376 return HDF_SUCCESS;
377 }
378
DacManagerIoWrite(struct HdfSBuf * data,struct HdfSBuf * reply)379 static int32_t DacManagerIoWrite(struct HdfSBuf *data, struct HdfSBuf *reply)
380 {
381 int32_t ret;
382 uint32_t channel;
383 uint32_t val;
384 uint32_t number;
385
386 if (data == NULL) {
387 HDF_LOGE("%s: invalid data", __func__);
388 return HDF_ERR_INVALID_PARAM;
389 }
390
391 if (!HdfSbufReadUint32(data, &number)) {
392 HDF_LOGE("%s: read number failed!", __func__);
393 return HDF_ERR_IO;
394 }
395
396 number = (uint32_t)(number - DAC_HANDLE_SHIFT);
397 if (number < 0 || number >= DAC_DEVICES_MAX) {
398 HDF_LOGE("%s: invalid number %u", __func__, number);
399 return HDF_ERR_INVALID_PARAM;
400 }
401
402 if (!HdfSbufReadUint32(data, &channel)) {
403 HDF_LOGE("%s: read dac channel failed", __func__);
404 return HDF_ERR_IO;
405 }
406
407 if (!HdfSbufReadUint32(data, &val)) {
408 HDF_LOGE("%s: read dac value failed", __func__);
409 return HDF_ERR_IO;
410 }
411
412 ret = DacDeviceWrite(DacDeviceGet(number), channel, val);
413 if (ret != HDF_SUCCESS) {
414 HDF_LOGE("%s: write dac failed:%d", __func__, ret);
415 return ret;
416 }
417
418 return HDF_SUCCESS;
419 }
420
DacManagerDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)421 static int32_t DacManagerDispatch(struct HdfDeviceIoClient *client, int cmd,
422 struct HdfSBuf *data, struct HdfSBuf *reply)
423 {
424 switch (cmd) {
425 case DAC_IO_OPEN:
426 return DacManagerIoOpen(data, reply);
427 case DAC_IO_CLOSE:
428 return DacManagerIoClose(data, reply);
429 case DAC_IO_WRITE:
430 return DacManagerIoWrite(data, reply);
431 default:
432 return HDF_ERR_NOT_SUPPORT;
433 }
434 return HDF_SUCCESS;
435 }
DacManagerBind(struct HdfDeviceObject * device)436 static int32_t DacManagerBind(struct HdfDeviceObject *device)
437 {
438 (void)device;
439 return HDF_SUCCESS;
440 }
DacManagerInit(struct HdfDeviceObject * device)441 static int32_t DacManagerInit(struct HdfDeviceObject *device)
442 {
443 int32_t ret;
444 struct DacManager *manager = NULL;
445
446 if (device == NULL) {
447 HDF_LOGE("%s: device is null", __func__);
448 return HDF_ERR_INVALID_OBJECT;
449 }
450
451 manager = (struct DacManager *)OsalMemCalloc(sizeof(*manager));
452 if (manager == NULL) {
453 HDF_LOGE("%s: alloc manager failed", __func__);
454 return HDF_ERR_MALLOC_FAIL;
455 }
456
457 ret = OsalSpinInit(&manager->spin);
458 if (ret != HDF_SUCCESS) {
459 HDF_LOGE("%s: spinlock init failed", __func__);
460 OsalMemFree(manager);
461 return HDF_FAILURE;
462 }
463
464 manager->device = device;
465 g_dacManager = manager;
466 device->service = &manager->service;
467 device->service->Dispatch = DacManagerDispatch;
468 return HDF_SUCCESS;
469 }
470
DacManagerRelease(struct HdfDeviceObject * device)471 static void DacManagerRelease(struct HdfDeviceObject *device)
472 {
473 struct DacManager *manager = NULL;
474
475 if (device == NULL) {
476 HDF_LOGE("%s: device is null", __func__);
477 return;
478 }
479
480 manager = (struct DacManager *)device->service;
481 if (manager == NULL) {
482 HDF_LOGI("%s: no service bind", __func__);
483 return;
484 }
485
486 g_dacManager = NULL;
487 OsalMemFree(manager);
488 }
489
490 struct HdfDriverEntry g_dacManagerEntry = {
491 .moduleVersion = 1,
492 .Bind = DacManagerBind,
493 .Init = DacManagerInit,
494 .Release = DacManagerRelease,
495 .moduleName = "HDF_PLATFORM_DAC_MANAGER",
496 };
497 HDF_INIT(g_dacManagerEntry);
498