• 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(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