1384 lines
49 KiB
Diff
1384 lines
49 KiB
Diff
|
From 46e3e82a547b78ca5db11a8444f787fd15f8e8ce Mon Sep 17 00:00:00 2001
|
||
|
From: Sugar Zhang <sugar.zhang@rock-chips.com>
|
||
|
Date: Wed, 7 Sep 2016 14:30:21 +0800
|
||
|
Subject: [PATCH] UPSTREAM: ASoC: rockchip: spdif: restore register during
|
||
|
runtime_suspend/resume cycle
|
||
|
|
||
|
when step into runtime_suspend, spdif pd will be disabled and loss state.
|
||
|
so need to restore register when runtime_resume.
|
||
|
|
||
|
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit 3628c6987fb45d719cd963805bbba9f15017290e)
|
||
|
---
|
||
|
sound/soc/rockchip/rockchip_spdif.c | 12 +++++++++++-
|
||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
|
||
|
index 784941ca2408..831e4caf29d3 100644
|
||
|
--- a/sound/soc/rockchip/rockchip_spdif.c
|
||
|
+++ b/sound/soc/rockchip/rockchip_spdif.c
|
||
|
@@ -69,6 +69,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev)
|
||
|
{
|
||
|
struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
|
||
|
|
||
|
+ regcache_cache_only(spdif->regmap, true);
|
||
|
clk_disable_unprepare(spdif->mclk);
|
||
|
clk_disable_unprepare(spdif->hclk);
|
||
|
|
||
|
@@ -92,7 +93,16 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
- return 0;
|
||
|
+ regcache_cache_only(spdif->regmap, false);
|
||
|
+ regcache_mark_dirty(spdif->regmap);
|
||
|
+
|
||
|
+ ret = regcache_sync(spdif->regmap);
|
||
|
+ if (ret) {
|
||
|
+ clk_disable_unprepare(spdif->mclk);
|
||
|
+ clk_disable_unprepare(spdif->hclk);
|
||
|
+ }
|
||
|
+
|
||
|
+ return ret;
|
||
|
}
|
||
|
|
||
|
static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
|
||
|
|
||
|
From d8a8c9964022565ecf7b5ea7249262c3ac381a1b Mon Sep 17 00:00:00 2001
|
||
|
From: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||
|
Date: Tue, 3 Jan 2017 16:52:50 +0100
|
||
|
Subject: [PATCH] UPSTREAM: DRM: add help to get ELD speaker allocation
|
||
|
|
||
|
Add helper to allow users to retrieve the speaker allocations without
|
||
|
knowledge of the ELD structure.
|
||
|
|
||
|
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||
|
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit c82dbe5c055e4d246bd07c4d7b24801c9445c241)
|
||
|
---
|
||
|
include/drm/drm_edid.h | 13 +++++++++++++
|
||
|
1 file changed, 13 insertions(+)
|
||
|
|
||
|
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
|
||
|
index 85861b63e77a..55201e7e2ede 100644
|
||
|
--- a/include/drm/drm_edid.h
|
||
|
+++ b/include/drm/drm_edid.h
|
||
|
@@ -254,6 +254,7 @@ struct detailed_timing {
|
||
|
# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */
|
||
|
|
||
|
#define DRM_ELD_SPEAKER 7
|
||
|
+# define DRM_ELD_SPEAKER_MASK 0x7f
|
||
|
# define DRM_ELD_SPEAKER_RLRC (1 << 6)
|
||
|
# define DRM_ELD_SPEAKER_FLRC (1 << 5)
|
||
|
# define DRM_ELD_SPEAKER_RC (1 << 4)
|
||
|
@@ -417,6 +418,18 @@ static inline int drm_eld_size(const uint8_t *eld)
|
||
|
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
|
||
|
}
|
||
|
|
||
|
+/**
|
||
|
+ * drm_eld_get_spk_alloc - Get speaker allocation
|
||
|
+ * @eld: pointer to an ELD memory structure
|
||
|
+ *
|
||
|
+ * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
|
||
|
+ * field definitions to identify speakers.
|
||
|
+ */
|
||
|
+static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
|
||
|
+{
|
||
|
+ return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
|
||
|
+}
|
||
|
+
|
||
|
struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||
|
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
||
|
size_t len),
|
||
|
|
||
|
From e622344ce58345eda1ce7372bf7e91e4e90ece5f Mon Sep 17 00:00:00 2001
|
||
|
From: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||
|
Date: Tue, 3 Jan 2017 16:52:51 +0100
|
||
|
Subject: [PATCH] UPSTREAM: ASoC: core: add optional pcm_new callback for DAI
|
||
|
driver
|
||
|
|
||
|
During probe, DAIs can need to perform some actions that requests
|
||
|
the knowledge of the pcm runtime handle.
|
||
|
The callback is called during DAIs linking, after PCM device creation.
|
||
|
For instance this can be used to add relationship between a DAI pcm
|
||
|
control and the pcm device.
|
||
|
|
||
|
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit 25f7b701c20db3e9ae09e28dd652949bd977e5cd)
|
||
|
---
|
||
|
include/sound/soc-dai.h | 3 +++
|
||
|
sound/soc/soc-core.c | 28 ++++++++++++++++++++++++++++
|
||
|
2 files changed, 31 insertions(+)
|
||
|
|
||
|
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
|
||
|
index 212eaaf172ed..345e4f8ee93f 100644
|
||
|
--- a/include/sound/soc-dai.h
|
||
|
+++ b/include/sound/soc-dai.h
|
||
|
@@ -230,6 +230,9 @@ struct snd_soc_dai_driver {
|
||
|
int (*resume)(struct snd_soc_dai *dai);
|
||
|
/* compress dai */
|
||
|
int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
|
||
|
+ /* Optional Callback used at pcm creation*/
|
||
|
+ int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
|
||
|
+ struct snd_soc_dai *dai);
|
||
|
/* DAI is also used for the control bus */
|
||
|
bool bus_control;
|
||
|
|
||
|
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
|
||
|
index 3c6713da3ad9..e46e80c0e07d 100644
|
||
|
--- a/sound/soc/soc-core.c
|
||
|
+++ b/sound/soc/soc-core.c
|
||
|
@@ -1289,6 +1289,27 @@ static int soc_probe_dai(struct snd_soc_dai *dai, int order)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais,
|
||
|
+ struct snd_soc_pcm_runtime *rtd)
|
||
|
+{
|
||
|
+ int i, ret = 0;
|
||
|
+
|
||
|
+ for (i = 0; i < num_dais; ++i) {
|
||
|
+ struct snd_soc_dai_driver *drv = dais[i]->driver;
|
||
|
+
|
||
|
+ if (!rtd->dai_link->no_pcm && drv->pcm_new)
|
||
|
+ ret = drv->pcm_new(rtd, dais[i]);
|
||
|
+ if (ret < 0) {
|
||
|
+ dev_err(dais[i]->dev,
|
||
|
+ "ASoC: Failed to bind %s with pcm device\n",
|
||
|
+ dais[i]->name);
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static int soc_link_dai_widgets(struct snd_soc_card *card,
|
||
|
struct snd_soc_dai_link *dai_link,
|
||
|
struct snd_soc_pcm_runtime *rtd)
|
||
|
@@ -1400,6 +1421,13 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
|
||
|
dai_link->stream_name, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
+ ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
|
||
|
+ if (ret < 0)
|
||
|
+ return ret;
|
||
|
+ ret = soc_link_dai_pcm_new(rtd->codec_dais,
|
||
|
+ rtd->num_codecs, rtd);
|
||
|
+ if (ret < 0)
|
||
|
+ return ret;
|
||
|
} else {
|
||
|
INIT_DELAYED_WORK(&rtd->delayed_work,
|
||
|
codec2codec_close_delayed_work);
|
||
|
|
||
|
From 3877e4beac5a5efc2898185fe75555e21cf6b090 Mon Sep 17 00:00:00 2001
|
||
|
From: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||
|
Date: Tue, 3 Jan 2017 16:52:52 +0100
|
||
|
Subject: [PATCH] UPSTREAM: ASoC: hdmi-codec: add channel mapping control
|
||
|
|
||
|
Add user interface to provide channel mapping.
|
||
|
In a first step this control is read only.
|
||
|
|
||
|
As TLV type, the control provides all configuration available for
|
||
|
HDMI sink(ELD), and provides current channel mapping selected by codec
|
||
|
based on ELD and number of channels specified by user on open.
|
||
|
When control is called before the number of the channel is specified
|
||
|
(i.e. hw_params is set), it returns all channels set to UNKNOWN.
|
||
|
|
||
|
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit cd6111b26280a2f38a9fb8e6630c63a96477e4bf)
|
||
|
---
|
||
|
sound/soc/codecs/hdmi-codec.c | 377 +++++++++++++++++++++++++++++++++++++++++-
|
||
|
1 file changed, 376 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
|
||
|
index 028d60c196ae..cb78d8971b41 100644
|
||
|
--- a/sound/soc/codecs/hdmi-codec.c
|
||
|
+++ b/sound/soc/codecs/hdmi-codec.c
|
||
|
@@ -21,12 +21,264 @@
|
||
|
#include <sound/pcm.h>
|
||
|
#include <sound/pcm_params.h>
|
||
|
#include <sound/soc.h>
|
||
|
+#include <sound/tlv.h>
|
||
|
#include <sound/pcm_drm_eld.h>
|
||
|
#include <sound/hdmi-codec.h>
|
||
|
#include <sound/pcm_iec958.h>
|
||
|
|
||
|
#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
|
||
|
|
||
|
+#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
|
||
|
+
|
||
|
+struct hdmi_codec_channel_map_table {
|
||
|
+ unsigned char map; /* ALSA API channel map position */
|
||
|
+ unsigned long spk_mask; /* speaker position bit mask */
|
||
|
+};
|
||
|
+
|
||
|
+/*
|
||
|
+ * CEA speaker placement for HDMI 1.4:
|
||
|
+ *
|
||
|
+ * FL FLC FC FRC FR FRW
|
||
|
+ *
|
||
|
+ * LFE
|
||
|
+ *
|
||
|
+ * RL RLC RC RRC RR
|
||
|
+ *
|
||
|
+ * Speaker placement has to be extended to support HDMI 2.0
|
||
|
+ */
|
||
|
+enum hdmi_codec_cea_spk_placement {
|
||
|
+ FL = BIT(0), /* Front Left */
|
||
|
+ FC = BIT(1), /* Front Center */
|
||
|
+ FR = BIT(2), /* Front Right */
|
||
|
+ FLC = BIT(3), /* Front Left Center */
|
||
|
+ FRC = BIT(4), /* Front Right Center */
|
||
|
+ RL = BIT(5), /* Rear Left */
|
||
|
+ RC = BIT(6), /* Rear Center */
|
||
|
+ RR = BIT(7), /* Rear Right */
|
||
|
+ RLC = BIT(8), /* Rear Left Center */
|
||
|
+ RRC = BIT(9), /* Rear Right Center */
|
||
|
+ LFE = BIT(10), /* Low Frequency Effect */
|
||
|
+};
|
||
|
+
|
||
|
+/*
|
||
|
+ * cea Speaker allocation structure
|
||
|
+ */
|
||
|
+struct hdmi_codec_cea_spk_alloc {
|
||
|
+ const int ca_id;
|
||
|
+ unsigned int n_ch;
|
||
|
+ unsigned long mask;
|
||
|
+};
|
||
|
+
|
||
|
+/* Channel maps stereo HDMI */
|
||
|
+const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
|
||
|
+ { .channels = 2,
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
|
||
|
+ { }
|
||
|
+};
|
||
|
+
|
||
|
+/* Channel maps for multi-channel playbacks, up to 8 n_ch */
|
||
|
+const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
|
||
|
+ { .channels = 2, /* CA_ID 0x00 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
|
||
|
+ { .channels = 4, /* CA_ID 0x01 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 4, /* CA_ID 0x02 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC } },
|
||
|
+ { .channels = 4, /* CA_ID 0x03 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC } },
|
||
|
+ { .channels = 6, /* CA_ID 0x04 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 6, /* CA_ID 0x05 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 6, /* CA_ID 0x06 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 6, /* CA_ID 0x07 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 6, /* CA_ID 0x08 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
|
||
|
+ { .channels = 6, /* CA_ID 0x09 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
|
||
|
+ { .channels = 6, /* CA_ID 0x0A */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
|
||
|
+ { .channels = 6, /* CA_ID 0x0B */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
|
||
|
+ { .channels = 8, /* CA_ID 0x0C */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 8, /* CA_ID 0x0D */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 8, /* CA_ID 0x0E */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 8, /* CA_ID 0x0F */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
|
||
|
+ { .channels = 8, /* CA_ID 0x10 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x11 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x12 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x13 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
|
||
|
+ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x14 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x15 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x16 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x17 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x18 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x19 */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x1A */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x1B */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x1C */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x1D */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x1E */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { .channels = 8, /* CA_ID 0x1F */
|
||
|
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
|
||
|
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
|
||
|
+ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
|
||
|
+ { }
|
||
|
+};
|
||
|
+
|
||
|
+/*
|
||
|
+ * hdmi_codec_channel_alloc: speaker configuration available for CEA
|
||
|
+ *
|
||
|
+ * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
|
||
|
+ * The preceding ones have better chances to be selected by
|
||
|
+ * hdmi_codec_get_ch_alloc_table_idx().
|
||
|
+ */
|
||
|
+static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
|
||
|
+ { .ca_id = 0x00, .n_ch = 2,
|
||
|
+ .mask = FL | FR},
|
||
|
+ /* 2.1 */
|
||
|
+ { .ca_id = 0x01, .n_ch = 4,
|
||
|
+ .mask = FL | FR | LFE},
|
||
|
+ /* Dolby Surround */
|
||
|
+ { .ca_id = 0x02, .n_ch = 4,
|
||
|
+ .mask = FL | FR | FC },
|
||
|
+ /* surround51 */
|
||
|
+ { .ca_id = 0x0b, .n_ch = 6,
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR},
|
||
|
+ /* surround40 */
|
||
|
+ { .ca_id = 0x08, .n_ch = 6,
|
||
|
+ .mask = FL | FR | RL | RR },
|
||
|
+ /* surround41 */
|
||
|
+ { .ca_id = 0x09, .n_ch = 6,
|
||
|
+ .mask = FL | FR | LFE | RL | RR },
|
||
|
+ /* surround50 */
|
||
|
+ { .ca_id = 0x0a, .n_ch = 6,
|
||
|
+ .mask = FL | FR | FC | RL | RR },
|
||
|
+ /* 6.1 */
|
||
|
+ { .ca_id = 0x0f, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR | RC },
|
||
|
+ /* surround71 */
|
||
|
+ { .ca_id = 0x13, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
|
||
|
+ /* others */
|
||
|
+ { .ca_id = 0x03, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC },
|
||
|
+ { .ca_id = 0x04, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC},
|
||
|
+ { .ca_id = 0x05, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RC },
|
||
|
+ { .ca_id = 0x06, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | RC },
|
||
|
+ { .ca_id = 0x07, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | RC },
|
||
|
+ { .ca_id = 0x0c, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC | RL | RR },
|
||
|
+ { .ca_id = 0x0d, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RL | RR | RC },
|
||
|
+ { .ca_id = 0x0e, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | RL | RR | RC },
|
||
|
+ { .ca_id = 0x10, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RL | RR | RLC | RRC },
|
||
|
+ { .ca_id = 0x11, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RL | RR | RLC | RRC },
|
||
|
+ { .ca_id = 0x12, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | RL | RR | RLC | RRC },
|
||
|
+ { .ca_id = 0x14, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FLC | FRC },
|
||
|
+ { .ca_id = 0x15, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FLC | FRC },
|
||
|
+ { .ca_id = 0x16, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x17, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x18, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC | FLC | FRC },
|
||
|
+ { .ca_id = 0x19, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RC | FLC | FRC },
|
||
|
+ { .ca_id = 0x1a, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x1b, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RC | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x1c, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RL | RR | FLC | FRC },
|
||
|
+ { .ca_id = 0x1d, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RL | RR | FLC | FRC },
|
||
|
+ { .ca_id = 0x1e, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | RL | RR | FLC | FRC },
|
||
|
+ { .ca_id = 0x1f, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
|
||
|
+};
|
||
|
+
|
||
|
struct hdmi_codec_priv {
|
||
|
struct hdmi_codec_pdata hcd;
|
||
|
struct snd_soc_dai_driver *daidrv;
|
||
|
@@ -41,6 +293,8 @@ struct hdmi_codec_priv {
|
||
|
struct notifier_block nb;
|
||
|
unsigned int jack_status;
|
||
|
unsigned int mode;
|
||
|
+ struct snd_pcm_chmap *chmap_info;
|
||
|
+ unsigned int chmap_idx;
|
||
|
};
|
||
|
|
||
|
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
|
||
|
@@ -109,6 +363,83 @@ static int hdmi_audio_mode_put(struct snd_kcontrol *kcontrol,
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+ const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
|
||
|
+ [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
|
||
|
+ [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
|
||
|
+ };
|
||
|
+ unsigned long spk_mask = 0;
|
||
|
+
|
||
|
+ for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
|
||
|
+ if (spk_alloc & (1 << i))
|
||
|
+ spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ return spk_mask;
|
||
|
+}
|
||
|
+
|
||
|
+void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
|
||
|
+{
|
||
|
+ u8 spk_alloc;
|
||
|
+ unsigned long spk_mask;
|
||
|
+
|
||
|
+ spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
|
||
|
+ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
|
||
|
+
|
||
|
+ /* Detect if only stereo supported, else return 8 channels mappings */
|
||
|
+ if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2)
|
||
|
+ hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps;
|
||
|
+ else
|
||
|
+ hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
|
||
|
+}
|
||
|
+
|
||
|
+static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
|
||
|
+ unsigned char channels)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+ u8 spk_alloc;
|
||
|
+ unsigned long spk_mask;
|
||
|
+ const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
|
||
|
+
|
||
|
+ spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
|
||
|
+ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
|
||
|
+
|
||
|
+ for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
|
||
|
+ /* If spk_alloc == 0, HDMI is unplugged return stereo config*/
|
||
|
+ if (!spk_alloc && cap->ca_id == 0)
|
||
|
+ return i;
|
||
|
+ if (cap->n_ch != channels)
|
||
|
+ continue;
|
||
|
+ if (!(cap->mask == (spk_mask & cap->mask)))
|
||
|
+ continue;
|
||
|
+ return i;
|
||
|
+ }
|
||
|
+
|
||
|
+ return -EINVAL;
|
||
|
+}
|
||
|
+static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
|
||
|
+ struct snd_ctl_elem_value *ucontrol)
|
||
|
+{
|
||
|
+ unsigned const char *map;
|
||
|
+ unsigned int i;
|
||
|
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
|
||
|
+ struct hdmi_codec_priv *hcp = info->private_data;
|
||
|
+
|
||
|
+ map = info->chmap[hcp->chmap_idx].map;
|
||
|
+
|
||
|
+ for (i = 0; i < info->max_channels; i++) {
|
||
|
+ if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
|
||
|
+ ucontrol->value.integer.value[i] = 0;
|
||
|
+ else
|
||
|
+ ucontrol->value.integer.value[i] = map[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
static const struct snd_kcontrol_new hdmi_controls[] = {
|
||
|
{
|
||
|
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
||
|
@@ -184,6 +515,9 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
|
||
|
ret = snd_pcm_hw_constraint_eld(substream->runtime,
|
||
|
hcp->eld);
|
||
|
mutex_unlock(&hcp->eld_lock);
|
||
|
+
|
||
|
+ /* Select chmap supported */
|
||
|
+ hdmi_codec_eld_chmap(hcp);
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
@@ -201,6 +535,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
|
||
|
|
||
|
WARN_ON(hcp->current_stream != substream);
|
||
|
|
||
|
+ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||
|
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
|
||
|
|
||
|
mutex_lock(&hcp->current_stream_lock);
|
||
|
@@ -221,7 +556,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||
|
.dig_subframe = { 0 },
|
||
|
}
|
||
|
};
|
||
|
- int ret;
|
||
|
+ int ret, idx;
|
||
|
|
||
|
dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
|
||
|
params_width(params), params_rate(params),
|
||
|
@@ -248,6 +583,17 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||
|
hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
|
||
|
hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
|
||
|
|
||
|
+ /* Select a channel allocation that matches with ELD and pcm channels */
|
||
|
+ idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
|
||
|
+ if (idx < 0) {
|
||
|
+ dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
|
||
|
+ idx);
|
||
|
+ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||
|
+ return idx;
|
||
|
+ }
|
||
|
+ hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
|
||
|
+ hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
|
||
|
+
|
||
|
hp.sample_width = params_width(params);
|
||
|
hp.sample_rate = params_rate(params);
|
||
|
hp.channels = params_channels(params);
|
||
|
@@ -377,6 +723,32 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
|
||
|
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
|
||
|
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
|
||
|
|
||
|
+static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
||
|
+ struct snd_soc_dai *dai)
|
||
|
+{
|
||
|
+ struct snd_soc_dai_driver *drv = dai->driver;
|
||
|
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ dev_dbg(dai->dev, "%s()\n", __func__);
|
||
|
+
|
||
|
+ ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||
|
+ NULL, drv->playback.channels_max, 0,
|
||
|
+ &hcp->chmap_info);
|
||
|
+ if (ret < 0)
|
||
|
+ return ret;
|
||
|
+
|
||
|
+ /* override handlers */
|
||
|
+ hcp->chmap_info->private_data = hcp;
|
||
|
+ hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
|
||
|
+
|
||
|
+ /* default chmap supported is stereo */
|
||
|
+ hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
|
||
|
+ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static struct snd_soc_dai_driver hdmi_i2s_dai = {
|
||
|
.name = "i2s-hifi",
|
||
|
.id = DAI_ID_I2S,
|
||
|
@@ -389,6 +761,7 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = {
|
||
|
.sig_bits = 24,
|
||
|
},
|
||
|
.ops = &hdmi_dai_ops,
|
||
|
+ .pcm_new = hdmi_codec_pcm_new,
|
||
|
};
|
||
|
|
||
|
static const struct snd_soc_dai_driver hdmi_spdif_dai = {
|
||
|
@@ -402,6 +775,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
|
||
|
.formats = SPDIF_FORMATS,
|
||
|
},
|
||
|
.ops = &hdmi_dai_ops,
|
||
|
+ .pcm_new = hdmi_codec_pcm_new,
|
||
|
};
|
||
|
|
||
|
static struct snd_soc_codec_driver hdmi_codec = {
|
||
|
@@ -534,6 +908,7 @@ static int hdmi_codec_remove(struct platform_device *pdev)
|
||
|
{
|
||
|
struct hdmi_codec_priv *hcp = platform_get_drvdata(pdev);
|
||
|
|
||
|
+ kfree(hcp->chmap_info);
|
||
|
hdmi_unregister_notifier(&hcp->nb);
|
||
|
snd_soc_unregister_codec(&pdev->dev);
|
||
|
return 0;
|
||
|
|
||
|
From 52c48ffd0956821dd3f1315b9ec3fd2a677b2b63 Mon Sep 17 00:00:00 2001
|
||
|
From: Christophe Jaillet <christophe.jaillet@wanadoo.fr>
|
||
|
Date: Thu, 15 Jun 2017 07:53:11 +0200
|
||
|
Subject: [PATCH] UPSTREAM: ASoC: rockchip: Fix an error handling in
|
||
|
'rockchip_i2s_probe'
|
||
|
|
||
|
If this memory allocation fail, we must disable what has been enabled.
|
||
|
Do not return immediately but go thrue the error handling path instead.
|
||
|
|
||
|
Also use 'devm_kmemdup' instead of 'devm_kzalloc+memcpy' to simplify code.
|
||
|
|
||
|
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit c3a3d3c41b74b05267bab6173f2a8224a1443ba6)
|
||
|
---
|
||
|
sound/soc/rockchip/rockchip_i2s.c | 9 +++++----
|
||
|
1 file changed, 5 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
|
||
|
index b359639c1038..02ff642499bf 100644
|
||
|
--- a/sound/soc/rockchip/rockchip_i2s.c
|
||
|
+++ b/sound/soc/rockchip/rockchip_i2s.c
|
||
|
@@ -658,12 +658,13 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
||
|
goto err_pm_disable;
|
||
|
}
|
||
|
|
||
|
- soc_dai = devm_kzalloc(&pdev->dev,
|
||
|
+ soc_dai = devm_kmemdup(&pdev->dev, &rockchip_i2s_dai,
|
||
|
sizeof(*soc_dai), GFP_KERNEL);
|
||
|
- if (!soc_dai)
|
||
|
- return -ENOMEM;
|
||
|
+ if (!soc_dai) {
|
||
|
+ ret = -ENOMEM;
|
||
|
+ goto err_pm_disable;
|
||
|
+ }
|
||
|
|
||
|
- memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai));
|
||
|
if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
|
||
|
if (val >= 2 && val <= 8)
|
||
|
soc_dai->playback.channels_max = val;
|
||
|
|
||
|
From 7b9368e1f2d50d7ca5b07ea50240fd8f45d884fe Mon Sep 17 00:00:00 2001
|
||
|
From: Markus Elfring <elfring@users.sourceforge.net>
|
||
|
Date: Thu, 10 Aug 2017 18:38:09 +0200
|
||
|
Subject: [PATCH] UPSTREAM: ASoC: rockchip: Delete an error message for a
|
||
|
failed memory allocation in rockchip_i2s_probe()
|
||
|
|
||
|
Omit an extra message for a memory allocation failure in this function.
|
||
|
|
||
|
This issue was detected by using the Coccinelle software.
|
||
|
|
||
|
Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf
|
||
|
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit b48b2710913d583ff93c365413532e1a7cd60d84)
|
||
|
---
|
||
|
sound/soc/rockchip/rockchip_i2s.c | 4 +---
|
||
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
|
||
|
index 02ff642499bf..16ff8d5e0033 100644
|
||
|
--- a/sound/soc/rockchip/rockchip_i2s.c
|
||
|
+++ b/sound/soc/rockchip/rockchip_i2s.c
|
||
|
@@ -594,10 +594,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
||
|
int val;
|
||
|
|
||
|
i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
|
||
|
- if (!i2s) {
|
||
|
- dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n");
|
||
|
+ if (!i2s)
|
||
|
return -ENOMEM;
|
||
|
- }
|
||
|
|
||
|
i2s->dev = &pdev->dev;
|
||
|
|
||
|
|
||
|
From f217d206adafde4eb886ffbd5ecd7779c37438ef Mon Sep 17 00:00:00 2001
|
||
|
From: John Keeping <john@metanate.com>
|
||
|
Date: Thu, 14 Sep 2017 16:58:55 +0100
|
||
|
Subject: [PATCH] UPSTREAM: ASoC: rockchip: i2s: fix unbalanced clk_disable
|
||
|
|
||
|
mclk is enabled and disabled only in i2s_runtime_{resume,suspend}() and
|
||
|
we ensure that the device is runtime suspended before reaching this
|
||
|
clk_disable_unprepare() call, so it is wrong to call it again here.
|
||
|
|
||
|
Signed-off-by: John Keeping <john@metanate.com>
|
||
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||
|
(cherry picked from commit 32debfcd3ff0939c93238ddde03ffcc96cca5c60)
|
||
|
---
|
||
|
sound/soc/rockchip/rockchip_i2s.c | 1 -
|
||
|
1 file changed, 1 deletion(-)
|
||
|
|
||
|
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
|
||
|
index 16ff8d5e0033..986ad2efc8e9 100644
|
||
|
--- a/sound/soc/rockchip/rockchip_i2s.c
|
||
|
+++ b/sound/soc/rockchip/rockchip_i2s.c
|
||
|
@@ -727,7 +727,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
|
||
|
if (!pm_runtime_status_suspended(&pdev->dev))
|
||
|
i2s_runtime_suspend(&pdev->dev);
|
||
|
|
||
|
- clk_disable_unprepare(i2s->mclk);
|
||
|
clk_disable_unprepare(i2s->hclk);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
From 8b1551df18617eba99d59f89724191954a7213a4 Mon Sep 17 00:00:00 2001
|
||
|
From: Romain Perier <romain.perier@collabora.com>
|
||
|
Date: Thu, 20 Apr 2017 14:34:34 +0530
|
||
|
Subject: [PATCH] UPSTREAM: drm: dw-hdmi: gate audio clock from the I2S
|
||
|
enablement callbacks
|
||
|
|
||
|
Currently, the audio sampler clock is enabled from dw_hdmi_setup() at
|
||
|
step E. and is kept enabled for later use. This clock should be enabled
|
||
|
and disabled along with the actual audio stream and not always on (that
|
||
|
is bad for PM). Furthermore, as described by the datasheet, the I2S
|
||
|
variant needs to gate/ungate the clock when the stream is
|
||
|
enabled/disabled.
|
||
|
|
||
|
This commit adds a parameter to hdmi_audio_enable_clk() that controls
|
||
|
when the audio sample clock must be enabled or disabled. Then, it adds
|
||
|
the call to this function from dw_hdmi_i2s_audio_enable() and
|
||
|
dw_hdmi_i2s_audio_disable().
|
||
|
|
||
|
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
|
||
|
Signed-off-by: Romain Perier <romain.perier@collabora.com>
|
||
|
Link: http://patchwork.freedesktop.org/patch/msgid/20170414083113.4255-3-romain.perier@collabora.com
|
||
|
Signed-off-by: Archit Taneja <architt@codeaurora.org>
|
||
|
(cherry picked from commit 57fbc05585a9c841c910677228f1e3f8a3a62801)
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++++++-------
|
||
|
1 file changed, 17 insertions(+), 7 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
index 8726498e9f73..17c182cb07b5 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
@@ -824,6 +824,15 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
|
||
|
|
||
|
+static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
|
||
|
+{
|
||
|
+ if (enable)
|
||
|
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
|
||
|
+ else
|
||
|
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
|
||
|
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||
|
+}
|
||
|
+
|
||
|
static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
|
||
|
{
|
||
|
hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
|
||
|
@@ -837,6 +846,12 @@ static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi)
|
||
|
static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi)
|
||
|
{
|
||
|
hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
|
||
|
+ hdmi_enable_audio_clk(hdmi, true);
|
||
|
+}
|
||
|
+
|
||
|
+static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi)
|
||
|
+{
|
||
|
+ hdmi_enable_audio_clk(hdmi, false);
|
||
|
}
|
||
|
|
||
|
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi)
|
||
|
@@ -2149,12 +2164,6 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
|
||
|
HDMI_MC_FLOWCTRL);
|
||
|
}
|
||
|
|
||
|
-static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
|
||
|
-{
|
||
|
- hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
|
||
|
- hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||
|
-}
|
||
|
-
|
||
|
/* Workaround to clear the overflow condition */
|
||
|
static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
|
||
|
{
|
||
|
@@ -2306,7 +2315,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
||
|
|
||
|
/* HDMI Initialization Step E - Configure audio */
|
||
|
hdmi_clk_regenerator_update_pixel_clock(hdmi);
|
||
|
- hdmi_enable_audio_clk(hdmi);
|
||
|
+ hdmi_enable_audio_clk(hdmi, true);
|
||
|
}
|
||
|
|
||
|
/* not for DVI mode */
|
||
|
@@ -3742,6 +3751,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
|
||
|
audio.read = hdmi_readb;
|
||
|
audio.mod = hdmi_modb;
|
||
|
hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
|
||
|
+ hdmi->disable_audio = dw_hdmi_i2s_audio_disable;
|
||
|
|
||
|
pdevinfo.name = "dw-hdmi-i2s-audio";
|
||
|
pdevinfo.data = &audio;
|
||
|
|
||
|
From 442b913082d21de7a8364344feb520946413da5b Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Mon, 7 Aug 2017 22:24:15 +0200
|
||
|
Subject: [PATCH] drm: dw-hdmi-i2s: sync with upstream
|
||
|
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 1 -
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 20 +++++++++++++-------
|
||
|
2 files changed, 13 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
|
||
|
index 3930ba04977b..af7f39c85ba4 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
|
||
|
@@ -14,7 +14,6 @@ struct dw_hdmi_audio_data {
|
||
|
|
||
|
struct dw_hdmi_i2s_audio_data {
|
||
|
struct dw_hdmi *hdmi;
|
||
|
- struct platform_device *pdev;
|
||
|
|
||
|
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
|
||
|
u8 (*read)(struct dw_hdmi *hdmi, int offset);
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
index f1f62d8c1d16..5ff993a35ab6 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
@@ -16,7 +16,8 @@
|
||
|
|
||
|
#define DRIVER_NAME "dw-hdmi-i2s-audio"
|
||
|
|
||
|
-static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, u8 val, int offset)
|
||
|
+static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio,
|
||
|
+ u8 val, int offset)
|
||
|
{
|
||
|
struct dw_hdmi *hdmi = audio->hdmi;
|
||
|
|
||
|
@@ -220,6 +221,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
|
||
|
struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data;
|
||
|
struct platform_device_info pdevinfo;
|
||
|
struct hdmi_codec_pdata pdata;
|
||
|
+ struct platform_device *platform;
|
||
|
|
||
|
pdata.ops = &dw_hdmi_i2s_ops;
|
||
|
pdata.i2s = 1;
|
||
|
@@ -234,23 +236,27 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
|
||
|
pdevinfo.size_data = sizeof(pdata);
|
||
|
pdevinfo.dma_mask = DMA_BIT_MASK(32);
|
||
|
|
||
|
- audio->pdev = platform_device_register_full(&pdevinfo);
|
||
|
- return IS_ERR_OR_NULL(audio->pdev);
|
||
|
+ platform = platform_device_register_full(&pdevinfo);
|
||
|
+ if (IS_ERR(platform))
|
||
|
+ return PTR_ERR(platform);
|
||
|
+
|
||
|
+ dev_set_drvdata(&pdev->dev, platform);
|
||
|
+
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
static int snd_dw_hdmi_remove(struct platform_device *pdev)
|
||
|
{
|
||
|
- struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data;
|
||
|
+ struct platform_device *platform = dev_get_drvdata(&pdev->dev);
|
||
|
|
||
|
- if (!IS_ERR_OR_NULL(audio->pdev))
|
||
|
- platform_device_unregister(audio->pdev);
|
||
|
+ platform_device_unregister(platform);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static struct platform_driver snd_dw_hdmi_driver = {
|
||
|
.probe = snd_dw_hdmi_probe,
|
||
|
- .remove = snd_dw_hdmi_remove,
|
||
|
+ .remove = snd_dw_hdmi_remove,
|
||
|
.driver = {
|
||
|
.name = DRIVER_NAME,
|
||
|
.owner = THIS_MODULE,
|
||
|
|
||
|
From 1d3de24bd61e0bfba1a9e042e040fa65346ccd9d Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sun, 2 Apr 2017 11:33:39 +0200
|
||
|
Subject: [PATCH] drm: dw-hdmi-i2s: implement get_eld
|
||
|
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 1 +
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 12 ++++++++++++
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
|
||
|
3 files changed, 14 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
|
||
|
index af7f39c85ba4..c5ace7808fdf 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
|
||
|
@@ -14,6 +14,7 @@ struct dw_hdmi_audio_data {
|
||
|
|
||
|
struct dw_hdmi_i2s_audio_data {
|
||
|
struct dw_hdmi *hdmi;
|
||
|
+ u8 *eld;
|
||
|
|
||
|
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
|
||
|
u8 (*read)(struct dw_hdmi *hdmi, int offset);
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
index 5ff993a35ab6..e7312571e2cb 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
@@ -11,6 +11,8 @@
|
||
|
|
||
|
#include <sound/hdmi-codec.h>
|
||
|
|
||
|
+#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
|
||
|
+
|
||
|
#include "dw-hdmi.h"
|
||
|
#include "dw-hdmi-audio.h"
|
||
|
|
||
|
@@ -211,9 +213,19 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data)
|
||
|
hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
|
||
|
}
|
||
|
|
||
|
+static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, u8 *buf, size_t len)
|
||
|
+{
|
||
|
+ struct dw_hdmi_i2s_audio_data *audio = data;
|
||
|
+
|
||
|
+ memcpy(buf, audio->eld, min(len, (size_t)MAX_ELD_BYTES));
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static struct hdmi_codec_ops dw_hdmi_i2s_ops = {
|
||
|
.hw_params = dw_hdmi_i2s_hw_params,
|
||
|
.audio_shutdown = dw_hdmi_i2s_audio_shutdown,
|
||
|
+ .get_eld = dw_hdmi_i2s_get_eld,
|
||
|
};
|
||
|
|
||
|
static int snd_dw_hdmi_probe(struct platform_device *pdev)
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
index 17c182cb07b5..df1ea752ac3d 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
@@ -3750,6 +3750,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
|
||
|
audio.write = hdmi_writeb;
|
||
|
audio.read = hdmi_readb;
|
||
|
audio.mod = hdmi_modb;
|
||
|
+ audio.eld = hdmi->connector.eld;
|
||
|
hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
|
||
|
hdmi->disable_audio = dw_hdmi_i2s_audio_disable;
|
||
|
|
||
|
|
||
|
From 1e16f2f6b861a7273d922c9251665acec542eed9 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Mon, 17 Apr 2017 13:09:16 +0200
|
||
|
Subject: [PATCH] drm: dw-hdmi-i2s: configure channel allocation
|
||
|
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
index e7312571e2cb..1d4570e3fbed 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
@@ -188,7 +188,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
||
|
hdmi_write(audio, 0x00, HDMI_FC_AUDICONF1);
|
||
|
|
||
|
/* Set Channel Allocation */
|
||
|
- hdmi_write(audio, 0x00, HDMI_FC_AUDICONF2);
|
||
|
+ hdmi_write(audio, hparms->cea.channel_allocation, HDMI_FC_AUDICONF2);
|
||
|
|
||
|
/* Set LFEPBLDOWN-MIX INH and LSV */
|
||
|
hdmi_write(audio, 0x00, HDMI_FC_AUDICONF3);
|
||
|
|
||
|
From 747742580e282f4374100909906f6957c997c4a3 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Mon, 14 Aug 2017 00:14:05 +0200
|
||
|
Subject: [PATCH] ASoC: hdmi-codec: reorder channel map
|
||
|
|
||
|
---
|
||
|
sound/soc/codecs/hdmi-codec.c | 113 +++++++++++++++++++-----------------------
|
||
|
1 file changed, 52 insertions(+), 61 deletions(-)
|
||
|
|
||
|
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
|
||
|
index cb78d8971b41..b74659bc3bbc 100644
|
||
|
--- a/sound/soc/codecs/hdmi-codec.c
|
||
|
+++ b/sound/soc/codecs/hdmi-codec.c
|
||
|
@@ -205,78 +205,69 @@ const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
|
||
|
*/
|
||
|
static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
|
||
|
{ .ca_id = 0x00, .n_ch = 2,
|
||
|
- .mask = FL | FR},
|
||
|
- /* 2.1 */
|
||
|
- { .ca_id = 0x01, .n_ch = 4,
|
||
|
- .mask = FL | FR | LFE},
|
||
|
- /* Dolby Surround */
|
||
|
+ .mask = FL | FR },
|
||
|
+ { .ca_id = 0x03, .n_ch = 4,
|
||
|
+ .mask = FL | FR | LFE | FC },
|
||
|
{ .ca_id = 0x02, .n_ch = 4,
|
||
|
.mask = FL | FR | FC },
|
||
|
- /* surround51 */
|
||
|
+ { .ca_id = 0x01, .n_ch = 4,
|
||
|
+ .mask = FL | FR | LFE },
|
||
|
{ .ca_id = 0x0b, .n_ch = 6,
|
||
|
- .mask = FL | FR | LFE | FC | RL | RR},
|
||
|
- /* surround40 */
|
||
|
- { .ca_id = 0x08, .n_ch = 6,
|
||
|
- .mask = FL | FR | RL | RR },
|
||
|
- /* surround41 */
|
||
|
- { .ca_id = 0x09, .n_ch = 6,
|
||
|
- .mask = FL | FR | LFE | RL | RR },
|
||
|
- /* surround50 */
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR },
|
||
|
{ .ca_id = 0x0a, .n_ch = 6,
|
||
|
.mask = FL | FR | FC | RL | RR },
|
||
|
- /* 6.1 */
|
||
|
- { .ca_id = 0x0f, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | FC | RL | RR | RC },
|
||
|
- /* surround71 */
|
||
|
+ { .ca_id = 0x09, .n_ch = 6,
|
||
|
+ .mask = FL | FR | LFE | RL | RR },
|
||
|
+ { .ca_id = 0x08, .n_ch = 6,
|
||
|
+ .mask = FL | FR | RL | RR },
|
||
|
+ { .ca_id = 0x07, .n_ch = 6,
|
||
|
+ .mask = FL | FR | LFE | FC | RC },
|
||
|
+ { .ca_id = 0x06, .n_ch = 6,
|
||
|
+ .mask = FL | FR | FC | RC },
|
||
|
+ { .ca_id = 0x05, .n_ch = 6,
|
||
|
+ .mask = FL | FR | LFE | RC },
|
||
|
+ { .ca_id = 0x04, .n_ch = 6,
|
||
|
+ .mask = FL | FR | RC },
|
||
|
{ .ca_id = 0x13, .n_ch = 8,
|
||
|
.mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
|
||
|
- /* others */
|
||
|
- { .ca_id = 0x03, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | FC },
|
||
|
- { .ca_id = 0x04, .n_ch = 8,
|
||
|
- .mask = FL | FR | RC},
|
||
|
- { .ca_id = 0x05, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | RC },
|
||
|
- { .ca_id = 0x06, .n_ch = 8,
|
||
|
- .mask = FL | FR | FC | RC },
|
||
|
- { .ca_id = 0x07, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | FC | RC },
|
||
|
- { .ca_id = 0x0c, .n_ch = 8,
|
||
|
- .mask = FL | FR | RC | RL | RR },
|
||
|
- { .ca_id = 0x0d, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | RL | RR | RC },
|
||
|
- { .ca_id = 0x0e, .n_ch = 8,
|
||
|
- .mask = FL | FR | FC | RL | RR | RC },
|
||
|
- { .ca_id = 0x10, .n_ch = 8,
|
||
|
- .mask = FL | FR | RL | RR | RLC | RRC },
|
||
|
- { .ca_id = 0x11, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | RL | RR | RLC | RRC },
|
||
|
+ { .ca_id = 0x1f, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
|
||
|
{ .ca_id = 0x12, .n_ch = 8,
|
||
|
.mask = FL | FR | FC | RL | RR | RLC | RRC },
|
||
|
- { .ca_id = 0x14, .n_ch = 8,
|
||
|
- .mask = FL | FR | FLC | FRC },
|
||
|
- { .ca_id = 0x15, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | FLC | FRC },
|
||
|
- { .ca_id = 0x16, .n_ch = 8,
|
||
|
- .mask = FL | FR | FC | FLC | FRC },
|
||
|
- { .ca_id = 0x17, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | FC | FLC | FRC },
|
||
|
- { .ca_id = 0x18, .n_ch = 8,
|
||
|
- .mask = FL | FR | RC | FLC | FRC },
|
||
|
- { .ca_id = 0x19, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | RC | FLC | FRC },
|
||
|
- { .ca_id = 0x1a, .n_ch = 8,
|
||
|
- .mask = FL | FR | RC | FC | FLC | FRC },
|
||
|
- { .ca_id = 0x1b, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | RC | FC | FLC | FRC },
|
||
|
- { .ca_id = 0x1c, .n_ch = 8,
|
||
|
- .mask = FL | FR | RL | RR | FLC | FRC },
|
||
|
- { .ca_id = 0x1d, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | RL | RR | FLC | FRC },
|
||
|
{ .ca_id = 0x1e, .n_ch = 8,
|
||
|
.mask = FL | FR | FC | RL | RR | FLC | FRC },
|
||
|
- { .ca_id = 0x1f, .n_ch = 8,
|
||
|
- .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
|
||
|
+ { .ca_id = 0x11, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RL | RR | RLC | RRC },
|
||
|
+ { .ca_id = 0x1d, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RL | RR | FLC | FRC },
|
||
|
+ { .ca_id = 0x10, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RL | RR | RLC | RRC },
|
||
|
+ { .ca_id = 0x1c, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RL | RR | FLC | FRC },
|
||
|
+ { .ca_id = 0x0f, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | RL | RR | RC },
|
||
|
+ { .ca_id = 0x1b, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RC | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x0e, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | RL | RR | RC },
|
||
|
+ { .ca_id = 0x1a, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x0d, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RL | RR | RC },
|
||
|
+ { .ca_id = 0x19, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | RC | FLC | FRC },
|
||
|
+ { .ca_id = 0x0c, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC | RL | RR },
|
||
|
+ { .ca_id = 0x18, .n_ch = 8,
|
||
|
+ .mask = FL | FR | RC | FLC | FRC },
|
||
|
+ { .ca_id = 0x17, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x16, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FC | FLC | FRC },
|
||
|
+ { .ca_id = 0x15, .n_ch = 8,
|
||
|
+ .mask = FL | FR | LFE | FLC | FRC },
|
||
|
+ { .ca_id = 0x14, .n_ch = 8,
|
||
|
+ .mask = FL | FR | FLC | FRC },
|
||
|
};
|
||
|
|
||
|
struct hdmi_codec_priv {
|
||
|
|
||
|
From 1cdb1f115b4bc9781c90d01d914dd4bbac6d0977 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sun, 27 Aug 2017 23:32:40 +0200
|
||
|
Subject: [PATCH] ASoC: codecs: rk3328: limit to working rates
|
||
|
|
||
|
---
|
||
|
sound/soc/codecs/rk3328_codec.c | 7 ++++++-
|
||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c
|
||
|
index af1b7429b6d4..d0b4578ffa0e 100644
|
||
|
--- a/sound/soc/codecs/rk3328_codec.c
|
||
|
+++ b/sound/soc/codecs/rk3328_codec.c
|
||
|
@@ -354,7 +354,12 @@ static struct snd_soc_dai_driver rk3328_dai[] = {
|
||
|
.stream_name = "HIFI Playback",
|
||
|
.channels_min = 1,
|
||
|
.channels_max = 2,
|
||
|
- .rates = SNDRV_PCM_RATE_8000_96000,
|
||
|
+ .rates = (SNDRV_PCM_RATE_8000 |
|
||
|
+ SNDRV_PCM_RATE_16000 |
|
||
|
+ SNDRV_PCM_RATE_32000 |
|
||
|
+ SNDRV_PCM_RATE_48000 |
|
||
|
+ SNDRV_PCM_RATE_64000 |
|
||
|
+ SNDRV_PCM_RATE_96000),
|
||
|
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||
|
SNDRV_PCM_FMTBIT_S20_3LE |
|
||
|
SNDRV_PCM_FMTBIT_S24_LE |
|
||
|
--- a/sound/soc/codecs/rk3228_codec.c
|
||
|
+++ b/sound/soc/codecs/rk3228_codec.c
|
||
|
@@ -352,7 +352,12 @@
|
||
|
.stream_name = "HIFI Playback",
|
||
|
.channels_min = 1,
|
||
|
.channels_max = 2,
|
||
|
- .rates = SNDRV_PCM_RATE_8000_96000,
|
||
|
+ .rates = (SNDRV_PCM_RATE_8000 |
|
||
|
+ SNDRV_PCM_RATE_16000 |
|
||
|
+ SNDRV_PCM_RATE_32000 |
|
||
|
+ SNDRV_PCM_RATE_48000 |
|
||
|
+ SNDRV_PCM_RATE_64000 |
|
||
|
+ SNDRV_PCM_RATE_96000),
|
||
|
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||
|
SNDRV_PCM_FMTBIT_S20_3LE |
|
||
|
SNDRV_PCM_FMTBIT_S24_LE |
|
||
|
From 878d789ff5faa02f0da5e68126e2276124611eeb Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sun, 8 Jul 2018 12:34:43 +0200
|
||
|
Subject: [PATCH] drm: dw-hdmi: change audio config
|
||
|
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 9 ++-------
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 15 ++++++++++++---
|
||
|
2 files changed, 14 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
index 1d4570e3fbed..d0904f6b7a82 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||
|
@@ -110,8 +110,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
||
|
HDMI_AUD_INT_FIFO_FULL_MSK, HDMI_AUD_INT);
|
||
|
hdmi_update_bits(audio, HDMI_AUD_CONF0_SW_RESET,
|
||
|
HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
|
||
|
- hdmi_update_bits(audio, HDMI_MC_SWRSTZ_I2S_RESET_MSK,
|
||
|
- HDMI_MC_SWRSTZ_I2S_RESET_MSK, HDMI_MC_SWRSTZ);
|
||
|
+ hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2S_RESET_MSK, HDMI_MC_SWRSTZ);
|
||
|
|
||
|
switch (hparms->mode) {
|
||
|
case NLPCM:
|
||
|
@@ -193,11 +192,6 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
||
|
/* Set LFEPBLDOWN-MIX INH and LSV */
|
||
|
hdmi_write(audio, 0x00, HDMI_FC_AUDICONF3);
|
||
|
|
||
|
- hdmi_update_bits(audio, HDMI_AUD_CONF0_SW_RESET,
|
||
|
- HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
|
||
|
- hdmi_update_bits(audio, HDMI_MC_SWRSTZ_I2S_RESET_MSK,
|
||
|
- HDMI_MC_SWRSTZ_I2S_RESET_MSK, HDMI_MC_SWRSTZ);
|
||
|
-
|
||
|
dw_hdmi_audio_enable(hdmi);
|
||
|
|
||
|
return 0;
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
index df1ea752ac3d..4bf4ff0fd741 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
@@ -89,6 +89,7 @@ static const struct dw_hdmi_audio_tmds_n common_tmds_n_table[] = {
|
||
|
{ .tmds = 71000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
|
||
|
{ .tmds = 72000000, .n_32k = 4096, .n_44k1 = 5635, .n_48k = 6144, },
|
||
|
{ .tmds = 73250000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, },
|
||
|
+ { .tmds = 74176000, .n_32k = 11648, .n_44k1 = 17836, .n_48k = 11648, },
|
||
|
{ .tmds = 74250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
|
||
|
{ .tmds = 75000000, .n_32k = 4096, .n_44k1 = 5880, .n_48k = 6144, },
|
||
|
{ .tmds = 78750000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, },
|
||
|
@@ -105,13 +106,16 @@ static const struct dw_hdmi_audio_tmds_n common_tmds_n_table[] = {
|
||
|
{ .tmds = 119000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, },
|
||
|
{ .tmds = 135000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
|
||
|
{ .tmds = 146250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
|
||
|
- { .tmds = 148500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
|
||
|
+ { .tmds = 148352000, .n_32k = 11648, .n_44k1 = 8918, .n_48k = 5824, },
|
||
|
+ { .tmds = 148500000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
|
||
|
{ .tmds = 154000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, },
|
||
|
{ .tmds = 162000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
|
||
|
|
||
|
/* For 297 MHz+ HDMI spec have some other rule for setting N */
|
||
|
- { .tmds = 297000000, .n_32k = 3073, .n_44k1 = 4704, .n_48k = 5120, },
|
||
|
- { .tmds = 594000000, .n_32k = 3073, .n_44k1 = 9408, .n_48k = 10240, },
|
||
|
+ { .tmds = 296703000, .n_32k = 5824, .n_44k1 = 4459, .n_48k = 5824, },
|
||
|
+ { .tmds = 297000000, .n_32k = 3072, .n_44k1 = 4704, .n_48k = 5120, },
|
||
|
+ { .tmds = 593407000, .n_32k = 5824, .n_44k1 = 8918, .n_48k = 5824, },
|
||
|
+ { .tmds = 594000000, .n_32k = 3072, .n_44k1 = 9408, .n_48k = 6144, },
|
||
|
|
||
|
/* End of table */
|
||
|
{ .tmds = 0, .n_32k = 0, .n_44k1 = 0, .n_48k = 0, },
|
||
|
@@ -831,6 +835,11 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
|
||
|
else
|
||
|
hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
|
||
|
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||
|
+
|
||
|
+ if (enable) {
|
||
|
+ hdmi_set_cts_n(hdmi, 0, 0);
|
||
|
+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
|
||
|
|
||
|
From 6bf23972f26fde1abad52cd1a65d1223d51d47c2 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonas Karlman <jonas@kwiboo.se>
|
||
|
Date: Sun, 8 Jul 2018 12:56:51 +0200
|
||
|
Subject: [PATCH] WIP: drm: dw-hdmi: use Auto CTS mode
|
||
|
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++-------------
|
||
|
1 file changed, 31 insertions(+), 21 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
index 4bf4ff0fd741..2583320f3289 100644
|
||
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||
|
@@ -643,14 +643,18 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
|
||
|
static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
|
||
|
unsigned int n)
|
||
|
{
|
||
|
- /* Must be set/cleared first */
|
||
|
- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
|
||
|
-
|
||
|
- /* nshift factor = 0 */
|
||
|
- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
|
||
|
-
|
||
|
- hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
|
||
|
- HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
|
||
|
+ /* Use Auto CTS mode with CTS is unknown */
|
||
|
+ if (cts) {
|
||
|
+ /* Must be set/cleared first */
|
||
|
+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
|
||
|
+
|
||
|
+ /* nshift factor = 0 */
|
||
|
+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
|
||
|
+
|
||
|
+ hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
|
||
|
+ HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
|
||
|
+ } else
|
||
|
+ hdmi_writeb(hdmi, 0, HDMI_AUD_CTS3);
|
||
|
hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
|
||
|
hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
|
||
|
|
||
|
@@ -777,24 +781,30 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
|
||
|
{
|
||
|
unsigned long ftdms = pixel_clk;
|
||
|
unsigned int n, cts;
|
||
|
+ u8 config3;
|
||
|
u64 tmp;
|
||
|
|
||
|
n = hdmi_find_n(hdmi, pixel_clk, sample_rate);
|
||
|
|
||
|
- /*
|
||
|
- * Compute the CTS value from the N value. Note that CTS and N
|
||
|
- * can be up to 20 bits in total, so we need 64-bit math. Also
|
||
|
- * note that our TDMS clock is not fully accurate; it is accurate
|
||
|
- * to kHz. This can introduce an unnecessary remainder in the
|
||
|
- * calculation below, so we don't try to warn about that.
|
||
|
- */
|
||
|
- tmp = (u64)ftdms * n;
|
||
|
- do_div(tmp, 128 * sample_rate);
|
||
|
- cts = tmp;
|
||
|
+ config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
|
||
|
|
||
|
- dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
|
||
|
- __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000,
|
||
|
- n, cts);
|
||
|
+ if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
|
||
|
+ /*
|
||
|
+ * Compute the CTS value from the N value. Note that CTS and N
|
||
|
+ * can be up to 20 bits in total, so we need 64-bit math. Also
|
||
|
+ * note that our TDMS clock is not fully accurate; it is accurate
|
||
|
+ * to kHz. This can introduce an unnecessary remainder in the
|
||
|
+ * calculation below, so we don't try to warn about that.
|
||
|
+ */
|
||
|
+ tmp = (u64)ftdms * n;
|
||
|
+ do_div(tmp, 128 * sample_rate);
|
||
|
+ cts = tmp;
|
||
|
+
|
||
|
+ dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
|
||
|
+ __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000,
|
||
|
+ n, cts);
|
||
|
+ } else
|
||
|
+ cts = 0;
|
||
|
|
||
|
spin_lock_irq(&hdmi->audio_lock);
|
||
|
hdmi->audio_n = n;
|
||
|
|