1 /*
2 * Copyright (c) 2022-2023 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<math.h>
10 #include "adc/adc_core.h"
11 #include "device_resource_if.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15
16 #define HDF_LOG_TAG adc_virtual_driver
17 #define MATCH_ATTR adc_virtual
18 #define BASE_NUMBER 2
19 #define ADC_MAX_DATA_WIDTH 24
20
21 struct VirtualAdcDevice {
22 struct AdcDevice device;
23 uint32_t devNum;
24 uint32_t dataWidth;
25 uint32_t channels;
26 uint32_t maxValue;
27 };
28
VirtualAdcStart(struct AdcDevice * device)29 static int32_t VirtualAdcStart(struct AdcDevice *device)
30 {
31 struct VirtualAdcDevice *virtual = NULL;
32
33 if (device == NULL) {
34 HDF_LOGE("VirtualAdcStart: device is null!");
35 return HDF_ERR_INVALID_OBJECT;
36 }
37
38 virtual = (struct VirtualAdcDevice *)device;
39 virtual->maxValue = pow(BASE_NUMBER, virtual->dataWidth) - 1;
40
41 return HDF_SUCCESS;
42 }
43
VirtualAdcRead(struct AdcDevice * device,uint32_t channel,uint32_t * val)44 static int32_t VirtualAdcRead(struct AdcDevice *device, uint32_t channel, uint32_t *val)
45 {
46 struct VirtualAdcDevice *virtual = NULL;
47
48 if (device == NULL) {
49 HDF_LOGE("VirtualAdcRead: device is null!");
50 return HDF_ERR_INVALID_OBJECT;
51 }
52
53 virtual = (struct VirtualAdcDevice *)device;
54 if (channel >= virtual->channels || val == NULL) {
55 HDF_LOGE("VirtualAdcRead: invalid channel or val is null!");
56 return HDF_ERR_INVALID_PARAM;
57 }
58
59 *val = virtual->maxValue;
60 return HDF_SUCCESS;
61 }
62
VirtualAdcStop(struct AdcDevice * device)63 static int32_t VirtualAdcStop(struct AdcDevice *device)
64 {
65 (void)device;
66 return HDF_SUCCESS;
67 }
68
69 static const struct AdcMethod g_method = {
70 .read = VirtualAdcRead,
71 .stop = VirtualAdcStop,
72 .start = VirtualAdcStart,
73 };
74
VirtualAdcReadDrs(struct VirtualAdcDevice * virtual,const struct DeviceResourceNode * node)75 static int32_t VirtualAdcReadDrs(struct VirtualAdcDevice *virtual, const struct DeviceResourceNode *node)
76 {
77 int32_t ret;
78 struct DeviceResourceIface *drsOps = NULL;
79
80 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
81 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
82 HDF_LOGE("VirtualAdcReadDrs: invalid drs ops!");
83 return HDF_ERR_NOT_SUPPORT;
84 }
85
86 ret = drsOps->GetUint32(node, "devNum", &virtual->devNum, 0);
87 if (ret != HDF_SUCCESS) {
88 HDF_LOGE("VirtualAdcReadDrs: read devNum fail, ret: %d!", ret);
89 return ret;
90 }
91
92 ret = drsOps->GetUint32(node, "dataWidth", &virtual->dataWidth, 0);
93 if (ret != HDF_SUCCESS || virtual->dataWidth == 0 || virtual->dataWidth >= ADC_MAX_DATA_WIDTH) {
94 HDF_LOGE("VirtualAdcReadDrs: read dataWidth fail, ret: %d!", ret);
95 return ret;
96 }
97
98 ret = drsOps->GetUint32(node, "channels", &virtual->channels, 0);
99 if (ret != HDF_SUCCESS) {
100 HDF_LOGE("VirtualAdcReadDrs: read channels fail, ret: %d!", ret);
101 return ret;
102 }
103 HDF_LOGD("VirtualAdcReadDrs: success, devNum=%u, dataWidth=%u, channels=%u!",
104 virtual->devNum, virtual->dataWidth, virtual->channels);
105
106 return HDF_SUCCESS;
107 }
108
VirtualAdcInit(struct HdfDeviceObject * device)109 static int32_t VirtualAdcInit(struct HdfDeviceObject *device)
110 {
111 int32_t ret;
112 struct VirtualAdcDevice *virtual = NULL;
113
114 if (device == NULL || device->property == NULL) {
115 HDF_LOGE("VirtualAdcInit: device or property is null!");
116 return HDF_ERR_INVALID_OBJECT;
117 }
118
119 virtual = (struct VirtualAdcDevice *)OsalMemCalloc(sizeof(*virtual));
120 if (virtual == NULL) {
121 HDF_LOGE("VirtualAdcInit: alloc virtual fail!");
122 return HDF_ERR_MALLOC_FAIL;
123 }
124
125 ret = VirtualAdcReadDrs(virtual, device->property);
126 if (ret != HDF_SUCCESS) {
127 HDF_LOGE("VirtualAdcInit: read drs fail, ret: %d!", ret);
128 OsalMemFree(virtual);
129 return ret;
130 }
131
132 virtual->device.priv = (void *)device->property;
133 virtual->device.devNum = virtual->devNum;
134 virtual->device.ops = &g_method;
135 ret = AdcDeviceAdd(&virtual->device);
136 if (ret != HDF_SUCCESS) {
137 HDF_LOGE("VirtualAdcInit: add adc virtual device:%u fail, ret: %d!", virtual->devNum, ret);
138 OsalMemFree(virtual);
139 return ret;
140 }
141
142 HDF_LOGI("VirtualAdcInit: adc virtual driver init success!");
143 return ret;
144 }
145
VirtualAdcRelease(struct HdfDeviceObject * device)146 static void VirtualAdcRelease(struct HdfDeviceObject *device)
147 {
148 int32_t ret;
149 uint32_t devNum;
150 struct AdcDevice *dev = NULL;
151 struct DeviceResourceIface *drsOps = NULL;
152
153 HDF_LOGI("VirtualAdcRelease: enter!");
154 if (device == NULL || device->property == NULL) {
155 HDF_LOGE("VirtualAdcRelease: device or property is null!");
156 return;
157 }
158
159 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
160 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
161 HDF_LOGE("VirtualAdcRelease: invalid drs ops!");
162 return;
163 }
164
165 ret = drsOps->GetUint32(device->property, "devNum", (uint32_t *)&devNum, 0);
166 if (ret != HDF_SUCCESS) {
167 HDF_LOGE("VirtualAdcRelease: read devNum fail, ret: %d!", ret);
168 return;
169 }
170
171 dev = AdcDeviceGet(devNum);
172 AdcDevicePut(dev);
173 if (dev != NULL && dev->priv == device->property) {
174 AdcDeviceRemove(dev);
175 OsalMemFree(dev);
176 }
177 }
178
179 static struct HdfDriverEntry g_virtualAdcDriverEntry = {
180 .moduleVersion = 1,
181 .Init = VirtualAdcInit,
182 .Release = VirtualAdcRelease,
183 .moduleName = "virtual_adc_driver",
184 };
185 HDF_INIT(g_virtualAdcDriverEntry);
186