layerscape: add patches-5.4
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-5.4 / 801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch
diff --git a/target/linux/layerscape/patches-5.4/801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch b/target/linux/layerscape/patches-5.4/801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch
new file mode 100644 (file)
index 0000000..0bee583
--- /dev/null
@@ -0,0 +1,164 @@
+From 599235bd9d22c8cad90b0a7621b46d70cca94d31 Mon Sep 17 00:00:00 2001
+From: Viorel Suman <viorel.suman@nxp.com>
+Date: Wed, 5 Jun 2019 13:46:32 +0000
+Subject: [PATCH] MLK-21957-3: ASoC: fsl_sai: add bitcount and timestamp
+ controls
+
+Bitcount and timestamp support added in SAI IP recently.
+Add the related controls in SAI driver.
+
+Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
+---
+ sound/soc/fsl/fsl_sai.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ sound/soc/fsl/fsl_sai.h |  6 +++
+ 2 files changed, 102 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -992,6 +992,90 @@ static const struct snd_soc_dai_ops fsl_
+       .shutdown       = fsl_sai_shutdown,
+ };
++static const char
++      *en_sl[] = { "Disabled", "Enabled", },
++      *inc_sl[] = { "On enabled and bitcount increment", "On enabled", };
++
++static const struct soc_enum tstmp_enum[] = {
++SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 0, ARRAY_SIZE(en_sl), en_sl),
++SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 0, ARRAY_SIZE(en_sl), en_sl),
++SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl),
++SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl),
++};
++
++int fsl_sai_get_reg(struct snd_kcontrol *kcontrol,
++                  struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
++      struct soc_mreg_control *mc =
++              (struct soc_mreg_control *)kcontrol->private_value;
++      bool pm_active = pm_runtime_active(component->dev);
++      unsigned int regval;
++      int ret;
++
++      if (pm_active)
++              regcache_cache_bypass(component->regmap, true);
++
++      ret = snd_soc_component_read(component, mc->regbase, &regval);
++
++      if (pm_active)
++              regcache_cache_bypass(component->regmap, false);
++
++      if (ret < 0)
++              return ret;
++
++      ucontrol->value.integer.value[0] = regval;
++
++      return 0;
++}
++
++#define SOC_SINGLE_REG_RO(xname, xreg) \
++{     .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \
++      .access = SNDRV_CTL_ELEM_ACCESS_READ | \
++                SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
++      .info = snd_soc_info_xr_sx, .get = fsl_sai_get_reg, \
++      .private_value = (unsigned long)&(struct soc_mreg_control) \
++              { .regbase = xreg, .regcount = 1, .nbits = 32, \
++                .invert = 0, .min = 0, .max = 0xffffffff, } }
++
++static const struct snd_kcontrol_new fsl_sai_pb_ctrls[] = {
++      SOC_ENUM("Playback Timestamp Control", tstmp_enum[0]),
++      SOC_ENUM("Playback Timestamp Increment", tstmp_enum[2]),
++      SOC_SINGLE("Playback Timestamp Reset", FSL_SAI_TTCTL, 8, 1, 0),
++      SOC_SINGLE("Playback Bit Counter Reset", FSL_SAI_TTCTL, 9, 1, 0),
++      SOC_SINGLE_REG_RO("Playback Timestamp Counter", FSL_SAI_TTCTN),
++      SOC_SINGLE_REG_RO("Playback Bit Counter", FSL_SAI_TBCTN),
++      SOC_SINGLE_REG_RO("Playback Latched Timestamp Counter", FSL_SAI_TTCAP),
++};
++
++static const struct snd_kcontrol_new fsl_sai_cp_ctrls[] = {
++      SOC_ENUM("Capture Timestamp Control", tstmp_enum[1]),
++      SOC_ENUM("Capture Timestamp Increment", tstmp_enum[3]),
++      SOC_SINGLE("Capture Timestamp Reset", FSL_SAI_RTCTL, 8, 1, 0),
++      SOC_SINGLE("Capture Bit Counter Reset", FSL_SAI_RTCTL, 9, 1, 0),
++      SOC_SINGLE_REG_RO("Capture Timestamp Counter", FSL_SAI_RTCTN),
++      SOC_SINGLE_REG_RO("Capture Bit Counter", FSL_SAI_RBCTN),
++      SOC_SINGLE_REG_RO("Capture Latched Timestamp Counter", FSL_SAI_RTCAP),
++};
++
++static int fsl_sai_pcm_new(struct snd_soc_pcm_runtime *rtd,
++                         struct snd_soc_dai *dai)
++{
++      struct fsl_sai *sai = dev_get_drvdata(dai->dev);
++      struct snd_pcm *pcm = rtd->pcm;
++      bool ts_enabled = sai->verid.timestamp_en;
++      struct snd_soc_component *comp = dai->component;
++
++      if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
++              snd_soc_add_component_controls(comp, fsl_sai_pb_ctrls,
++                                             ARRAY_SIZE(fsl_sai_pb_ctrls));
++
++      if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
++              snd_soc_add_component_controls(comp, fsl_sai_cp_ctrls,
++                                             ARRAY_SIZE(fsl_sai_cp_ctrls));
++      return 0;
++}
++
+ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
+ {
+       struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
+@@ -1030,6 +1114,7 @@ static int fsl_sai_dai_resume(struct snd
+ }
+ static struct snd_soc_dai_driver fsl_sai_dai = {
++      .pcm_new = fsl_sai_pcm_new,
+       .probe = fsl_sai_dai_probe,
+       .playback = {
+               .stream_name = "CPU-Playback",
+@@ -1054,7 +1139,7 @@ static struct snd_soc_dai_driver fsl_sai
+ };
+ static const struct snd_soc_component_driver fsl_component = {
+-      .name           = "fsl-sai",
++      .name   = "fsl-sai",
+ };
+ static struct reg_default fsl_sai_v2_reg_defaults[] = {
+@@ -1141,6 +1226,14 @@ static bool fsl_sai_readable_reg(struct
+       case FSL_SAI_MDIV:
+       case FSL_SAI_VERID:
+       case FSL_SAI_PARAM:
++      case FSL_SAI_TTCTN:
++      case FSL_SAI_RTCTN:
++      case FSL_SAI_TTCTL:
++      case FSL_SAI_TBCTN:
++      case FSL_SAI_TTCAP:
++      case FSL_SAI_RTCTL:
++      case FSL_SAI_RBCTN:
++      case FSL_SAI_RTCAP:
+               return true;
+       default:
+               return false;
+@@ -1214,6 +1307,8 @@ static bool fsl_sai_writeable_reg(struct
+       case FSL_SAI_RMR:
+       case FSL_SAI_MCTL:
+       case FSL_SAI_MDIV:
++      case FSL_SAI_TTCTL:
++      case FSL_SAI_RTCTL:
+               return true;
+       default:
+               return false;
+--- a/sound/soc/fsl/fsl_sai.h
++++ b/sound/soc/fsl/fsl_sai.h
+@@ -210,6 +210,12 @@
+ #define SAI_FLAG_PMQOS   BIT(0)
++/* SAI timestamp and bitcounter */
++#define FSL_SAI_xTCTL_TSEN BIT(0)
++#define FSL_SAI_xTCTL_TSINC BIT(1)
++#define FSL_SAI_xTCTL_RTSC BIT(8)
++#define FSL_SAI_xTCTL_RBC BIT(9)
++
+ struct fsl_sai_soc_data {
+       unsigned int fifo_depth;
+       unsigned int fifos;