• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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