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