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