1
2
3
4
5
6
7#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
8
9#include <linux/of_platform.h>
10
11#include <drm/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
26struct 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
38static 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
59static 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
80static 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
103static 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
114static 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
125static 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
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
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
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
172static 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
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
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
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
218static 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
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
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
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
264static 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
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
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
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
310static 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
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
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
343static 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
354static 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
382static 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
408static 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
418static 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
444static 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
467static 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
492int 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
507
508
509
510
511
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->audio_enabled = true;
531
532end:
533 return rc;
534}
535
536static void dp_audio_shutdown(struct device *dev, void *data)
537{
538 struct dp_audio_private *audio;
539 struct platform_device *pdev;
540 struct msm_dp *dp_display;
541
542 pdev = to_platform_device(dev);
543 dp_display = platform_get_drvdata(pdev);
544 audio = dp_audio_get_data(pdev);
545 if (IS_ERR(audio)) {
546 DRM_ERROR("failed to get audio data\n");
547 return;
548 }
549
550
551
552
553
554
555
556
557
558 if (!dp_display->audio_enabled)
559 return;
560
561 dp_audio_enable(audio, false);
562
563 dp_display_signal_audio_complete(dp_display);
564}
565
566static const struct hdmi_codec_ops dp_audio_codec_ops = {
567 .hw_params = dp_audio_hw_params,
568 .audio_shutdown = dp_audio_shutdown,
569 .get_eld = dp_audio_get_eld,
570 .hook_plugged_cb = dp_audio_hook_plugged_cb,
571};
572
573static struct hdmi_codec_pdata codec_data = {
574 .ops = &dp_audio_codec_ops,
575 .max_i2s_channels = 8,
576 .i2s = 1,
577};
578
579int dp_register_audio_driver(struct device *dev,
580 struct dp_audio *dp_audio)
581{
582 struct dp_audio_private *audio_priv;
583
584 audio_priv = container_of(dp_audio,
585 struct dp_audio_private, dp_audio);
586
587 audio_priv->audio_pdev = platform_device_register_data(dev,
588 HDMI_CODEC_DRV_NAME,
589 PLATFORM_DEVID_AUTO,
590 &codec_data,
591 sizeof(codec_data));
592 return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
593}
594
595struct dp_audio *dp_audio_get(struct platform_device *pdev,
596 struct dp_panel *panel,
597 struct dp_catalog *catalog)
598{
599 int rc = 0;
600 struct dp_audio_private *audio;
601 struct dp_audio *dp_audio;
602
603 if (!pdev || !panel || !catalog) {
604 DRM_ERROR("invalid input\n");
605 rc = -EINVAL;
606 goto error;
607 }
608
609 audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL);
610 if (!audio) {
611 rc = -ENOMEM;
612 goto error;
613 }
614
615 audio->pdev = pdev;
616 audio->panel = panel;
617 audio->catalog = catalog;
618
619 dp_audio = &audio->dp_audio;
620
621 dp_catalog_audio_init(catalog);
622
623 return dp_audio;
624error:
625 return ERR_PTR(rc);
626}
627
628void dp_audio_put(struct dp_audio *dp_audio)
629{
630 struct dp_audio_private *audio;
631
632 if (!dp_audio)
633 return;
634
635 audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
636
637 devm_kfree(&audio->pdev->dev, audio);
638}
639