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 < 0 || 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 < 0 || number >= ADC_DEVICES_MAX || reply == NULL) {
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 if (data == NULL) {
347 HDF_LOGE("%s: invalid data!", __func__);
348 return HDF_ERR_INVALID_PARAM;
349 }
350
351 if (!HdfSbufReadUint32(data, &number)) {
352 HDF_LOGE("%s: read data failed!", __func__);
353 return HDF_ERR_IO;
354 }
355
356 number = (uint32_t)(number - ADC_HANDLE_SHIFT);
357 if (number < 0 || number >= ADC_DEVICES_MAX) {
358 HDF_LOGE("%s: get device %u failed", __func__, number);
359 return HDF_ERR_INVALID_PARAM;
360 }
361
362 AdcDeviceClose(AdcManagerFindDevice(number));
363 return HDF_SUCCESS;
364 }
365
AdcManagerIoRead(struct HdfSBuf * data,struct HdfSBuf * reply)366 static int32_t AdcManagerIoRead(struct HdfSBuf *data, struct HdfSBuf *reply)
367 {
368 int32_t ret;
369 uint32_t number;
370 uint32_t channel;
371 uint32_t val;
372
373 if (data == NULL || reply == NULL) {
374 HDF_LOGE("%s: invalid data or reply!", __func__);
375 return HDF_ERR_INVALID_PARAM;
376 }
377
378 if (!HdfSbufReadUint32(data, &number)) {
379 HDF_LOGE("AdcManagerIoRead: read handle failed!");
380 return HDF_ERR_IO;
381 }
382
383 if (!HdfSbufReadUint32(data, &channel)) {
384 HDF_LOGE("AdcManagerIoRead: read handle failed!");
385 return HDF_ERR_IO;
386 }
387
388 number = (uint32_t)(number - ADC_HANDLE_SHIFT);
389 ret = AdcDeviceRead(AdcManagerFindDevice(number), channel, &val);
390 if (ret != HDF_SUCCESS) {
391 HDF_LOGE("AdcManagerIoRead: read val failed!");
392 return HDF_ERR_IO;
393 }
394
395 if (!HdfSbufWriteUint32(reply, val)) {
396 HDF_LOGE("%s: write val fail!", __func__);
397 return HDF_ERR_IO;
398 }
399
400 return ret;
401 }
402
AdcManagerDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)403 static int32_t AdcManagerDispatch(struct HdfDeviceIoClient *client, int cmd,
404 struct HdfSBuf *data, struct HdfSBuf *reply)
405 {
406 switch (cmd) {
407 case ADC_IO_OPEN:
408 return AdcManagerIoOpen(data, reply);
409 case ADC_IO_CLOSE:
410 return AdcManagerIoClose(data, reply);
411 case ADC_IO_READ:
412 return AdcManagerIoRead(data, reply);
413 default:
414 return HDF_ERR_NOT_SUPPORT;
415 }
416 return HDF_SUCCESS;
417 }
418
AdcManagerBind(struct HdfDeviceObject * device)419 static int32_t AdcManagerBind(struct HdfDeviceObject *device)
420 {
421 (void)device;
422 return HDF_SUCCESS;
423 }
424
AdcManagerInit(struct HdfDeviceObject * device)425 static int32_t AdcManagerInit(struct HdfDeviceObject *device)
426 {
427 int32_t ret;
428 struct AdcManager *manager = NULL;
429
430 HDF_LOGI("%s: Enter", __func__);
431 if (device == NULL) {
432 HDF_LOGE("%s: device is null", __func__);
433 return HDF_ERR_INVALID_OBJECT;
434 }
435
436 manager = (struct AdcManager *)OsalMemCalloc(sizeof(*manager));
437 if (manager == NULL) {
438 HDF_LOGE("%s: alloc manager failed", __func__);
439 return HDF_ERR_MALLOC_FAIL;
440 }
441
442 ret = OsalSpinInit(&manager->spin);
443 if (ret != HDF_SUCCESS) {
444 HDF_LOGE("%s: spinlock init failed", __func__);
445 OsalMemFree(manager);
446 return HDF_FAILURE;
447 }
448
449 manager->device = device;
450 g_adcManager = manager;
451 device->service = &manager->service;
452 device->service->Dispatch = AdcManagerDispatch;
453 return HDF_SUCCESS;
454 }
455
AdcManagerRelease(struct HdfDeviceObject * device)456 static void AdcManagerRelease(struct HdfDeviceObject *device)
457 {
458 struct AdcManager *manager = NULL;
459
460 HDF_LOGI("%s: Enter", __func__);
461 if (device == NULL) {
462 HDF_LOGE("%s: device is null", __func__);
463 return;
464 }
465
466 manager = (struct AdcManager *)device->service;
467 if (manager == NULL) {
468 HDF_LOGI("%s: no service bind", __func__);
469 return;
470 }
471
472 g_adcManager = NULL;
473 OsalMemFree(manager);
474 }
475
476 struct HdfDriverEntry g_adcManagerEntry = {
477 .moduleVersion = 1,
478 .Bind = AdcManagerBind,
479 .Init = AdcManagerInit,
480 .Release = AdcManagerRelease,
481 .moduleName = "HDF_PLATFORM_ADC_MANAGER",
482 };
483 HDF_INIT(g_adcManagerEntry);
484