• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Institute of Software, CAS.
3  * Author : huangji@nj.iscas.ac.cn
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <linux/device.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/platform_device.h>
21 #include <linux/mfd/rk808.h>
22 #include "rk817_codec.h"
23 #include "rk809_codec_impl.h"
24 #include "audio_accessory_base.h"
25 #include "audio_codec_if.h"
26 #include "audio_codec_base.h"
27 #include "audio_driver_log.h"
28 
29 #define HDF_LOG_TAG "rk809_codec_adapter"
30 
31 struct CodecData g_rk809Data = {
32     .Init = Rk809DeviceInit,
33     .Read = RK809CodecReadReg,
34     .Write = Rk809CodecWriteReg,
35 };
36 
37 struct AudioDaiOps g_rk809DaiDeviceOps = {
38     .Startup = Rk809DaiStartup,
39     .HwParams = Rk809DaiHwParams,
40     .Trigger = Rk809NormalTrigger,
41 };
42 
43 struct DaiData g_rk809DaiData = {
44     .DaiInit = Rk809DaiDeviceInit,
45     .ops = &g_rk809DaiDeviceOps,
46 };
47 
48 static struct Rk809ChipData *g_chip;
GetCodecDevice(void)49 struct Rk809ChipData* GetCodecDevice(void)
50 {
51     return g_chip;
52 }
53 /* HdfDriverEntry */
GetServiceName(const struct HdfDeviceObject * device)54 static int32_t GetServiceName(const struct HdfDeviceObject *device)
55 {
56     const struct DeviceResourceNode *node = NULL;
57     struct DeviceResourceIface *drsOps = NULL;
58     int32_t ret;
59 
60     if (device == NULL) {
61         AUDIO_DEVICE_LOG_ERR("input HdfDeviceObject object is nullptr.");
62         return HDF_FAILURE;
63     }
64     node = device->property;
65     if (node == NULL) {
66         AUDIO_DEVICE_LOG_ERR("get drs node is nullptr.");
67         return HDF_FAILURE;
68     }
69     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
70     if (drsOps == NULL || drsOps->GetString == NULL) {
71         AUDIO_DEVICE_LOG_ERR("drsOps or drsOps getString is null!");
72         return HDF_FAILURE;
73     }
74     ret = drsOps->GetString(node, "serviceName", &g_chip->codec.drvCodecName, 0);
75     if (ret != HDF_SUCCESS) {
76         AUDIO_DEVICE_LOG_ERR("read serviceName failed.");
77         return ret;
78     }
79     return HDF_SUCCESS;
80 }
81 
82 /* HdfDriverEntry implementations */
Rk809DriverBind(struct HdfDeviceObject * device)83 static int32_t Rk809DriverBind(struct HdfDeviceObject *device)
84 {
85     struct CodecHost *codecHost;
86     if (device == NULL) {
87         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
88         return HDF_FAILURE;
89     }
90 
91     codecHost = (struct CodecHost *)OsalMemCalloc(sizeof(*codecHost));
92     if (codecHost == NULL) {
93         AUDIO_DRIVER_LOG_ERR("malloc codecHost fail!");
94         return HDF_FAILURE;
95     }
96     codecHost->device = device;
97     device->service = &codecHost->service;
98 
99     return HDF_SUCCESS;
100 }
101 
102 static void RK809ChipRelease(void);
103 
Rk809DriverInit(struct HdfDeviceObject * device)104 static int32_t Rk809DriverInit(struct HdfDeviceObject *device)
105 {
106     int32_t ret;
107     struct regmap_config codecRegmapCfg = getCodecRegmap();
108     struct platform_device *codeDev = GetCodecPlatformDevice();
109     struct rk808 *rk808;
110     if (!codeDev) {
111         AUDIO_DEVICE_LOG_ERR("codeDev not ready");
112         return HDF_FAILURE;
113     }
114     g_chip = devm_kzalloc(&codeDev->dev, sizeof(struct Rk809ChipData), GFP_KERNEL);
115     if (!g_chip) {
116         return HDF_ERR_MALLOC_FAIL;
117     }
118     g_chip->codec = g_rk809Data;
119     g_chip->dai = g_rk809DaiData;
120     platform_set_drvdata(codeDev, g_chip);
121     g_chip->pdev = codeDev;
122     rk808 = dev_get_drvdata(g_chip->pdev->dev.parent);
123     if (!rk808) {
124         RK809ChipRelease();
125         return HDF_FAILURE;
126     }
127     g_chip->regmap = devm_regmap_init_i2c(rk808->i2c, &codecRegmapCfg);
128     if (IS_ERR(g_chip->regmap)) {
129         AUDIO_DEVICE_LOG_ERR("failed to allocate regmap: %ld\n", PTR_ERR(g_chip->regmap));
130         RK809ChipRelease();
131         return ret;
132     }
133     ret = CodecGetConfigInfo(device, &(g_chip->codec));
134     if (ret !=  HDF_SUCCESS) {
135         RK809ChipRelease();
136         return ret;
137     }
138     if (CodecSetConfigInfo(&(g_chip->codec),  &(g_chip->dai)) != HDF_SUCCESS) {
139         return HDF_FAILURE;
140     }
141     ret = GetServiceName(device);
142     if (ret !=  HDF_SUCCESS) {
143         RK809ChipRelease();
144         return ret;
145     }
146     ret = CodecGetDaiName(device,  &(g_chip->dai.drvDaiName));
147     if (ret != HDF_SUCCESS) {
148         return HDF_FAILURE;
149     }
150     ret = AudioRegisterCodec(device, &(g_chip->codec), &(g_chip->dai));
151     if (ret !=  HDF_SUCCESS) {
152         RK809ChipRelease();
153         return ret;
154     }
155     return HDF_SUCCESS;
156 }
157 
RK809ChipRelease(void)158 static void RK809ChipRelease(void)
159 {
160     if (g_chip) {
161         platform_set_drvdata(g_chip->pdev, NULL);
162         if (g_chip->regmap) {
163             regmap_exit(g_chip->regmap);
164         }
165         devm_kfree(&g_chip->pdev->dev, g_chip);
166     }
167     AUDIO_DEVICE_LOG_ERR("success!");
168     return;
169 }
170 
RK809DriverRelease(struct HdfDeviceObject * device)171 static void RK809DriverRelease(struct HdfDeviceObject *device)
172 {
173     struct CodecHost *codecHost;
174     if (device == NULL) {
175         AUDIO_DRIVER_LOG_ERR("device is NULL");
176         return;
177     }
178 
179     if (device->priv != NULL) {
180         OsalMemFree(device->priv);
181     }
182     codecHost = (struct CodecHost *)device->service;
183     if (codecHost == NULL) {
184         HDF_LOGE("CodecDriverRelease: codecHost is NULL");
185         return;
186     }
187     OsalMemFree(codecHost);
188 }
189 
190 /* HdfDriverEntry definitions */
191 struct HdfDriverEntry g_Rk809DriverEntry = {
192     .moduleVersion = 1,
193     .moduleName = "CODEC_RK809",
194     .Bind = Rk809DriverBind,
195     .Init = Rk809DriverInit,
196     .Release = RK809DriverRelease,
197 };
198 
199 HDF_INIT(g_Rk809DriverEntry);
200