xref: /openbmc/linux/drivers/gpu/drm/msm/dp/dp_audio.c (revision cef69974)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
4  */
5 
6 
7 #define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
8 
9 #include <linux/of_platform.h>
10 
11 #include <drm/dp/drm_dp_helper.h>
12 #include <drm/drm_edid.h>
13 
14 #include "dp_catalog.h"
15 #include "dp_audio.h"
16 #include "dp_panel.h"
17 #include "dp_display.h"
18 
19 #define HEADER_BYTE_2_BIT	 0
20 #define PARITY_BYTE_2_BIT	 8
21 #define HEADER_BYTE_1_BIT	16
22 #define PARITY_BYTE_1_BIT	24
23 #define HEADER_BYTE_3_BIT	16
24 #define PARITY_BYTE_3_BIT	24
25 
26 struct dp_audio_private {
27 	struct platform_device *audio_pdev;
28 	struct platform_device *pdev;
29 	struct dp_catalog *catalog;
30 	struct dp_panel *panel;
31 
32 	bool engine_on;
33 	u32 channels;
34 
35 	struct dp_audio dp_audio;
36 };
37 
38 static u8 dp_audio_get_g0_value(u8 data)
39 {
40 	u8 c[4];
41 	u8 g[4];
42 	u8 ret_data = 0;
43 	u8 i;
44 
45 	for (i = 0; i < 4; i++)
46 		c[i] = (data >> i) & 0x01;
47 
48 	g[0] = c[3];
49 	g[1] = c[0] ^ c[3];
50 	g[2] = c[1];
51 	g[3] = c[2];
52 
53 	for (i = 0; i < 4; i++)
54 		ret_data = ((g[i] & 0x01) << i) | ret_data;
55 
56 	return ret_data;
57 }
58 
59 static u8 dp_audio_get_g1_value(u8 data)
60 {
61 	u8 c[4];
62 	u8 g[4];
63 	u8 ret_data = 0;
64 	u8 i;
65 
66 	for (i = 0; i < 4; i++)
67 		c[i] = (data >> i) & 0x01;
68 
69 	g[0] = c[0] ^ c[3];
70 	g[1] = c[0] ^ c[1] ^ c[3];
71 	g[2] = c[1] ^ c[2];
72 	g[3] = c[2] ^ c[3];
73 
74 	for (i = 0; i < 4; i++)
75 		ret_data = ((g[i] & 0x01) << i) | ret_data;
76 
77 	return ret_data;
78 }
79 
80 static u8 dp_audio_calculate_parity(u32 data)
81 {
82 	u8 x0 = 0;
83 	u8 x1 = 0;
84 	u8 ci = 0;
85 	u8 iData = 0;
86 	u8 i = 0;
87 	u8 parity_byte;
88 	u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
89 
90 	for (i = 0; i < num_byte; i++) {
91 		iData = (data >> i*4) & 0xF;
92 
93 		ci = iData ^ x1;
94 		x1 = x0 ^ dp_audio_get_g1_value(ci);
95 		x0 = dp_audio_get_g0_value(ci);
96 	}
97 
98 	parity_byte = x1 | (x0 << 4);
99 
100 	return parity_byte;
101 }
102 
103 static u32 dp_audio_get_header(struct dp_catalog *catalog,
104 		enum dp_catalog_audio_sdp_type sdp,
105 		enum dp_catalog_audio_header_type header)
106 {
107 	catalog->sdp_type = sdp;
108 	catalog->sdp_header = header;
109 	dp_catalog_audio_get_header(catalog);
110 
111 	return catalog->audio_data;
112 }
113 
114 static void dp_audio_set_header(struct dp_catalog *catalog,
115 		u32 data,
116 		enum dp_catalog_audio_sdp_type sdp,
117 		enum dp_catalog_audio_header_type header)
118 {
119 	catalog->sdp_type = sdp;
120 	catalog->sdp_header = header;
121 	catalog->audio_data = data;
122 	dp_catalog_audio_set_header(catalog);
123 }
124 
125 static void dp_audio_stream_sdp(struct dp_audio_private *audio)
126 {
127 	struct dp_catalog *catalog = audio->catalog;
128 	u32 value, new_value;
129 	u8 parity_byte;
130 
131 	/* Config header and parity byte 1 */
132 	value = dp_audio_get_header(catalog,
133 			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
134 
135 	new_value = 0x02;
136 	parity_byte = dp_audio_calculate_parity(new_value);
137 	value |= ((new_value << HEADER_BYTE_1_BIT)
138 			| (parity_byte << PARITY_BYTE_1_BIT));
139 	DRM_DEBUG_DP("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
140 			value, parity_byte);
141 	dp_audio_set_header(catalog, value,
142 		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
143 
144 	/* Config header and parity byte 2 */
145 	value = dp_audio_get_header(catalog,
146 			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
147 	new_value = value;
148 	parity_byte = dp_audio_calculate_parity(new_value);
149 	value |= ((new_value << HEADER_BYTE_2_BIT)
150 			| (parity_byte << PARITY_BYTE_2_BIT));
151 	DRM_DEBUG_DP("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
152 			value, parity_byte);
153 
154 	dp_audio_set_header(catalog, value,
155 		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
156 
157 	/* Config header and parity byte 3 */
158 	value = dp_audio_get_header(catalog,
159 			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
160 
161 	new_value = audio->channels - 1;
162 	parity_byte = dp_audio_calculate_parity(new_value);
163 	value |= ((new_value << HEADER_BYTE_3_BIT)
164 			| (parity_byte << PARITY_BYTE_3_BIT));
165 	DRM_DEBUG_DP("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
166 		value, parity_byte);
167 
168 	dp_audio_set_header(catalog, value,
169 		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
170 }
171 
172 static void dp_audio_timestamp_sdp(struct dp_audio_private *audio)
173 {
174 	struct dp_catalog *catalog = audio->catalog;
175 	u32 value, new_value;
176 	u8 parity_byte;
177 
178 	/* Config header and parity byte 1 */
179 	value = dp_audio_get_header(catalog,
180 			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
181 
182 	new_value = 0x1;
183 	parity_byte = dp_audio_calculate_parity(new_value);
184 	value |= ((new_value << HEADER_BYTE_1_BIT)
185 			| (parity_byte << PARITY_BYTE_1_BIT));
186 	DRM_DEBUG_DP("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
187 		value, parity_byte);
188 	dp_audio_set_header(catalog, value,
189 		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
190 
191 	/* Config header and parity byte 2 */
192 	value = dp_audio_get_header(catalog,
193 			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
194 
195 	new_value = 0x17;
196 	parity_byte = dp_audio_calculate_parity(new_value);
197 	value |= ((new_value << HEADER_BYTE_2_BIT)
198 			| (parity_byte << PARITY_BYTE_2_BIT));
199 	DRM_DEBUG_DP("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
200 			value, parity_byte);
201 	dp_audio_set_header(catalog, value,
202 		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
203 
204 	/* Config header and parity byte 3 */
205 	value = dp_audio_get_header(catalog,
206 			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
207 
208 	new_value = (0x0 | (0x11 << 2));
209 	parity_byte = dp_audio_calculate_parity(new_value);
210 	value |= ((new_value << HEADER_BYTE_3_BIT)
211 			| (parity_byte << PARITY_BYTE_3_BIT));
212 	DRM_DEBUG_DP("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
213 			value, parity_byte);
214 	dp_audio_set_header(catalog, value,
215 		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
216 }
217 
218 static void dp_audio_infoframe_sdp(struct dp_audio_private *audio)
219 {
220 	struct dp_catalog *catalog = audio->catalog;
221 	u32 value, new_value;
222 	u8 parity_byte;
223 
224 	/* Config header and parity byte 1 */
225 	value = dp_audio_get_header(catalog,
226 			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
227 
228 	new_value = 0x84;
229 	parity_byte = dp_audio_calculate_parity(new_value);
230 	value |= ((new_value << HEADER_BYTE_1_BIT)
231 			| (parity_byte << PARITY_BYTE_1_BIT));
232 	DRM_DEBUG_DP("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
233 			value, parity_byte);
234 	dp_audio_set_header(catalog, value,
235 		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
236 
237 	/* Config header and parity byte 2 */
238 	value = dp_audio_get_header(catalog,
239 			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
240 
241 	new_value = 0x1b;
242 	parity_byte = dp_audio_calculate_parity(new_value);
243 	value |= ((new_value << HEADER_BYTE_2_BIT)
244 			| (parity_byte << PARITY_BYTE_2_BIT));
245 	DRM_DEBUG_DP("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
246 			value, parity_byte);
247 	dp_audio_set_header(catalog, value,
248 		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
249 
250 	/* Config header and parity byte 3 */
251 	value = dp_audio_get_header(catalog,
252 			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
253 
254 	new_value = (0x0 | (0x11 << 2));
255 	parity_byte = dp_audio_calculate_parity(new_value);
256 	value |= ((new_value << HEADER_BYTE_3_BIT)
257 			| (parity_byte << PARITY_BYTE_3_BIT));
258 	DRM_DEBUG_DP("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
259 			new_value, parity_byte);
260 	dp_audio_set_header(catalog, value,
261 		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
262 }
263 
264 static void dp_audio_copy_management_sdp(struct dp_audio_private *audio)
265 {
266 	struct dp_catalog *catalog = audio->catalog;
267 	u32 value, new_value;
268 	u8 parity_byte;
269 
270 	/* Config header and parity byte 1 */
271 	value = dp_audio_get_header(catalog,
272 			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
273 
274 	new_value = 0x05;
275 	parity_byte = dp_audio_calculate_parity(new_value);
276 	value |= ((new_value << HEADER_BYTE_1_BIT)
277 			| (parity_byte << PARITY_BYTE_1_BIT));
278 	DRM_DEBUG_DP("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
279 			value, parity_byte);
280 	dp_audio_set_header(catalog, value,
281 		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
282 
283 	/* Config header and parity byte 2 */
284 	value = dp_audio_get_header(catalog,
285 			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
286 
287 	new_value = 0x0F;
288 	parity_byte = dp_audio_calculate_parity(new_value);
289 	value |= ((new_value << HEADER_BYTE_2_BIT)
290 			| (parity_byte << PARITY_BYTE_2_BIT));
291 	DRM_DEBUG_DP("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
292 			value, parity_byte);
293 	dp_audio_set_header(catalog, value,
294 		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
295 
296 	/* Config header and parity byte 3 */
297 	value = dp_audio_get_header(catalog,
298 			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
299 
300 	new_value = 0x0;
301 	parity_byte = dp_audio_calculate_parity(new_value);
302 	value |= ((new_value << HEADER_BYTE_3_BIT)
303 			| (parity_byte << PARITY_BYTE_3_BIT));
304 	DRM_DEBUG_DP("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
305 			value, parity_byte);
306 	dp_audio_set_header(catalog, value,
307 		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
308 }
309 
310 static void dp_audio_isrc_sdp(struct dp_audio_private *audio)
311 {
312 	struct dp_catalog *catalog = audio->catalog;
313 	u32 value, new_value;
314 	u8 parity_byte;
315 
316 	/* Config header and parity byte 1 */
317 	value = dp_audio_get_header(catalog,
318 			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
319 
320 	new_value = 0x06;
321 	parity_byte = dp_audio_calculate_parity(new_value);
322 	value |= ((new_value << HEADER_BYTE_1_BIT)
323 			| (parity_byte << PARITY_BYTE_1_BIT));
324 	DRM_DEBUG_DP("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
325 			value, parity_byte);
326 	dp_audio_set_header(catalog, value,
327 		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
328 
329 	/* Config header and parity byte 2 */
330 	value = dp_audio_get_header(catalog,
331 			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
332 
333 	new_value = 0x0F;
334 	parity_byte = dp_audio_calculate_parity(new_value);
335 	value |= ((new_value << HEADER_BYTE_2_BIT)
336 			| (parity_byte << PARITY_BYTE_2_BIT));
337 	DRM_DEBUG_DP("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
338 			value, parity_byte);
339 	dp_audio_set_header(catalog, value,
340 		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
341 }
342 
343 static void dp_audio_setup_sdp(struct dp_audio_private *audio)
344 {
345 	dp_catalog_audio_config_sdp(audio->catalog);
346 
347 	dp_audio_stream_sdp(audio);
348 	dp_audio_timestamp_sdp(audio);
349 	dp_audio_infoframe_sdp(audio);
350 	dp_audio_copy_management_sdp(audio);
351 	dp_audio_isrc_sdp(audio);
352 }
353 
354 static void dp_audio_setup_acr(struct dp_audio_private *audio)
355 {
356 	u32 select = 0;
357 	struct dp_catalog *catalog = audio->catalog;
358 
359 	switch (audio->dp_audio.bw_code) {
360 	case DP_LINK_BW_1_62:
361 		select = 0;
362 		break;
363 	case DP_LINK_BW_2_7:
364 		select = 1;
365 		break;
366 	case DP_LINK_BW_5_4:
367 		select = 2;
368 		break;
369 	case DP_LINK_BW_8_1:
370 		select = 3;
371 		break;
372 	default:
373 		DRM_DEBUG_DP("Unknown link rate\n");
374 		select = 0;
375 		break;
376 	}
377 
378 	catalog->audio_data = select;
379 	dp_catalog_audio_config_acr(catalog);
380 }
381 
382 static void dp_audio_safe_to_exit_level(struct dp_audio_private *audio)
383 {
384 	struct dp_catalog *catalog = audio->catalog;
385 	u32 safe_to_exit_level = 0;
386 
387 	switch (audio->dp_audio.lane_count) {
388 	case 1:
389 		safe_to_exit_level = 14;
390 		break;
391 	case 2:
392 		safe_to_exit_level = 8;
393 		break;
394 	case 4:
395 		safe_to_exit_level = 5;
396 		break;
397 	default:
398 		DRM_DEBUG_DP("setting the default safe_to_exit_level = %u\n",
399 				safe_to_exit_level);
400 		safe_to_exit_level = 14;
401 		break;
402 	}
403 
404 	catalog->audio_data = safe_to_exit_level;
405 	dp_catalog_audio_sfe_level(catalog);
406 }
407 
408 static void dp_audio_enable(struct dp_audio_private *audio, bool enable)
409 {
410 	struct dp_catalog *catalog = audio->catalog;
411 
412 	catalog->audio_data = enable;
413 	dp_catalog_audio_enable(catalog);
414 
415 	audio->engine_on = enable;
416 }
417 
418 static struct dp_audio_private *dp_audio_get_data(struct platform_device *pdev)
419 {
420 	struct dp_audio *dp_audio;
421 	struct msm_dp *dp_display;
422 
423 	if (!pdev) {
424 		DRM_ERROR("invalid input\n");
425 		return ERR_PTR(-ENODEV);
426 	}
427 
428 	dp_display = platform_get_drvdata(pdev);
429 	if (!dp_display) {
430 		DRM_ERROR("invalid input\n");
431 		return ERR_PTR(-ENODEV);
432 	}
433 
434 	dp_audio = dp_display->dp_audio;
435 
436 	if (!dp_audio) {
437 		DRM_ERROR("invalid dp_audio data\n");
438 		return ERR_PTR(-EINVAL);
439 	}
440 
441 	return container_of(dp_audio, struct dp_audio_private, dp_audio);
442 }
443 
444 static int dp_audio_hook_plugged_cb(struct device *dev, void *data,
445 		hdmi_codec_plugged_cb fn,
446 		struct device *codec_dev)
447 {
448 
449 	struct platform_device *pdev;
450 	struct msm_dp *dp_display;
451 
452 	pdev = to_platform_device(dev);
453 	if (!pdev) {
454 		pr_err("invalid input\n");
455 		return -ENODEV;
456 	}
457 
458 	dp_display = platform_get_drvdata(pdev);
459 	if (!dp_display) {
460 		pr_err("invalid input\n");
461 		return -ENODEV;
462 	}
463 
464 	return dp_display_set_plugged_cb(dp_display, fn, codec_dev);
465 }
466 
467 static int dp_audio_get_eld(struct device *dev,
468 	void *data, uint8_t *buf, size_t len)
469 {
470 	struct platform_device *pdev;
471 	struct msm_dp *dp_display;
472 
473 	pdev = to_platform_device(dev);
474 
475 	if (!pdev) {
476 		DRM_ERROR("invalid input\n");
477 		return -ENODEV;
478 	}
479 
480 	dp_display = platform_get_drvdata(pdev);
481 	if (!dp_display) {
482 		DRM_ERROR("invalid input\n");
483 		return -ENODEV;
484 	}
485 
486 	memcpy(buf, dp_display->connector->eld,
487 		min(sizeof(dp_display->connector->eld), len));
488 
489 	return 0;
490 }
491 
492 int dp_audio_hw_params(struct device *dev,
493 	void *data,
494 	struct hdmi_codec_daifmt *daifmt,
495 	struct hdmi_codec_params *params)
496 {
497 	int rc = 0;
498 	struct dp_audio_private *audio;
499 	struct platform_device *pdev;
500 	struct msm_dp *dp_display;
501 
502 	pdev = to_platform_device(dev);
503 	dp_display = platform_get_drvdata(pdev);
504 
505 	/*
506 	 * there could be cases where sound card can be opened even
507 	 * before OR even when DP is not connected . This can cause
508 	 * unclocked access as the audio subsystem relies on the DP
509 	 * driver to maintain the correct state of clocks. To protect
510 	 * such cases check for connection status and bail out if not
511 	 * connected.
512 	 */
513 	if (!dp_display->power_on) {
514 		rc = -EINVAL;
515 		goto end;
516 	}
517 
518 	audio = dp_audio_get_data(pdev);
519 	if (IS_ERR(audio)) {
520 		rc = PTR_ERR(audio);
521 		goto end;
522 	}
523 
524 	audio->channels = params->channels;
525 
526 	dp_audio_setup_sdp(audio);
527 	dp_audio_setup_acr(audio);
528 	dp_audio_safe_to_exit_level(audio);
529 	dp_audio_enable(audio, true);
530 	dp_display_signal_audio_start(dp_display);
531 	dp_display->audio_enabled = true;
532 
533 end:
534 	return rc;
535 }
536 
537 static void dp_audio_shutdown(struct device *dev, void *data)
538 {
539 	struct dp_audio_private *audio;
540 	struct platform_device *pdev;
541 	struct msm_dp *dp_display;
542 
543 	pdev = to_platform_device(dev);
544 	dp_display = platform_get_drvdata(pdev);
545 	audio = dp_audio_get_data(pdev);
546 	if (IS_ERR(audio)) {
547 		DRM_ERROR("failed to get audio data\n");
548 		return;
549 	}
550 
551 	/*
552 	 * if audio was not enabled there is no need
553 	 * to execute the shutdown and we can bail out early.
554 	 * This also makes sure that we dont cause an unclocked
555 	 * access when audio subsystem calls this without DP being
556 	 * connected. is_connected cannot be used here as its set
557 	 * to false earlier than this call
558 	 */
559 	if (!dp_display->audio_enabled)
560 		return;
561 
562 	dp_audio_enable(audio, false);
563 	/* signal the dp display to safely shutdown clocks */
564 	dp_display_signal_audio_complete(dp_display);
565 }
566 
567 static const struct hdmi_codec_ops dp_audio_codec_ops = {
568 	.hw_params = dp_audio_hw_params,
569 	.audio_shutdown = dp_audio_shutdown,
570 	.get_eld = dp_audio_get_eld,
571 	.hook_plugged_cb = dp_audio_hook_plugged_cb,
572 };
573 
574 static struct hdmi_codec_pdata codec_data = {
575 	.ops = &dp_audio_codec_ops,
576 	.max_i2s_channels = 8,
577 	.i2s = 1,
578 };
579 
580 int dp_register_audio_driver(struct device *dev,
581 		struct dp_audio *dp_audio)
582 {
583 	struct dp_audio_private *audio_priv;
584 
585 	audio_priv = container_of(dp_audio,
586 			struct dp_audio_private, dp_audio);
587 
588 	audio_priv->audio_pdev = platform_device_register_data(dev,
589 						HDMI_CODEC_DRV_NAME,
590 						PLATFORM_DEVID_AUTO,
591 						&codec_data,
592 						sizeof(codec_data));
593 	return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
594 }
595 
596 struct dp_audio *dp_audio_get(struct platform_device *pdev,
597 			struct dp_panel *panel,
598 			struct dp_catalog *catalog)
599 {
600 	int rc = 0;
601 	struct dp_audio_private *audio;
602 	struct dp_audio *dp_audio;
603 
604 	if (!pdev || !panel || !catalog) {
605 		DRM_ERROR("invalid input\n");
606 		rc = -EINVAL;
607 		goto error;
608 	}
609 
610 	audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL);
611 	if (!audio) {
612 		rc = -ENOMEM;
613 		goto error;
614 	}
615 
616 	audio->pdev = pdev;
617 	audio->panel = panel;
618 	audio->catalog = catalog;
619 
620 	dp_audio = &audio->dp_audio;
621 
622 	dp_catalog_audio_init(catalog);
623 
624 	return dp_audio;
625 error:
626 	return ERR_PTR(rc);
627 }
628 
629 void dp_audio_put(struct dp_audio *dp_audio)
630 {
631 	struct dp_audio_private *audio;
632 
633 	if (!dp_audio)
634 		return;
635 
636 	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
637 
638 	devm_kfree(&audio->pdev->dev, audio);
639 }
640