Merge branch 'asoc-5.3' into asoc-5.4
authorMark Brown <broonie@kernel.org>
Tue, 20 Aug 2019 17:28:43 +0000 (18:28 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 20 Aug 2019 17:28:43 +0000 (18:28 +0100)
18 files changed:
MAINTAINERS
sound/soc/amd/raven/acp3x-pcm-dma.c
sound/soc/codecs/hdac_hda.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/max98373.c
sound/soc/codecs/max98373.h
sound/soc/codecs/wm8737.c
sound/soc/codecs/wm8904.c
sound/soc/fsl/imx-audmux.c
sound/soc/intel/boards/sof_rt5682.c
sound/soc/meson/Kconfig
sound/soc/meson/axg-tdm-formatter.c
sound/soc/rockchip/rockchip_max98090.c
sound/soc/sh/rcar/adg.c
sound/soc/sof/intel/hda.c
sound/soc/sunxi/sun4i-i2s.c
sound/soc/uniphier/aio-cpu.c
sound/soc/uniphier/aio.h

index 22b2206722766c575649ed64e05597a98ccd15f0..24e29b2e53c911156fbcf7d560e80912afade4c6 100644 (file)
@@ -8044,6 +8044,7 @@ S:        Maintained
 F:     drivers/video/fbdev/i810/
 
 INTEL ASoC DRIVERS
+M:     Cezary Rojewski <cezary.rojewski@intel.com>
 M:     Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
 M:     Liam Girdwood <liam.r.girdwood@linux.intel.com>
 M:     Jie Yang <yang.jie@linux.intel.com>
index a4ade6bb5bebea57f499f3d113eff5eec14ada1d..bc4dfafdfcd12757f76e4f78ee12b3ebb89acd62 100644 (file)
@@ -31,8 +31,8 @@ struct i2s_stream_instance {
        u16 num_pages;
        u16 channels;
        u32 xfer_resolution;
-       struct page *pg;
        u64 bytescount;
+       dma_addr_t dma_addr;
        void __iomem *acp3x_base;
 };
 
@@ -211,9 +211,8 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
 static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
 {
        u16 page_idx;
-       u64 addr;
        u32 low, high, val, acp_fifo_addr;
-       struct page *pg = rtd->pg;
+       dma_addr_t addr = rtd->dma_addr;
 
        /* 8 scratch registers used to map one 64 bit address */
        if (direction == SNDRV_PCM_STREAM_PLAYBACK)
@@ -229,7 +228,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
 
        for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
                /* Load the low address of page int ACP SRAM through SRBM */
-               addr = page_to_phys(pg);
                low = lower_32_bits(addr);
                high = upper_32_bits(addr);
 
@@ -239,7 +237,7 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
                                + 4);
                /* Move to next physically contiguos page */
                val += 8;
-               pg++;
+               addr += PAGE_SIZE;
        }
 
        if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -341,7 +339,6 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
 {
        int status;
        u64 size;
-       struct page *pg;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct i2s_stream_instance *rtd = runtime->private_data;
 
@@ -354,9 +351,8 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
                return status;
 
        memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
-       pg = virt_to_page(substream->dma_buffer.area);
-       if (pg) {
-               rtd->pg = pg;
+       if (substream->dma_buffer.area) {
+               rtd->dma_addr = substream->dma_buffer.addr;
                rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
                config_acp3x_dma(rtd, substream->stream);
                status = 0;
@@ -385,9 +381,11 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
 
 static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd,
+                                                                   DRV_NAME);
+       struct device *parent = component->dev->parent;
        snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
-                                             rtd->pcm->card->dev,
-                                             MIN_BUFFER, MAX_BUFFER);
+                                             parent, MIN_BUFFER, MAX_BUFFER);
        return 0;
 }
 
index 7d494025691498e8bb93cb3fe7b93b207c4a014f..91242b6f8ea7adf27e05f2883397f932a2f1688e 100644 (file)
@@ -495,6 +495,10 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev)
 
 static int hdac_hda_dev_remove(struct hdac_device *hdev)
 {
+       struct hdac_hda_priv *hda_pvt;
+
+       hda_pvt = dev_get_drvdata(&hdev->dev);
+       cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work);
        return 0;
 }
 
index 29918954e74078bd8a14ffbe63017a99ae9e38b6..18c173e6a13b2867b2bb922a16e98a5680c07512 100644 (file)
@@ -88,8 +88,10 @@ struct hdac_hdmi_port {
        hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
        struct hdac_hdmi_eld eld;
        const char *jack_pin;
+       bool is_connect;
        struct snd_soc_dapm_context *dapm;
        const char *output_pin;
+       struct work_struct dapm_work;
 };
 
 struct hdac_hdmi_pcm {
@@ -163,11 +165,7 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
 {
        struct hdac_device *hdev = port->pin->hdev;
 
-       if (is_connect)
-               snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
-       else
-               snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
-
+       port->is_connect = is_connect;
        if (is_connect) {
                /*
                 * Report Jack connect event when a device is connected
@@ -193,10 +191,32 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
                if (pcm->jack_event > 0)
                        pcm->jack_event--;
        }
+}
 
+static void hdac_hdmi_port_dapm_update(struct hdac_hdmi_port *port)
+{
+       if (port->is_connect)
+               snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
+       else
+               snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
        snd_soc_dapm_sync(port->dapm);
 }
 
+static void hdac_hdmi_jack_dapm_work(struct work_struct *work)
+{
+       struct hdac_hdmi_port *port;
+
+       port = container_of(work, struct hdac_hdmi_port, dapm_work);
+       hdac_hdmi_port_dapm_update(port);
+}
+
+static void hdac_hdmi_jack_report_sync(struct hdac_hdmi_pcm *pcm,
+               struct hdac_hdmi_port *port, bool is_connect)
+{
+       hdac_hdmi_jack_report(pcm, port, is_connect);
+       hdac_hdmi_port_dapm_update(port);
+}
+
 /* MST supported verbs */
 /*
  * Get the no devices that can be connected to a port on the Pin widget.
@@ -904,7 +924,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
                list_for_each_entry_safe(p, p_next, &pcm->port_list, head) {
                        if (p == port && p->id == port->id &&
                                        p->pin == port->pin) {
-                               hdac_hdmi_jack_report(pcm, port, false);
+                               hdac_hdmi_jack_report_sync(pcm, port, false);
                                list_del(&p->head);
                        }
                }
@@ -918,7 +938,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
                if (!strcmp(cvt_name, pcm->cvt->name)) {
                        list_add_tail(&port->head, &pcm->port_list);
                        if (port->eld.monitor_present && port->eld.eld_valid) {
-                               hdac_hdmi_jack_report(pcm, port, true);
+                               hdac_hdmi_jack_report_sync(pcm, port, true);
                                mutex_unlock(&hdmi->pin_mutex);
                                return ret;
                        }
@@ -1281,16 +1301,20 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
                 * report jack here. It will be done in usermode mux
                 * control select.
                 */
-               if (pcm)
+               if (pcm) {
                        hdac_hdmi_jack_report(pcm, port, false);
+                       schedule_work(&port->dapm_work);
+               }
 
                mutex_unlock(&hdmi->pin_mutex);
                return;
        }
 
        if (port->eld.monitor_present && port->eld.eld_valid) {
-               if (pcm)
+               if (pcm) {
                        hdac_hdmi_jack_report(pcm, port, true);
+                       schedule_work(&port->dapm_work);
+               }
 
                print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
                          port->eld.eld_buffer, port->eld.eld_size, false);
@@ -1319,6 +1343,7 @@ static int hdac_hdmi_add_ports(struct hdac_device *hdev,
        for (i = 0; i < max_ports; i++) {
                ports[i].id = i;
                ports[i].pin = pin;
+               INIT_WORK(&ports[i].dapm_work, hdac_hdmi_jack_dapm_work);
        }
        pin->ports = ports;
        pin->num_ports = max_ports;
@@ -2083,8 +2108,20 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
        return ret;
 }
 
+static void clear_dapm_works(struct hdac_device *hdev)
+{
+       struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
+       struct hdac_hdmi_pin *pin;
+       int i;
+
+       list_for_each_entry(pin, &hdmi->pin_list, head)
+               for (i = 0; i < pin->num_ports; i++)
+                       cancel_work_sync(&pin->ports[i].dapm_work);
+}
+
 static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
 {
+       clear_dapm_works(hdev);
        snd_hdac_display_power(hdev->bus, hdev->addr, false);
 
        return 0;
@@ -2103,6 +2140,8 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
        if (!bus)
                return 0;
 
+       clear_dapm_works(hdev);
+
        /*
         * Power down afg.
         * codec_read is preferred over codec_write to set the power state.
index 9a1eb7222357d2b8d38a2d81b3c9a121b2b23f55..e609abcf3220e71f9c600cec0aebf71067fb2003 100644 (file)
@@ -268,6 +268,12 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
        case 48000:
                sampling_rate = MAX98373_PCM_SR_SET1_SR_48000;
                break;
+       case 88200:
+               sampling_rate = MAX98373_PCM_SR_SET1_SR_88200;
+               break;
+       case 96000:
+               sampling_rate = MAX98373_PCM_SR_SET1_SR_96000;
+               break;
        default:
                dev_err(component->dev, "rate %d not supported\n",
                        params_rate(params));
index 533d2053f6087d95a7707a30a31088b43861456e..63dae8be7105b2aa5c61c509f16c5dd9bd1b402b 100644 (file)
 #define MAX98373_PCM_SR_SET1_SR_32000 (0x6 << 0)
 #define MAX98373_PCM_SR_SET1_SR_44100 (0x7 << 0)
 #define MAX98373_PCM_SR_SET1_SR_48000 (0x8 << 0)
+#define MAX98373_PCM_SR_SET1_SR_88200 (0x9 << 0)
+#define MAX98373_PCM_SR_SET1_SR_96000 (0xA << 0)
 
 /* MAX98373_R2028_PCM_SR_SETUP_2 */
 #define MAX98373_PCM_SR_SET2_SR_MASK (0xF << 4)
index 0c246fb5e5ac1dddc7d027f3242bfb33cd6bbff8..7a3f9fbe8d53d8677649a690ec1a8e581f4ad215 100644 (file)
@@ -167,7 +167,7 @@ SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
 SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
 SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
 SOC_ENUM("3D Low Cut-off", low_3d),
-SOC_ENUM("3D High Cut-off", low_3d),
+SOC_ENUM("3D High Cut-off", high_3d),
 SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
 
 SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
index 5ebdd1d9afdeab2ccb038c989794dbbdee49301f..bcb3c9d5abf0c68df3b519024b9df52021e22fbf 100644 (file)
@@ -545,18 +545,6 @@ static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
 static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
 
-static const char *input_mode_text[] = {
-       "Single-Ended", "Differential Line", "Differential Mic"
-};
-
-static SOC_ENUM_SINGLE_DECL(lin_mode,
-                           WM8904_ANALOGUE_LEFT_INPUT_1, 0,
-                           input_mode_text);
-
-static SOC_ENUM_SINGLE_DECL(rin_mode,
-                           WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
-                           input_mode_text);
-
 static const char *hpf_mode_text[] = {
        "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
 };
@@ -591,9 +579,6 @@ static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
 SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
                 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
 
-SOC_ENUM("Left Capture Mode", lin_mode),
-SOC_ENUM("Right Capture Mode", rin_mode),
-
 /* No TLV since it depends on mode */
 SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
             WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
@@ -852,6 +837,10 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static const char *input_mode_text[] = {
+       "Single-Ended", "Differential Line", "Differential Mic"
+};
+
 static const char *lin_text[] = {
        "IN1L", "IN2L", "IN3L"
 };
@@ -866,7 +855,14 @@ static SOC_ENUM_SINGLE_DECL(lin_inv_enum, WM8904_ANALOGUE_LEFT_INPUT_1, 4,
                            lin_text);
 
 static const struct snd_kcontrol_new lin_inv_mux =
-       SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
+       SOC_DAPM_ENUM("Left Capture Inverting Mux", lin_inv_enum);
+
+static SOC_ENUM_SINGLE_DECL(lin_mode_enum,
+                           WM8904_ANALOGUE_LEFT_INPUT_1, 0,
+                           input_mode_text);
+
+static const struct snd_kcontrol_new lin_mode =
+       SOC_DAPM_ENUM("Left Capture Mode", lin_mode_enum);
 
 static const char *rin_text[] = {
        "IN1R", "IN2R", "IN3R"
@@ -882,7 +878,14 @@ static SOC_ENUM_SINGLE_DECL(rin_inv_enum, WM8904_ANALOGUE_RIGHT_INPUT_1, 4,
                            rin_text);
 
 static const struct snd_kcontrol_new rin_inv_mux =
-       SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
+       SOC_DAPM_ENUM("Right Capture Inverting Mux", rin_inv_enum);
+
+static SOC_ENUM_SINGLE_DECL(rin_mode_enum,
+                           WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
+                           input_mode_text);
+
+static const struct snd_kcontrol_new rin_mode =
+       SOC_DAPM_ENUM("Right Capture Mode", rin_mode_enum);
 
 static const char *aif_text[] = {
        "Left", "Right"
@@ -932,9 +935,11 @@ SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
 SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
 SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
                 &lin_inv_mux),
+SND_SOC_DAPM_MUX("Left Capture Mode", SND_SOC_NOPM, 0, 0, &lin_mode),
 SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
 SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
                 &rin_inv_mux),
+SND_SOC_DAPM_MUX("Right Capture Mode", SND_SOC_NOPM, 0, 0, &rin_mode),
 
 SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
                 NULL, 0),
@@ -1057,6 +1062,12 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
        { "Left Capture Inverting Mux", "IN2L", "IN2L" },
        { "Left Capture Inverting Mux", "IN3L", "IN3L" },
 
+       { "Left Capture Mode", "Single-Ended", "Left Capture Inverting Mux" },
+       { "Left Capture Mode", "Differential Line", "Left Capture Mux" },
+       { "Left Capture Mode", "Differential Line", "Left Capture Inverting Mux" },
+       { "Left Capture Mode", "Differential Mic", "Left Capture Mux" },
+       { "Left Capture Mode", "Differential Mic", "Left Capture Inverting Mux" },
+
        { "Right Capture Mux", "IN1R", "IN1R" },
        { "Right Capture Mux", "IN2R", "IN2R" },
        { "Right Capture Mux", "IN3R", "IN3R" },
@@ -1065,11 +1076,14 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
        { "Right Capture Inverting Mux", "IN2R", "IN2R" },
        { "Right Capture Inverting Mux", "IN3R", "IN3R" },
 
-       { "Left Capture PGA", NULL, "Left Capture Mux" },
-       { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
+       { "Right Capture Mode", "Single-Ended", "Right Capture Inverting Mux" },
+       { "Right Capture Mode", "Differential Line", "Right Capture Mux" },
+       { "Right Capture Mode", "Differential Line", "Right Capture Inverting Mux" },
+       { "Right Capture Mode", "Differential Mic", "Right Capture Mux" },
+       { "Right Capture Mode", "Differential Mic", "Right Capture Inverting Mux" },
 
-       { "Right Capture PGA", NULL, "Right Capture Mux" },
-       { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
+       { "Left Capture PGA", NULL, "Left Capture Mode" },
+       { "Right Capture PGA", NULL, "Right Capture Mode" },
 
        { "AIFOUTL Mux", "Left", "ADCL" },
        { "AIFOUTL Mux", "Right", "ADCR" },
index 7595f24a006e544d515f4cee1f29ba408e7c1f19..3ce85a43e08f23a0a5eae2fd833d54edab9eb247 100644 (file)
@@ -23,6 +23,8 @@
 
 static struct clk *audmux_clk;
 static void __iomem *audmux_base;
+static u32 *regcache;
+static u32 reg_max;
 
 #define IMX_AUDMUX_V2_PTCR(x)          ((x) * 8)
 #define IMX_AUDMUX_V2_PDCR(x)          ((x) * 8 + 4)
@@ -315,8 +317,23 @@ static int imx_audmux_probe(struct platform_device *pdev)
        if (of_id)
                pdev->id_entry = of_id->data;
        audmux_type = pdev->id_entry->driver_data;
-       if (audmux_type == IMX31_AUDMUX)
+
+       switch (audmux_type) {
+       case IMX31_AUDMUX:
                audmux_debugfs_init();
+               reg_max = 14;
+               break;
+       case IMX21_AUDMUX:
+               reg_max = 6;
+               break;
+       default:
+               dev_err(&pdev->dev, "unsupported version!\n");
+               return -EINVAL;
+       }
+
+       regcache = devm_kzalloc(&pdev->dev, sizeof(u32) * reg_max, GFP_KERNEL);
+       if (!regcache)
+               return -ENOMEM;
 
        if (of_id)
                imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
@@ -332,12 +349,47 @@ static int imx_audmux_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int imx_audmux_suspend(struct device *dev)
+{
+       int i;
+
+       clk_prepare_enable(audmux_clk);
+
+       for (i = 0; i < reg_max; i++)
+               regcache[i] = readl(audmux_base + i * 4);
+
+       clk_disable_unprepare(audmux_clk);
+
+       return 0;
+}
+
+static int imx_audmux_resume(struct device *dev)
+{
+       int i;
+
+       clk_prepare_enable(audmux_clk);
+
+       for (i = 0; i < reg_max; i++)
+               writel(regcache[i], audmux_base + i * 4);
+
+       clk_disable_unprepare(audmux_clk);
+
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops imx_audmux_pm = {
+       SET_SYSTEM_SLEEP_PM_OPS(imx_audmux_suspend, imx_audmux_resume)
+};
+
 static struct platform_driver imx_audmux_driver = {
        .probe          = imx_audmux_probe,
        .remove         = imx_audmux_remove,
        .id_table       = imx_audmux_ids,
        .driver = {
                .name   = DRIVER_NAME,
+               .pm = &imx_audmux_pm,
                .of_match_table = imx_audmux_dt_ids,
        }
 };
index c1181bc0119e823492b66cfc95e60d30b6e01757..a437567b8cee233a0dbebd52dfe1c70fe952dcce 100644 (file)
@@ -308,6 +308,7 @@ static const struct snd_soc_dapm_widget sof_widgets[] = {
        SND_SOC_DAPM_HP("Headphone Jack", NULL),
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
        SND_SOC_DAPM_SPK("Spk", NULL),
+       SND_SOC_DAPM_MIC("SoC DMIC", NULL),
 };
 
 static const struct snd_soc_dapm_route sof_map[] = {
@@ -318,6 +319,9 @@ static const struct snd_soc_dapm_route sof_map[] = {
        /* other jacks */
        { "IN1P", NULL, "Headset Mic" },
 
+       /* digital mics */
+       {"DMic", NULL, "SoC DMIC"},
+
 };
 
 static const struct snd_soc_dapm_route speaker_map[] = {
index 63b38c123103a8d8eeee7335ae719aa219be4648..2e3676147ceafa610a2a6c918f330ec143dfbcb4 100644 (file)
@@ -87,6 +87,7 @@ config SND_MESON_AXG_PDM
 
 config SND_MESON_G12A_TOHDMITX
        tristate "Amlogic G12A To HDMI TX Control Support"
+       select REGMAP_MMIO
        imply SND_SOC_HDMI_CODEC
        help
          Select Y or M to add support for HDMI audio on the g12a SoC
index 21c735afab35448cfcaeaa14c74a7f599079a743..358c8c0d861cd79dc3af06a8f89d972cd8d8c93f 100644 (file)
@@ -325,7 +325,7 @@ int axg_tdm_formatter_probe(struct platform_device *pdev)
        }
 
        /* Formatter dedicated reset line */
-       formatter->reset = reset_control_get_optional_exclusive(dev, NULL);
+       formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
        if (IS_ERR(formatter->reset)) {
                ret = PTR_ERR(formatter->reset);
                if (ret != -EPROBE_DEFER)
index 7b0c21fa6dca0dea67054e4a61d59ff6bb25a81d..0097df1fae662f1d5a25af1daf36ddfc5bfb20cc 100644 (file)
@@ -137,8 +137,19 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
        return ret;
 }
 
+static int rk_aif1_startup(struct snd_pcm_substream *substream)
+{
+       /*
+        * Set period size to 240 because pl330 has issue
+        * dealing with larger period in stress testing.
+        */
+       return snd_pcm_hw_constraint_minmax(substream->runtime,
+                       SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 240, 240);
+}
+
 static const struct snd_soc_ops rk_aif1_ops = {
        .hw_params = rk_aif1_hw_params,
+       .startup = rk_aif1_startup,
 };
 
 SND_SOC_DAILINK_DEFS(hifi,
index fce4e050a9b70567700f577363de8493d71d85d3..b9aacf3d3b29c9b0de99830a568371edbffffbe8 100644 (file)
@@ -30,6 +30,7 @@ struct rsnd_adg {
        struct clk *clkout[CLKOUTMAX];
        struct clk_onecell_data onecell;
        struct rsnd_mod mod;
+       int clk_rate[CLKMAX];
        u32 flags;
        u32 ckr;
        u32 rbga;
@@ -114,9 +115,9 @@ static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
        unsigned int val, en;
        unsigned int min, diff;
        unsigned int sel_rate[] = {
-               clk_get_rate(adg->clk[CLKA]),   /* 0000: CLKA */
-               clk_get_rate(adg->clk[CLKB]),   /* 0001: CLKB */
-               clk_get_rate(adg->clk[CLKC]),   /* 0010: CLKC */
+               adg->clk_rate[CLKA],    /* 0000: CLKA */
+               adg->clk_rate[CLKB],    /* 0001: CLKB */
+               adg->clk_rate[CLKC],    /* 0010: CLKC */
                adg->rbga_rate_for_441khz,      /* 0011: RBGA */
                adg->rbgb_rate_for_48khz,       /* 0100: RBGB */
        };
@@ -302,7 +303,7 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
         * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
         */
        for_each_rsnd_clk(clk, adg, i) {
-               if (rate == clk_get_rate(clk))
+               if (rate == adg->clk_rate[i])
                        return sel_table[i];
        }
 
@@ -369,10 +370,18 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
 
        for_each_rsnd_clk(clk, adg, i) {
                ret = 0;
-               if (enable)
+               if (enable) {
                        ret = clk_prepare_enable(clk);
-               else
+
+                       /*
+                        * We shouldn't use clk_get_rate() under
+                        * atomic context. Let's keep it when
+                        * rsnd_adg_clk_enable() was called
+                        */
+                       adg->clk_rate[i] = clk_get_rate(adg->clk[i]);
+               } else {
                        clk_disable_unprepare(clk);
+               }
 
                if (ret < 0)
                        dev_warn(dev, "can't use clk %d\n", i);
index c97c004afa4322334d61e2381b695d7b5bd10e56..c72e9a09eee16a03da41267f127fdf0dbfc1b95d 100644 (file)
@@ -357,10 +357,23 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
        if (bus->ppcap)
                dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n");
 
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+       /* init i915 and HDMI codecs */
+       ret = hda_codec_i915_init(sdev);
+       if (ret < 0) {
+               dev_err(sdev->dev, "error: init i915 and HDMI codec failed\n");
+               return ret;
+       }
+#endif
+
+       /* Init HDA controller after i915 init */
        ret = hda_dsp_ctrl_init_chip(sdev, true);
        if (ret < 0) {
                dev_err(bus->dev, "error: init chip failed with ret: %d\n",
                        ret);
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+               hda_codec_i915_exit(sdev);
+#endif
                return ret;
        }
 
@@ -368,13 +381,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
        if (bus->mlcap)
                snd_hdac_ext_bus_get_ml_capabilities(bus);
 
-       /* init i915 and HDMI codecs */
-       ret = hda_codec_i915_init(sdev);
-       if (ret < 0) {
-               dev_err(sdev->dev, "error: no HDMI audio devices found\n");
-               return ret;
-       }
-
        /* codec detection */
        if (!bus->codec_mask) {
                dev_info(bus->dev, "no hda codecs found!\n");
index 0a5fb9d4b2890fc400799b59a438f5bcfa9b587f..2c909c6cafa9059ca6eaeaf62d0b6b51d85a70da 100644 (file)
@@ -1000,8 +1000,8 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
        .field_rxchanmap        = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
        .field_txchansel        = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
        .field_rxchansel        = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
-       .get_sr                 = sun8i_i2s_get_sr_wss,
-       .get_wss                = sun8i_i2s_get_sr_wss,
+       .get_sr                 = sun4i_i2s_get_sr,
+       .get_wss                = sun4i_i2s_get_wss,
 };
 
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
@@ -1144,11 +1144,9 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
                        goto err_pm_disable;
        }
 
-       ret = devm_snd_soc_register_component(&pdev->dev,
-                                             &sun4i_i2s_component,
-                                             &sun4i_i2s_dai, 1);
+       ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
        if (ret) {
-               dev_err(&pdev->dev, "Could not register DAI\n");
+               dev_err(&pdev->dev, "Could not initialise regmap fields\n");
                goto err_suspend;
        }
 
@@ -1158,9 +1156,11 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
                goto err_suspend;
        }
 
-       ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &sun4i_i2s_component,
+                                             &sun4i_i2s_dai, 1);
        if (ret) {
-               dev_err(&pdev->dev, "Could not initialise regmap fields\n");
+               dev_err(&pdev->dev, "Could not register DAI\n");
                goto err_suspend;
        }
 
index ee90e6c3937ce31e0dfb025a1c627b695c35a0a3..2ae582a99b636e3637dd6f7c2200403627fadd23 100644 (file)
@@ -424,8 +424,11 @@ int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
 {
        struct uniphier_aio *aio = uniphier_priv(dai);
 
-       reset_control_assert(aio->chip->rst);
-       clk_disable_unprepare(aio->chip->clk);
+       aio->chip->num_wup_aios--;
+       if (!aio->chip->num_wup_aios) {
+               reset_control_assert(aio->chip->rst);
+               clk_disable_unprepare(aio->chip->clk);
+       }
 
        return 0;
 }
@@ -439,13 +442,15 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
        if (!aio->chip->active)
                return 0;
 
-       ret = clk_prepare_enable(aio->chip->clk);
-       if (ret)
-               return ret;
+       if (!aio->chip->num_wup_aios) {
+               ret = clk_prepare_enable(aio->chip->clk);
+               if (ret)
+                       return ret;
 
-       ret = reset_control_deassert(aio->chip->rst);
-       if (ret)
-               goto err_out_clock;
+               ret = reset_control_deassert(aio->chip->rst);
+               if (ret)
+                       goto err_out_clock;
+       }
 
        aio_iecout_set_enable(aio->chip, true);
        aio_chip_init(aio->chip);
@@ -458,7 +463,7 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
 
                ret = aio_init(sub);
                if (ret)
-                       goto err_out_clock;
+                       goto err_out_reset;
 
                if (!sub->setting)
                        continue;
@@ -466,11 +471,16 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
                aio_port_reset(sub);
                aio_src_reset(sub);
        }
+       aio->chip->num_wup_aios++;
 
        return 0;
 
+err_out_reset:
+       if (!aio->chip->num_wup_aios)
+               reset_control_assert(aio->chip->rst);
 err_out_clock:
-       clk_disable_unprepare(aio->chip->clk);
+       if (!aio->chip->num_wup_aios)
+               clk_disable_unprepare(aio->chip->clk);
 
        return ret;
 }
@@ -619,6 +629,7 @@ int uniphier_aio_probe(struct platform_device *pdev)
                return PTR_ERR(chip->rst);
 
        chip->num_aios = chip->chip_spec->num_dais;
+       chip->num_wup_aios = chip->num_aios;
        chip->aios = devm_kcalloc(dev,
                                  chip->num_aios, sizeof(struct uniphier_aio),
                                  GFP_KERNEL);
index ca6ccbae0ee8c2f6f89437ed1d9c18c8986c6607..a7ff7e556429ba15345f54bfc94f71a1ef549f66 100644 (file)
@@ -285,6 +285,7 @@ struct uniphier_aio_chip {
 
        struct uniphier_aio *aios;
        int num_aios;
+       int num_wup_aios;
        struct uniphier_aio_pll *plls;
        int num_plls;