hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/sound/soc/codecs/hdmi-codec.c
....@@ -1,20 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ALSA SoC codec for HDMI encoder drivers
3
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
4
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
45 * Author: Jyri Sarha <jsarha@ti.com>
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * version 2 as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but
11
- * WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * General Public License for more details.
146 */
157 #include <linux/module.h>
168 #include <linux/string.h>
17
-#include <linux/extcon-provider.h>
189 #include <sound/core.h>
1910 #include <sound/jack.h>
2011 #include <sound/pcm.h>
....@@ -31,7 +22,6 @@
3122
3223 struct hdmi_codec_channel_map_table {
3324 unsigned char map; /* ALSA API channel map position */
34
- unsigned long spk_mask; /* speaker position bit mask */
3525 };
3626
3727 /*
....@@ -278,24 +268,18 @@
278268 .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
279269 };
280270
281
-static const unsigned int hdmi_extcon_cable[] = {
282
- EXTCON_DISP_HDMI_AUDIO,
283
- EXTCON_NONE,
284
-};
285
-
286271 struct hdmi_codec_priv {
287272 struct hdmi_codec_pdata hcd;
288
- struct snd_soc_dai_driver *daidrv;
289
- struct hdmi_codec_daifmt daifmt[2];
290
- struct mutex current_stream_lock;
291
- struct snd_pcm_substream *current_stream;
292273 uint8_t eld[MAX_ELD_BYTES];
293274 struct snd_pcm_chmap *chmap_info;
294275 unsigned int chmap_idx;
295
- unsigned int mode;
276
+ struct mutex lock;
277
+ bool busy;
278
+ bool eld_bypass;
296279 struct snd_soc_jack *jack;
297
- struct extcon_dev *edev;
298280 unsigned int jack_status;
281
+ u8 iec_status[24];
282
+ struct snd_pcm_substream *substream;
299283 };
300284
301285 static const struct snd_soc_dapm_widget hdmi_widgets[] = {
....@@ -312,7 +296,7 @@
312296 struct snd_ctl_elem_info *uinfo)
313297 {
314298 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
315
- uinfo->count = FIELD_SIZEOF(struct hdmi_codec_priv, eld);
299
+ uinfo->count = sizeof_field(struct hdmi_codec_priv, eld);
316300
317301 return 0;
318302 }
....@@ -325,36 +309,6 @@
325309
326310 memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld));
327311
328
- return 0;
329
-}
330
-
331
-static int hdmi_audio_mode_info(struct snd_kcontrol *kcontrol,
332
- struct snd_ctl_elem_info *uinfo)
333
-{
334
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
335
- uinfo->count = 1;
336
- uinfo->value.integer.min = 0;
337
- uinfo->value.integer.max = HBR;
338
- return 0;
339
-}
340
-
341
-static int hdmi_audio_mode_get(struct snd_kcontrol *kcontrol,
342
- struct snd_ctl_elem_value *ucontrol)
343
-{
344
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
345
- struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
346
-
347
- ucontrol->value.integer.value[0] = hcp->mode;
348
- return 0;
349
-}
350
-
351
-static int hdmi_audio_mode_put(struct snd_kcontrol *kcontrol,
352
- struct snd_ctl_elem_value *ucontrol)
353
-{
354
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
355
- struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
356
-
357
- hcp->mode = ucontrol->value.integer.value[0];
358312 return 0;
359313 }
360314
....@@ -398,6 +352,9 @@
398352 unsigned long spk_mask;
399353 const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
400354
355
+ if (hcp->eld_bypass)
356
+ return 0;
357
+
401358 spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
402359 spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
403360
....@@ -434,22 +391,70 @@
434391 return 0;
435392 }
436393
437
-static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
438
- struct snd_soc_dai *dai)
394
+static int hdmi_codec_iec958_info(struct snd_kcontrol *kcontrol,
395
+ struct snd_ctl_elem_info *uinfo)
439396 {
440
- struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
441
- int ret = 0;
397
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
398
+ uinfo->count = 1;
399
+ return 0;
400
+}
442401
443
- mutex_lock(&hcp->current_stream_lock);
444
- if (!hcp->current_stream) {
445
- hcp->current_stream = substream;
446
- } else if (hcp->current_stream != substream) {
447
- dev_err(dai->dev, "Only one simultaneous stream supported!\n");
448
- ret = -EINVAL;
449
- }
450
- mutex_unlock(&hcp->current_stream_lock);
402
+static int hdmi_codec_iec958_default_get(struct snd_kcontrol *kcontrol,
403
+ struct snd_ctl_elem_value *ucontrol)
404
+{
405
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
406
+ struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
451407
452
- return ret;
408
+ memcpy(ucontrol->value.iec958.status, hcp->iec_status,
409
+ sizeof(hcp->iec_status));
410
+
411
+ return 0;
412
+}
413
+
414
+static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
415
+ struct snd_ctl_elem_value *ucontrol)
416
+{
417
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
418
+ struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
419
+
420
+ memcpy(hcp->iec_status, ucontrol->value.iec958.status,
421
+ sizeof(hcp->iec_status));
422
+
423
+ return 0;
424
+}
425
+
426
+static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
427
+ struct snd_ctl_elem_value *ucontrol)
428
+{
429
+ memset(ucontrol->value.iec958.status, 0xff,
430
+ sizeof_field(struct hdmi_codec_priv, iec_status));
431
+
432
+ return 0;
433
+}
434
+
435
+static int hdmi_codec_eld_bypass_get(struct snd_kcontrol *kcontrol,
436
+ struct snd_ctl_elem_value *ucontrol)
437
+{
438
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
439
+ struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
440
+
441
+ ucontrol->value.integer.value[0] = hcp->eld_bypass;
442
+
443
+ return 0;
444
+}
445
+
446
+static int hdmi_codec_eld_bypass_put(struct snd_kcontrol *kcontrol,
447
+ struct snd_ctl_elem_value *ucontrol)
448
+{
449
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
450
+ struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
451
+
452
+ if (hcp->eld_bypass == ucontrol->value.integer.value[0])
453
+ return 0;
454
+
455
+ hcp->eld_bypass = ucontrol->value.integer.value[0];
456
+
457
+ return 1;
453458 }
454459
455460 static int hdmi_codec_startup(struct snd_pcm_substream *substream,
....@@ -459,40 +464,39 @@
459464 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
460465 int ret = 0;
461466
462
- dev_dbg(dai->dev, "%s()\n", __func__);
463
-
464
- ret = hdmi_codec_new_stream(substream, dai);
465
- if (ret)
466
- return ret;
467
+ mutex_lock(&hcp->lock);
468
+ if (hcp->busy) {
469
+ dev_err(dai->dev, "Only one simultaneous stream supported!\n");
470
+ mutex_unlock(&hcp->lock);
471
+ return -EINVAL;
472
+ }
467473
468474 if (hcp->hcd.ops->audio_startup) {
469475 ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
470
- if (ret) {
471
- mutex_lock(&hcp->current_stream_lock);
472
- hcp->current_stream = NULL;
473
- mutex_unlock(&hcp->current_stream_lock);
474
- return ret;
475
- }
476
+ if (ret)
477
+ goto err;
476478 }
477479
478
- if (tx && hcp->hcd.ops->get_eld) {
480
+ if (tx && !hcp->eld_bypass && hcp->hcd.ops->get_eld) {
479481 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
480482 hcp->eld, sizeof(hcp->eld));
483
+ if (ret)
484
+ goto err;
481485
482
- if (!ret) {
483
- ret = snd_pcm_hw_constraint_eld(substream->runtime,
484
- hcp->eld);
485
- if (ret) {
486
- mutex_lock(&hcp->current_stream_lock);
487
- hcp->current_stream = NULL;
488
- mutex_unlock(&hcp->current_stream_lock);
489
- return ret;
490
- }
491
- }
486
+ ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld);
487
+ if (ret)
488
+ goto err;
489
+
492490 /* Select chmap supported */
493491 hdmi_codec_eld_chmap(hcp);
494492 }
495
- return 0;
493
+
494
+ hcp->busy = true;
495
+ hcp->substream = substream;
496
+
497
+err:
498
+ mutex_unlock(&hcp->lock);
499
+ return ret;
496500 }
497501
498502 static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
....@@ -500,17 +504,49 @@
500504 {
501505 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
502506
503
- dev_dbg(dai->dev, "%s()\n", __func__);
504
-
505
- WARN_ON(hcp->current_stream != substream);
506
-
507507 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
508
- if (hcp->hcd.ops->audio_shutdown)
509
- hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
508
+ hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
510509
511
- mutex_lock(&hcp->current_stream_lock);
512
- hcp->current_stream = NULL;
513
- mutex_unlock(&hcp->current_stream_lock);
510
+ mutex_lock(&hcp->lock);
511
+ hcp->substream = NULL;
512
+ hcp->busy = false;
513
+ mutex_unlock(&hcp->lock);
514
+}
515
+
516
+static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai,
517
+ unsigned int sample_width,
518
+ unsigned int sample_rate,
519
+ unsigned int channels,
520
+ struct hdmi_codec_params *hp)
521
+{
522
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
523
+ int idx;
524
+
525
+ /* Select a channel allocation that matches with ELD and pcm channels */
526
+ idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels);
527
+ if (idx < 0) {
528
+ dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
529
+ idx);
530
+ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
531
+ return idx;
532
+ }
533
+
534
+ memset(hp, 0, sizeof(*hp));
535
+
536
+ hdmi_audio_infoframe_init(&hp->cea);
537
+ hp->cea.channels = channels;
538
+ hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
539
+ hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
540
+ hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
541
+ hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
542
+
543
+ hp->sample_width = sample_width;
544
+ hp->sample_rate = sample_rate;
545
+ hp->channels = channels;
546
+
547
+ hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
548
+
549
+ return 0;
514550 }
515551
516552 static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
....@@ -518,6 +554,7 @@
518554 struct snd_soc_dai *dai)
519555 {
520556 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
557
+ struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
521558 struct hdmi_codec_params hp = {
522559 .iec = {
523560 .status = { 0 },
....@@ -526,74 +563,91 @@
526563 .dig_subframe = { 0 },
527564 }
528565 };
529
- int ret, idx;
566
+ int ret;
567
+
568
+ if (!hcp->hcd.ops->hw_params)
569
+ return 0;
530570
531571 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
532572 params_width(params), params_rate(params),
533573 params_channels(params));
534574
535
- if (params_width(params) > 24)
536
- params->msbits = 24;
575
+ ret = hdmi_codec_fill_codec_params(dai,
576
+ params_width(params),
577
+ params_rate(params),
578
+ params_channels(params),
579
+ &hp);
580
+ if (ret < 0)
581
+ return ret;
537582
538
- ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
539
- sizeof(hp.iec.status));
583
+ memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
584
+ ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status,
585
+ sizeof(hp.iec.status));
540586 if (ret < 0) {
541587 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
542588 ret);
543589 return ret;
544590 }
545591
546
- ret = hdmi_codec_new_stream(substream, dai);
547
- if (ret)
548
- return ret;
549
-
550
- hdmi_audio_infoframe_init(&hp.cea);
551
- hp.cea.channels = params_channels(params);
552
- hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
553
- hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
554
- hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
555
-
556
- /* Select a channel allocation that matches with ELD and pcm channels */
557
- idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
558
- if (idx < 0) {
559
- dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
560
- idx);
561
- hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
562
- return idx;
563
- }
564
- hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
565
- hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
566
-
567
- hp.sample_width = params_width(params);
568
- hp.sample_rate = params_rate(params);
569
- hp.channels = params_channels(params);
570
- hp.mode = hcp->mode;
571
-
592
+ cf->bit_fmt = params_format(params);
572593 return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
573
- &hcp->daifmt[dai->id], &hp);
594
+ cf, &hp);
574595 }
575596
576
-static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
577
- unsigned int fmt)
597
+static int hdmi_codec_prepare(struct snd_pcm_substream *substream,
598
+ struct snd_soc_dai *dai)
578599 {
579600 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
580
- struct hdmi_codec_daifmt cf = { 0 };
601
+ struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
602
+ struct snd_pcm_runtime *runtime = substream->runtime;
603
+ unsigned int channels = runtime->channels;
604
+ unsigned int width = snd_pcm_format_width(runtime->format);
605
+ unsigned int rate = runtime->rate;
606
+ struct hdmi_codec_params hp;
607
+ int ret;
581608
582
- dev_dbg(dai->dev, "%s()\n", __func__);
583
-
584
- if (dai->id == DAI_ID_SPDIF)
609
+ if (!hcp->hcd.ops->prepare)
585610 return 0;
611
+
612
+ dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
613
+ width, rate, channels);
614
+
615
+ ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp);
616
+ if (ret < 0)
617
+ return ret;
618
+
619
+ memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
620
+ ret = snd_pcm_fill_iec958_consumer(runtime, hp.iec.status,
621
+ sizeof(hp.iec.status));
622
+ if (ret < 0) {
623
+ dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
624
+ ret);
625
+ return ret;
626
+ }
627
+
628
+ cf->bit_fmt = runtime->format;
629
+ return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data,
630
+ cf, &hp);
631
+}
632
+
633
+static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
634
+ unsigned int fmt)
635
+{
636
+ struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
637
+
638
+ /* Reset daifmt */
639
+ memset(cf, 0, sizeof(*cf));
586640
587641 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
588642 case SND_SOC_DAIFMT_CBM_CFM:
589
- cf.bit_clk_master = 1;
590
- cf.frame_clk_master = 1;
643
+ cf->bit_clk_master = 1;
644
+ cf->frame_clk_master = 1;
591645 break;
592646 case SND_SOC_DAIFMT_CBS_CFM:
593
- cf.frame_clk_master = 1;
647
+ cf->frame_clk_master = 1;
594648 break;
595649 case SND_SOC_DAIFMT_CBM_CFS:
596
- cf.bit_clk_master = 1;
650
+ cf->bit_clk_master = 1;
597651 break;
598652 case SND_SOC_DAIFMT_CBS_CFS:
599653 break;
....@@ -605,67 +659,79 @@
605659 case SND_SOC_DAIFMT_NB_NF:
606660 break;
607661 case SND_SOC_DAIFMT_NB_IF:
608
- cf.frame_clk_inv = 1;
662
+ cf->frame_clk_inv = 1;
609663 break;
610664 case SND_SOC_DAIFMT_IB_NF:
611
- cf.bit_clk_inv = 1;
665
+ cf->bit_clk_inv = 1;
612666 break;
613667 case SND_SOC_DAIFMT_IB_IF:
614
- cf.frame_clk_inv = 1;
615
- cf.bit_clk_inv = 1;
668
+ cf->frame_clk_inv = 1;
669
+ cf->bit_clk_inv = 1;
616670 break;
617671 }
618672
619673 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
620674 case SND_SOC_DAIFMT_I2S:
621
- cf.fmt = HDMI_I2S;
675
+ cf->fmt = HDMI_I2S;
622676 break;
623677 case SND_SOC_DAIFMT_DSP_A:
624
- cf.fmt = HDMI_DSP_A;
678
+ cf->fmt = HDMI_DSP_A;
625679 break;
626680 case SND_SOC_DAIFMT_DSP_B:
627
- cf.fmt = HDMI_DSP_B;
681
+ cf->fmt = HDMI_DSP_B;
628682 break;
629683 case SND_SOC_DAIFMT_RIGHT_J:
630
- cf.fmt = HDMI_RIGHT_J;
684
+ cf->fmt = HDMI_RIGHT_J;
631685 break;
632686 case SND_SOC_DAIFMT_LEFT_J:
633
- cf.fmt = HDMI_LEFT_J;
687
+ cf->fmt = HDMI_LEFT_J;
634688 break;
635689 case SND_SOC_DAIFMT_AC97:
636
- cf.fmt = HDMI_AC97;
690
+ cf->fmt = HDMI_AC97;
637691 break;
638692 default:
639693 dev_err(dai->dev, "Invalid DAI interface format\n");
640694 return -EINVAL;
641695 }
642696
643
- hcp->daifmt[dai->id] = cf;
644
-
645697 return 0;
646698 }
647699
648
-static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
700
+static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
649701 {
650702 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
651703
652
- dev_dbg(dai->dev, "%s()\n", __func__);
704
+ /*
705
+ * ignore if direction was CAPTURE
706
+ * and it had .no_capture_mute flag
707
+ * see
708
+ * snd_soc_dai_digital_mute()
709
+ */
710
+ if (hcp->hcd.ops->mute_stream &&
711
+ (direction == SNDRV_PCM_STREAM_PLAYBACK ||
712
+ !hcp->hcd.ops->no_capture_mute))
713
+ return hcp->hcd.ops->mute_stream(dai->dev->parent,
714
+ hcp->hcd.data,
715
+ mute, direction);
653716
654
- if (hcp->hcd.ops->digital_mute)
655
- return hcp->hcd.ops->digital_mute(dai->dev->parent,
656
- hcp->hcd.data, mute);
657
-
658
- return 0;
717
+ return -ENOTSUPP;
659718 }
660719
661
-static const struct snd_soc_dai_ops hdmi_dai_ops = {
720
+static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
662721 .startup = hdmi_codec_startup,
663722 .shutdown = hdmi_codec_shutdown,
664723 .hw_params = hdmi_codec_hw_params,
665
- .set_fmt = hdmi_codec_set_fmt,
666
- .digital_mute = hdmi_codec_digital_mute,
724
+ .prepare = hdmi_codec_prepare,
725
+ .set_fmt = hdmi_codec_i2s_set_fmt,
726
+ .mute_stream = hdmi_codec_mute,
667727 };
668728
729
+static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
730
+ .startup = hdmi_codec_startup,
731
+ .shutdown = hdmi_codec_shutdown,
732
+ .hw_params = hdmi_codec_hw_params,
733
+ .mute_stream = hdmi_codec_mute,
734
+};
669735
670736 #define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
671737 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
....@@ -689,36 +755,43 @@
689755 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
690756 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
691757 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
692
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
758
+ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\
759
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
760
+
761
+static struct snd_kcontrol_new hdmi_codec_controls[] = {
762
+ {
763
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
764
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
765
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
766
+ .info = hdmi_codec_iec958_info,
767
+ .get = hdmi_codec_iec958_mask_get,
768
+ },
769
+ {
770
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
771
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
772
+ .info = hdmi_codec_iec958_info,
773
+ .get = hdmi_codec_iec958_default_get,
774
+ .put = hdmi_codec_iec958_default_put,
775
+ },
776
+ {
777
+ .access = (SNDRV_CTL_ELEM_ACCESS_READ |
778
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE),
779
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
780
+ .name = "ELD",
781
+ .info = hdmi_eld_ctl_info,
782
+ .get = hdmi_eld_ctl_get,
783
+ },
784
+ SOC_SINGLE_BOOL_EXT("ELD Bypass Switch", 0,
785
+ hdmi_codec_eld_bypass_get, hdmi_codec_eld_bypass_put),
786
+};
693787
694788 static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
695789 struct snd_soc_dai *dai)
696790 {
697791 struct snd_soc_dai_driver *drv = dai->driver;
698792 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
699
- struct snd_kcontrol *kctl;
700
- struct snd_kcontrol_new hdmi_eld_ctl = {
701
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
702
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
703
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
704
- .name = "ELD",
705
- .info = hdmi_eld_ctl_info,
706
- .get = hdmi_eld_ctl_get,
707
- .device = rtd->pcm->device,
708
- };
709
- struct snd_kcontrol_new hdmi_mode_ctl = {
710
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
711
- SNDRV_CTL_ELEM_ACCESS_WRITE |
712
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
713
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
714
- .name = "AUDIO MODE",
715
- .info = hdmi_audio_mode_info,
716
- .get = hdmi_audio_mode_get,
717
- .put = hdmi_audio_mode_put,
718
- };
793
+ unsigned int i;
719794 int ret;
720
-
721
- dev_dbg(dai->dev, "%s()\n", __func__);
722795
723796 ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
724797 NULL, drv->playback.channels_max, 0,
....@@ -734,26 +807,27 @@
734807 hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
735808 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
736809
737
- /* add ELD ctl with the device number corresponding to the PCM stream */
738
- kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component);
739
- if (!kctl)
740
- return -ENOMEM;
810
+ for (i = 0; i < ARRAY_SIZE(hdmi_codec_controls); i++) {
811
+ struct snd_kcontrol *kctl;
741812
742
- ret = snd_ctl_add(rtd->card->snd_card, kctl);
743
- if (ret < 0)
744
- return ret;
813
+ /* add ELD ctl with the device number corresponding to the PCM stream */
814
+ kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component);
815
+ if (!kctl)
816
+ return -ENOMEM;
745817
746
- /* add MODE ctl with the device number corresponding to the PCM stream */
747
- kctl = snd_ctl_new1(&hdmi_mode_ctl, dai->component);
748
- if (!kctl)
749
- return -ENOMEM;
818
+ kctl->id.device = rtd->pcm->device;
819
+ ret = snd_ctl_add(rtd->card->snd_card, kctl);
820
+ if (ret < 0)
821
+ return ret;
822
+ }
750823
751
- return snd_ctl_add(rtd->card->snd_card, kctl);
824
+ return 0;
752825 }
753826
754827 static int hdmi_dai_probe(struct snd_soc_dai *dai)
755828 {
756829 struct snd_soc_dapm_context *dapm;
830
+ struct hdmi_codec_daifmt *daifmt;
757831 struct snd_soc_dapm_route route[] = {
758832 {
759833 .sink = "TX",
....@@ -764,9 +838,19 @@
764838 .source = "RX",
765839 },
766840 };
841
+ int ret;
767842
768843 dapm = snd_soc_component_get_dapm(dai->component);
769
- return snd_soc_dapm_add_routes(dapm, route, 2);
844
+ ret = snd_soc_dapm_add_routes(dapm, route, 2);
845
+ if (ret)
846
+ return ret;
847
+
848
+ daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
849
+ if (!daifmt)
850
+ return -ENOMEM;
851
+
852
+ dai->playback_dma_data = daifmt;
853
+ return 0;
770854 }
771855
772856 static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
....@@ -783,17 +867,18 @@
783867 struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
784868
785869 if (plugged) {
870
+ if (!hcp->eld_bypass && hcp->hcd.ops->get_eld) {
871
+ hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data,
872
+ hcp->eld, sizeof(hcp->eld));
873
+ }
786874 hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
787
- extcon_set_state_sync(hcp->edev,
788
- EXTCON_DISP_HDMI_AUDIO, true);
789875 } else {
790876 hdmi_codec_jack_report(hcp, 0);
791
- extcon_set_state_sync(hcp->edev,
792
- EXTCON_DISP_HDMI_AUDIO, false);
877
+ memset(hcp->eld, 0, sizeof(hcp->eld));
793878 }
794879
795
- mutex_lock(&hcp->current_stream_lock);
796
- if (hcp->current_stream) {
880
+ mutex_lock(&hcp->lock);
881
+ if (hcp->substream) {
797882 /*
798883 * Workaround for HDMIIN and HDMIOUT plug-{in,out} when streaming.
799884 *
....@@ -814,16 +899,16 @@
814899 * we stop stream to notify user to re-open and configure sound card
815900 * and then go on streaming.
816901 */
817
- int stream = hcp->current_stream->stream;
902
+ int stream = hcp->substream->stream;
818903
819904 if (stream == SNDRV_PCM_STREAM_PLAYBACK && plugged)
820
- snd_pcm_stop(hcp->current_stream, SNDRV_PCM_STATE_SETUP);
905
+ snd_pcm_stop(hcp->substream, SNDRV_PCM_STATE_SETUP);
821906 else if (stream == SNDRV_PCM_STREAM_CAPTURE && !plugged)
822
- snd_pcm_stop(hcp->current_stream, SNDRV_PCM_STATE_DISCONNECTED);
907
+ snd_pcm_stop(hcp->substream, SNDRV_PCM_STATE_DISCONNECTED);
823908
824909 dev_dbg(dev, "stream[%d]: %s\n", stream, plugged ? "plug in" : "plug out");
825910 }
826
- mutex_unlock(&hcp->current_stream_lock);
911
+ mutex_unlock(&hcp->lock);
827912 }
828913
829914 static int hdmi_codec_set_jack(struct snd_soc_component *component,
....@@ -831,7 +916,7 @@
831916 void *data)
832917 {
833918 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
834
- int ret = -EOPNOTSUPP;
919
+ int ret = -ENOTSUPP;
835920
836921 if (hcp->hcd.ops->hook_plugged_cb) {
837922 hcp->jack = jack;
....@@ -845,10 +930,32 @@
845930 return ret;
846931 }
847932
933
+static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
934
+{
935
+ struct hdmi_codec_daifmt *cf;
936
+ int ret;
937
+
938
+ ret = hdmi_dai_probe(dai);
939
+ if (ret)
940
+ return ret;
941
+
942
+ cf = dai->playback_dma_data;
943
+ cf->fmt = HDMI_SPDIF;
944
+
945
+ return 0;
946
+}
947
+
948
+static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
949
+{
950
+ kfree(dai->playback_dma_data);
951
+ return 0;
952
+}
953
+
848954 static const struct snd_soc_dai_driver hdmi_i2s_dai = {
849955 .name = "i2s-hifi",
850956 .id = DAI_ID_I2S,
851957 .probe = hdmi_dai_probe,
958
+ .remove = hdmi_codec_dai_remove,
852959 .playback = {
853960 .stream_name = "I2S Playback",
854961 .channels_min = 2,
....@@ -865,14 +972,15 @@
865972 .formats = I2S_FORMATS,
866973 .sig_bits = 24,
867974 },
868
- .ops = &hdmi_dai_ops,
975
+ .ops = &hdmi_codec_i2s_dai_ops,
869976 .pcm_new = hdmi_codec_pcm_new,
870977 };
871978
872979 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
873980 .name = "spdif-hifi",
874981 .id = DAI_ID_SPDIF,
875
- .probe = hdmi_dai_probe,
982
+ .probe = hdmi_dai_spdif_probe,
983
+ .remove = hdmi_codec_dai_remove,
876984 .playback = {
877985 .stream_name = "SPDIF Playback",
878986 .channels_min = 2,
....@@ -887,7 +995,7 @@
887995 .rates = HDMI_RATES,
888996 .formats = SPDIF_FORMATS,
889997 },
890
- .ops = &hdmi_dai_ops,
998
+ .ops = &hdmi_codec_spdif_dai_ops,
891999 .pcm_new = hdmi_codec_pcm_new,
8921000 };
8931001
....@@ -903,7 +1011,17 @@
9031011 return ret;
9041012 }
9051013
1014
+static void hdmi_remove(struct snd_soc_component *component)
1015
+{
1016
+ struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
1017
+
1018
+ if (hcp->hcd.ops->hook_plugged_cb)
1019
+ hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
1020
+ hcp->hcd.data, NULL, NULL);
1021
+}
1022
+
9061023 static const struct snd_soc_component_driver hdmi_driver = {
1024
+ .remove = hdmi_remove,
9071025 .dapm_widgets = hdmi_widgets,
9081026 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
9091027 .of_xlate_dai_id = hdmi_of_xlate_dai_id,
....@@ -917,20 +1035,21 @@
9171035 static int hdmi_codec_probe(struct platform_device *pdev)
9181036 {
9191037 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
1038
+ struct snd_soc_dai_driver *daidrv;
9201039 struct device *dev = &pdev->dev;
9211040 struct hdmi_codec_priv *hcp;
9221041 int dai_count, i = 0;
9231042 int ret;
9241043
925
- dev_dbg(dev, "%s()\n", __func__);
926
-
9271044 if (!hcd) {
928
- dev_err(dev, "%s: No plalform data\n", __func__);
1045
+ dev_err(dev, "%s: No platform data\n", __func__);
9291046 return -EINVAL;
9301047 }
9311048
9321049 dai_count = hcd->i2s + hcd->spdif;
933
- if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params) {
1050
+ if (dai_count < 1 || !hcd->ops ||
1051
+ (!hcd->ops->hw_params && !hcd->ops->prepare) ||
1052
+ !hcd->ops->audio_shutdown) {
9341053 dev_err(dev, "%s: Invalid parameters\n", __func__);
9351054 return -EINVAL;
9361055 }
....@@ -940,41 +1059,30 @@
9401059 return -ENOMEM;
9411060
9421061 hcp->hcd = *hcd;
943
- mutex_init(&hcp->current_stream_lock);
1062
+ mutex_init(&hcp->lock);
9441063
945
- hcp->daidrv = devm_kcalloc(dev, dai_count, sizeof(*hcp->daidrv),
946
- GFP_KERNEL);
947
- if (!hcp->daidrv)
1064
+ ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status,
1065
+ sizeof(hcp->iec_status));
1066
+ if (ret < 0)
1067
+ return ret;
1068
+
1069
+ daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
1070
+ if (!daidrv)
9481071 return -ENOMEM;
9491072
9501073 if (hcd->i2s) {
951
- hcp->daidrv[i] = hdmi_i2s_dai;
952
- hcp->daidrv[i].playback.channels_max =
953
- hcd->max_i2s_channels;
1074
+ daidrv[i] = hdmi_i2s_dai;
1075
+ daidrv[i].playback.channels_max = hcd->max_i2s_channels;
9541076 i++;
9551077 }
9561078
957
- if (hcd->spdif) {
958
- hcp->daidrv[i] = hdmi_spdif_dai;
959
- hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
960
- }
1079
+ if (hcd->spdif)
1080
+ daidrv[i] = hdmi_spdif_dai;
9611081
9621082 dev_set_drvdata(dev, hcp);
9631083
964
- hcp->edev = devm_extcon_dev_allocate(&pdev->dev, hdmi_extcon_cable);
965
- if (IS_ERR(hcp->edev)) {
966
- dev_err(&pdev->dev, "Failed to allocate extcon device\n");
967
- return -ENOMEM;
968
- }
969
-
970
- ret = devm_extcon_dev_register(&pdev->dev, hcp->edev);
971
- if (ret < 0) {
972
- dev_err(&pdev->dev, "Failed to register extcon device\n");
973
- return ret;
974
- }
975
-
976
- ret = devm_snd_soc_register_component(dev, &hdmi_driver, hcp->daidrv,
977
- dai_count);
1084
+ ret = devm_snd_soc_register_component(dev, &hdmi_driver, daidrv,
1085
+ dai_count);
9781086 if (ret) {
9791087 dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
9801088 __func__, ret);