1 /*
2 * Copyright (C) 2022 HiHope Open Source Organization .
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 <linux/slab.h>
10 #include "gpio_if.h"
11 #include "audio_core.h"
12 #include "audio_platform_base.h"
13 #include "audio_dma_base.h"
14 #include "rk3568_dma_ops.h"
15 #include "osal_io.h"
16 #include "osal_mem.h"
17 #include "audio_driver_log.h"
18
19 #define HDF_LOG_TAG rk3568_platform_adapter
20
21 struct AudioDmaOps g_dmaDeviceOps = {
22 .DmaBufAlloc = Rk3568DmaBufAlloc,
23 .DmaBufFree = Rk3568DmaBufFree,
24 .DmaRequestChannel = Rk3568DmaRequestChannel,
25 .DmaConfigChannel = Rk3568DmaConfigChannel,
26 .DmaPrep = Rk3568DmaPrep,
27 .DmaSubmit = Rk3568DmaSubmit,
28 .DmaPending = Rk3568DmaPending,
29 .DmaPause = Rk3568DmaPause,
30 .DmaResume = Rk3568DmaResume,
31 .DmaPointer = Rk3568PcmPointer,
32 };
33
34 /* HdfDriverEntry implementations */
PlatformDriverBind(struct HdfDeviceObject * device)35 static int32_t PlatformDriverBind(struct HdfDeviceObject *device)
36 {
37 struct PlatformHost *platformHost = NULL;
38
39 if (device == NULL) {
40 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
41 return HDF_FAILURE;
42 }
43
44 platformHost = (struct PlatformHost *)OsalMemCalloc(sizeof(*platformHost));
45 if (platformHost == NULL) {
46 AUDIO_DEVICE_LOG_ERR("malloc host fail!");
47 return HDF_FAILURE;
48 }
49
50 platformHost->device = device;
51 device->service = &platformHost->service;
52
53 AUDIO_DEVICE_LOG_DEBUG("success!");
54 return HDF_SUCCESS;
55 }
56
PlatformGetServiceName(const struct HdfDeviceObject * device,struct PlatformData * platformData)57 static int32_t PlatformGetServiceName(const struct HdfDeviceObject *device, struct PlatformData *platformData)
58 {
59 const struct DeviceResourceNode *node = NULL;
60 struct DeviceResourceIface *drsOps = NULL;
61 int32_t ret;
62
63 if (device == NULL || platformData == NULL) {
64 AUDIO_DEVICE_LOG_ERR("para is NULL.");
65 return HDF_FAILURE;
66 }
67
68 node = device->property;
69 if (node == NULL) {
70 AUDIO_DEVICE_LOG_ERR("node is NULL.");
71 return HDF_FAILURE;
72 }
73
74 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
75 if (drsOps == NULL || drsOps->GetString == NULL) {
76 AUDIO_DEVICE_LOG_ERR("get drsops object instance fail!");
77 return HDF_FAILURE;
78 }
79
80 ret = drsOps->GetString(node, "serviceName", &platformData->drvPlatformName, 0);
81 if (ret != HDF_SUCCESS) {
82 AUDIO_DEVICE_LOG_ERR("read serviceName fail!");
83 return ret;
84 }
85 AUDIO_DEVICE_LOG_DEBUG("success!");
86
87 return HDF_SUCCESS;
88 }
89
PlatformDriverInit(struct HdfDeviceObject * device)90 static int32_t PlatformDriverInit(struct HdfDeviceObject *device)
91 {
92 int32_t ret;
93 struct PlatformData *platformData = NULL;
94 struct PlatformHost *platformHost = NULL;
95
96 if (device == NULL) {
97 AUDIO_DEVICE_LOG_ERR("device is NULL.");
98 return HDF_ERR_INVALID_OBJECT;
99 }
100 platformHost = (struct PlatformHost *)device->service;
101 if (platformHost == NULL) {
102 AUDIO_DEVICE_LOG_ERR("platformHost is NULL");
103 return HDF_FAILURE;
104 }
105
106 platformData = (struct PlatformData *)OsalMemCalloc(sizeof(*platformData));
107 if (platformData == NULL) {
108 AUDIO_DEVICE_LOG_ERR("malloc PlatformData fail!");
109 return HDF_FAILURE;
110 }
111
112 ret = PlatformGetServiceName(device, platformData);
113 if (ret != HDF_SUCCESS) {
114 OsalMemFree(platformData);
115 return ret;
116 }
117
118 platformData->PlatformInit = AudioDmaDeviceInit;
119 platformData->ops = &g_dmaDeviceOps;
120 if (AudioDmaGetConfigInfo(device, platformData) != HDF_SUCCESS) {
121 OsalMemFree(platformData);
122 return HDF_FAILURE;
123 }
124
125 OsalMutexInit(&platformData->renderBufInfo.buffMutex);
126 OsalMutexInit(&platformData->captureBufInfo.buffMutex);
127 ret = AudioSocRegisterPlatform(device, platformData);
128 if (ret != HDF_SUCCESS) {
129 OsalMemFree(platformData);
130 return ret;
131 }
132
133 platformHost->priv = platformData;
134 AUDIO_DEVICE_LOG_DEBUG("success.\n");
135 return HDF_SUCCESS;
136 }
137
PlatformDriverRelease(struct HdfDeviceObject * device)138 static void PlatformDriverRelease(struct HdfDeviceObject *device)
139 {
140 struct PlatformData *platformData = NULL;
141 struct PlatformHost *platformHost = NULL;
142 if (device == NULL) {
143 AUDIO_DEVICE_LOG_ERR("device is NULL");
144 return;
145 }
146
147 platformHost = (struct PlatformHost *)device->service;
148 if (platformHost == NULL) {
149 AUDIO_DEVICE_LOG_ERR("platformHost is NULL");
150 return;
151 }
152
153 platformData = (struct PlatformData *)platformHost->priv;
154 if (platformData != NULL) {
155 OsalMutexDestroy(&platformData->renderBufInfo.buffMutex);
156 OsalMutexDestroy(&platformData->captureBufInfo.buffMutex);
157 OsalMemFree(platformData);
158 }
159
160 OsalMemFree(platformHost);
161 AUDIO_DEVICE_LOG_DEBUG("success.\n");
162 return;
163 }
164
165 /* HdfDriverEntry definitions */
166 struct HdfDriverEntry g_platformDriverEntry = {
167 .moduleVersion = 1,
168 .moduleName = "DMA_RK3568",
169 .Bind = PlatformDriverBind,
170 .Init = PlatformDriverInit,
171 .Release = PlatformDriverRelease,
172 };
173 HDF_INIT(g_platformDriverEntry);
174