From 6963d00bb6e42e91882d2eb36639701aca9fe032 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 26 Jul 2019 20:15:17 +0200 Subject: [PATCH 01/23] MAINTAINERS: Update Intel ASoC drivers maintainers Adding myself to Intel ASoC drivers maintainers list. Signed-off-by: Cezary Rojewski Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190726181517.27655-1-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 11db05b56744..92829ca37459 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7861,6 +7861,7 @@ S: Maintained F: drivers/video/fbdev/i810/ INTEL ASoC DRIVERS +M: Cezary Rojewski M: Pierre-Louis Bossart M: Liam Girdwood M: Jie Yang From 52f87f3ca251f5e43b42e78ab9816b2b07718bfe Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Mon, 29 Jul 2019 17:21:30 +0200 Subject: [PATCH 02/23] ASoC: sun4i-i2s: Incorrect SR and WSS computation The A64 audio codec uses the original I2S block but the SR and WSS computation currently assigned is for the newer block. Fixes: 619c15f7fac9 (ASoC: sun4i-i2s: Change SR and WSS computation) Signed-off-by: Marcus Cooper Link: https://lore.kernel.org/r/20190729152130.27955-1-codekipper@gmail.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 9b2232908b65..7fa5c61169db 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -1002,8 +1002,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, From b9da500bde81ad820b5d95c6bf52fc33e1f490ee Mon Sep 17 00:00:00 2001 From: fengchunguo Date: Wed, 31 Jul 2019 15:41:56 +0800 Subject: [PATCH 03/23] ASoC: max98373: add 88200 and 96000 sampling rate support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 88200 and 96000 sampling rate was not enabled on driver, so can't be played. The error information: max98373 3-0031:rate 96000 not supported max98373 3-0031:ASoC: can't set max98373-aif1 hw params: -22 Signed-off-by: fengchunguo Link: https://lore.kernel.org/r/20190731074156.5620-1-chunguo.feng@amlogic.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98373.c | 6 ++++++ sound/soc/codecs/max98373.h | 2 ++ 2 files changed, 8 insertions(+) mode change 100644 => 100755 sound/soc/codecs/max98373.c mode change 100644 => 100755 sound/soc/codecs/max98373.h diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c old mode 100644 new mode 100755 index 528695cd6a1c..8c601a3ebc27 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -267,6 +267,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)); diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h old mode 100644 new mode 100755 index f6a37aa02f26..a59e51355a84 --- a/sound/soc/codecs/max98373.h +++ b/sound/soc/codecs/max98373.h @@ -130,6 +130,8 @@ #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) From 88639051017fb61a414b636dd0fc490da2b62b64 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 2 Aug 2019 19:21:23 +0530 Subject: [PATCH 04/23] ASoC: amd: acp3x: use dma_ops of parent device for acp3x dma driver AMD platform device acp3x_rv_i2s created by parent PCI device driver. Pass struct device of the parent to snd_pcm_lib_preallocate_pages() so dma_alloc_coherent() can use correct dma_ops. Otherwise, it will use default dma_ops which is nommu_dma_ops on x86_64 even when IOMMU is enabled and set to non passthrough mode. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/1564753899-17124-1-git-send-email-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/raven/acp3x-pcm-dma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index a4ade6bb5beb..905ed2f1861b 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -385,9 +385,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; } From 30c21734d853dae99d05a5295a59b7e26ccd5135 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 2 Aug 2019 19:21:24 +0530 Subject: [PATCH 05/23] ASoC: amd: acp3x: use dma address for acp3x dma driver We shouldn't assume CPU physical address we get from page_to_phys() is same as DMA address we get from dma_alloc_coherent(). On x86_64, we won't run into any problem with the assumption when dma_ops is nommu_dma_ops. However, DMA address is IOVA when IOMMU is enabled. And it's most likely different from CPU physical address when AMD IOMMU is not in passthrough mode. This patch fixes page faults when IOMMU is enabled. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/1564753899-17124-2-git-send-email-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/raven/acp3x-pcm-dma.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index 905ed2f1861b..bc4dfafdfcd1 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -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; From 7c0767643f3b6b0dd2cda923ae37a18590d431cf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 6 Aug 2019 11:15:06 +0100 Subject: [PATCH 06/23] ASoC: max98373: Remove executable bits Signed-off-by: Mark Brown --- sound/soc/codecs/max98373.c | 0 sound/soc/codecs/max98373.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 sound/soc/codecs/max98373.c mode change 100755 => 100644 sound/soc/codecs/max98373.h diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c old mode 100755 new mode 100644 diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h old mode 100755 new mode 100644 From 06e8f5c842f2dbb232897ba967ea7b422745c271 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 6 Aug 2019 12:45:38 +0900 Subject: [PATCH 07/23] ASoC: rsnd: don't call clk_get_rate() under atomic context ADG is using clk_get_rate() under atomic context, thus, we might have scheduling issue. To avoid this issue, we need to get/keep clk rate under non atomic context. We need to handle ADG as special device at Renesas Sound driver. From SW point of view, we want to impletent it as rsnd_mod_ops :: prepare, but it makes code just complicate. To avoid complicated code/patch, this patch adds new clk_rate[] array, and keep clk IN rate when rsnd_adg_clk_enable() was called. Reported-by: Leon Kong Signed-off-by: Kuninori Morimoto Tested-by: Leon Kong Link: https://lore.kernel.org/r/87v9vb0xkp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index fce4e050a9b7..b9aacf3d3b29 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -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); From cc352735d49c9c25fd711795bee35d3d001ddffa Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 6 Aug 2019 15:19:58 -0700 Subject: [PATCH 08/23] ASoC: SOF: Intel: hda: Initialize HDA controller after i915 init On some platforms, sound card registration fails when a HDMI monitor is not connected. This is caused by a recent commit that switched the order in which the HDA controller and the i915 are initialized. Initializing the i915 before initializing the HDA controller fixes the problem. Fixes: be1b577d01787c ("ASoC: SOF: Intel: hda: fix the hda init chip" Signed-off-by: Ranjani Sridharan Signed-off-by: Pierre-Louis Bossart Reviewed-by: Takashi Iwai Link: https://lore.kernel.org/r/20190806221958.19180-1-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 136f98bf5d7e..82f61c4e74bd 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -321,10 +321,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; } @@ -332,13 +345,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"); From 804cbf4bb063204ca6c2471baa694548aab02ce3 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 7 Aug 2019 09:50:30 -0500 Subject: [PATCH 09/23] ASoC: hdac_hda: fix page fault issue by removing race There is a race between hda codec device removing and the jack-detecting work, which will lead to a page fault issue as the latter work is accessing codec device which could be already removed. Here add the cancellation of jack-detecting work before codecs are actually removed to avoid the race and fix the issue. Bug: https://github.com/thesofproject/linux/issues/1067 Signed-off-by: Keyon Jie Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190807145030.26117-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hda.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index 7d4940256914..91242b6f8ea7 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -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; } From 332ccf00bf85adbf48015084be0e60f5cc57a055 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Aug 2019 17:15:31 +0200 Subject: [PATCH 10/23] ASoC: hdac_hdmi: Offload dapm update at jack detection hdac_hdmi_present_sense() calls the audio component to get ELD update, then it reports the jack status change and updates DAPM graph accordingly. This works when it's called from the normal code paths. However, it may lead to a dead lock when it's called from the audio component notifier. Namely, the DAPM update involves with the runtime PM, and it eventually calls again the audio component get_power() ops. Since i915 driver already takes a mutex around the audio component ops calls, we'll eventually get the mutex doubly. As a workaround, in this patch, only the jack state is updated in the code path from hdac_hdmi_eld_notify_cb(), and the DAPM update is deferred to a work so that it's processed in another context. Reported-by: Imre Deak Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20190809151531.24359-1-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 57 ++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 47eee18b66a3..11ec031ad749 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -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. @@ -873,7 +893,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); } } @@ -887,7 +907,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; } @@ -1250,16 +1270,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); @@ -1288,6 +1312,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; @@ -2052,8 +2077,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; @@ -2072,6 +2109,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. From 8afd1a99d713ccc7cf1bd509b205c3bb60cf0b90 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Fri, 9 Aug 2019 18:22:34 -0500 Subject: [PATCH 11/23] ASoC: Intel: sof-rt5682: add dmic dapm widget to support dmic PCM We need add DAPM MIC endpoint widget "SoC DMIC" and route, to enable DMIC PCM DAPM support. Signed-off-by: Keyon Jie Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190809232236.21182-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 64db00353e18..7285474f7d65 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -309,6 +309,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[] = { @@ -319,6 +320,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[] = { From 7188f656cdf762d4ea8ce16b6aaf4c6b06e119ec Mon Sep 17 00:00:00 2001 From: Cheng-Yi Chiang Date: Tue, 13 Aug 2019 15:44:30 +0800 Subject: [PATCH 12/23] ASoC: rockchip: rockchip_max98090: Set period size to 240 From stress testing of arecord, we found that period size greater than ~900 will bring pl330 to DYING state and can not recover within 100 iterations. The result is that arecord will stuck and get I/O error, and issue can not be recovered until reboot. This issue does not happen when period size is small. Set constraint of period size to 240 to prevent such issue. With the constraint, there will be no issue after 2000 iterations. We can revert this patch once the root cause is found in rockchip's pl330 implementation. Signed-off-by: Cheng-Yi Chiang Link: https://lore.kernel.org/r/20190813074430.191791-1-cychiang@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_max98090.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c index 782e534d4c0d..d54f672d38d8 100644 --- a/sound/soc/rockchip/rockchip_max98090.c +++ b/sound/soc/rockchip/rockchip_max98090.c @@ -138,8 +138,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, From 630742c296341a8cfe00dfd941392025ba8dd4e8 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 15 Aug 2019 17:23:00 +0800 Subject: [PATCH 13/23] ASoC: es8328: Fix copy-paste error in es8328_right_line_controls It seems 'es8328_rline_enum' should be used in es8328_right_line_controls Fixes: 567e4f98922c ("ASoC: add es8328 codec driver") Signed-off-by: YueHaibing Link: https://lore.kernel.org/r/20190815092300.68712-1-yuehaibing@huawei.com Signed-off-by: Mark Brown --- sound/soc/codecs/es8328.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 822a25a8f53c..69b81e704127 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -228,7 +228,7 @@ static const struct soc_enum es8328_rline_enum = ARRAY_SIZE(es8328_line_texts), es8328_line_texts); static const struct snd_kcontrol_new es8328_right_line_controls = - SOC_DAPM_ENUM("Route", es8328_lline_enum); + SOC_DAPM_ENUM("Route", es8328_rline_enum); /* Left Mixer */ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { From 9b4275c415acca6264a3d7f1182589959c93d530 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 15 Aug 2019 17:01:57 +0800 Subject: [PATCH 14/23] ASoC: cs4349: Use PM ops 'cs4349_runtime_pm' sound/soc/codecs/cs4349.c:358:32: warning: cs4349_runtime_pm defined but not used [-Wunused-const-variable=] cs4349_runtime_pm ops already defined, it seems we should enable it. Reported-by: Hulk Robot Fixes: e40da86 ("ASoC: cs4349: Add support for Cirrus Logic CS4349") Signed-off-by: YueHaibing Link: https://lore.kernel.org/r/20190815090157.70036-1-yuehaibing@huawei.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4349.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 09716fab1e26..3381209a882d 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -378,6 +378,7 @@ static struct i2c_driver cs4349_i2c_driver = { .driver = { .name = "cs4349", .of_match_table = cs4349_of_match, + .pm = &cs4349_runtime_pm, }, .id_table = cs4349_i2c_id, .probe = cs4349_i2c_probe, From 554b75bde64bcad9662530726d1483f7ef012069 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 15 Aug 2019 17:19:20 +0800 Subject: [PATCH 15/23] ASoC: wm8737: Fix copy-paste error in wm8737_snd_controls sound/soc/codecs/wm8737.c:112:29: warning: high_3d defined but not used [-Wunused-const-variable=] 'high_3d' should be used for 3D High Cut-off. Reported-by: Hulk Robot Fixes: 2a9ae13a2641 ("ASoC: Add initial WM8737 driver") Signed-off-by: YueHaibing Acked-by: Charles Keepax Link: https://lore.kernel.org/r/20190815091920.64480-1-yuehaibing@huawei.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8737.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 0c246fb5e5ac..7a3f9fbe8d53 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -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), From 8661ab5b23d6d30d8687fc05bc1dba8f9a64b444 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 16 Aug 2019 01:03:14 -0400 Subject: [PATCH 16/23] ASoC: imx-audmux: Add driver suspend and resume to support MEGA Fast For i.MX6 SoloX, there is a mode of the SoC to shutdown all power source of modules during system suspend and resume procedure. Thus, AUDMUX needs to save all the values of registers before the system suspend and restore them after the system resume. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1565931794-7218-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/imx-audmux.c | 54 +++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index b2351cd33b0f..16ede3b5cb32 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -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) @@ -317,8 +319,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); @@ -334,12 +351,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, } }; From c372a35550c8d60f673b20210eea58a06d6d38cb Mon Sep 17 00:00:00 2001 From: Kunihiko Hayashi Date: Tue, 20 Aug 2019 15:16:04 +0900 Subject: [PATCH 17/23] ASoC: uniphier: Fix double reset assersion when transitioning to suspend state When transitioning to supend state, uniphier_aio_dai_suspend() is called and asserts reset lines and disables clocks. However, if there are two or more DAIs, uniphier_aio_dai_suspend() are called multiple times, and double reset assersion will cause. This patch defines the counter that has the number of DAIs at first, and whenever uniphier_aio_dai_suspend() are called, it decrements the counter. And only if the counter is zero, it asserts reset lines and disables clocks. In the same way, uniphier_aio_dai_resume() are called, it increments the counter after deasserting reset lines and enabling clocks. Fixes: 139a34200233 ("ASoC: uniphier: add support for UniPhier AIO CPU DAI driver") Signed-off-by: Kunihiko Hayashi Link: https://lore.kernel.org/r/1566281764-14059-1-git-send-email-hayashi.kunihiko@socionext.com Signed-off-by: Mark Brown --- sound/soc/uniphier/aio-cpu.c | 31 +++++++++++++++++++++---------- sound/soc/uniphier/aio.h | 1 + 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c index ee90e6c3937c..2ae582a99b63 100644 --- a/sound/soc/uniphier/aio-cpu.c +++ b/sound/soc/uniphier/aio-cpu.c @@ -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); diff --git a/sound/soc/uniphier/aio.h b/sound/soc/uniphier/aio.h index ca6ccbae0ee8..a7ff7e556429 100644 --- a/sound/soc/uniphier/aio.h +++ b/sound/soc/uniphier/aio.h @@ -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; From 18dd62ae3bc31baa0473e4a09e46c02e0bdc57a0 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 20 Aug 2019 14:34:13 +0200 Subject: [PATCH 18/23] ASoC: meson: axg-tdm-formatter: free reset on device removal Use the devm variant to get the formatter reset so it is properly freed on device removal Fixes: 751bd5db5260 ("ASoC: meson: axg-tdm-formatter: add reset") Signed-off-by: Jerome Brunet Link: https://lore.kernel.org/r/20190820123413.22249-1-jbrunet@baylibre.com Signed-off-by: Mark Brown --- sound/soc/meson/axg-tdm-formatter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c index 2e498201139f..1a0bf9d3836d 100644 --- a/sound/soc/meson/axg-tdm-formatter.c +++ b/sound/soc/meson/axg-tdm-formatter.c @@ -327,7 +327,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) From 351b31002c1853af078ebfffd4b67bfc3d19e3dd Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 20 Aug 2019 14:35:10 +0200 Subject: [PATCH 19/23] ASoC: meson: g12a-tohdmitx: require regmap mmio The tohdmitx glue uses regmap MMIO so it should require it. Fixes: c8609f3870f7 ("ASoC: meson: add g12a tohdmitx control") Signed-off-by: Jerome Brunet Link: https://lore.kernel.org/r/20190820123510.22491-1-jbrunet@baylibre.com Signed-off-by: Mark Brown --- sound/soc/meson/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig index 63b38c123103..2e3676147cea 100644 --- a/sound/soc/meson/Kconfig +++ b/sound/soc/meson/Kconfig @@ -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 From 404be07f4ed27697f5fa69162f67a94555738595 Mon Sep 17 00:00:00 2001 From: Daniel Stuart Date: Thu, 15 Aug 2019 14:12:55 -0300 Subject: [PATCH 20/23] ASoC: intel: cht_bsw_max98090_ti: Add all Chromebooks that need pmc_plt_clk_0 quirk Every single baytrail chromebook sets PMC to 0, as can be seeing below by searching through coreboot source code: $ grep -rl "PMC_PLT_CLK\[0\]" . ./rambi/variants/glimmer/devicetree.cb ./rambi/variants/clapper/devicetree.cb ./rambi/variants/swanky/devicetree.cb ./rambi/variants/enguarde/devicetree.cb ./rambi/variants/winky/devicetree.cb ./rambi/variants/kip/devicetree.cb ./rambi/variants/squawks/devicetree.cb ./rambi/variants/orco/devicetree.cb ./rambi/variants/ninja/devicetree.cb ./rambi/variants/heli/devicetree.cb ./rambi/variants/sumo/devicetree.cb ./rambi/variants/banjo/devicetree.cb ./rambi/variants/candy/devicetree.cb ./rambi/variants/gnawty/devicetree.cb ./rambi/variants/rambi/devicetree.cb ./rambi/variants/quawks/devicetree.cb Plus, Cyan (only non-baytrail chromebook with max98090) also needs this patch for audio to work. Thus, this commit adds all the missing devices to bsw_max98090 quirk table, implemented by commit a182ecd3809c ("ASoC: intel: cht_bsw_max98090_ti: Add quirk for boards using pmc_plt_clk_0"). Signed-off-by: Daniel Stuart Link: https://lore.kernel.org/r/20190815171300.30126-1-daniel.stuart14@gmail.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 98 ++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 33eb72545be6..83b978e7b4c4 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -399,6 +399,20 @@ static struct snd_soc_card snd_soc_card_cht = { }; static const struct dmi_system_id cht_max98090_quirk_table[] = { + { + /* Banjo model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Banjo"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Candy model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Candy"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, { /* Clapper model Chromebook */ .matches = { @@ -406,6 +420,27 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = { }, .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, }, + { + /* Cyan model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Enguarde model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Enguarde"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Glimmer model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Glimmer"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, { /* Gnawty model Chromebook (Acer Chromebook CB3-111) */ .matches = { @@ -413,6 +448,62 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = { }, .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, }, + { + /* Heli model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Heli"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Kip model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Kip"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Ninja model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Ninja"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Orco model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Orco"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Quawks model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Quawks"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Rambi model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Rambi"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Squawks model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Squawks"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Sumo model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Sumo"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, { /* Swanky model Chromebook (Toshiba Chromebook 2) */ .matches = { @@ -420,6 +511,13 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = { }, .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, }, + { + /* Winky model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Winky"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, {} }; From 22afe6242387eca1ac3905fbde7bef38deb0357d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 20 Aug 2019 13:02:35 +0200 Subject: [PATCH 21/23] ASoC: wm8904: fix typo in DAPM kcontrol name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial fix for typo in "Capture Inverting Mux"es' name. Signed-off-by: Michał Mirosław Acked-by: Charles Keepax Link: https://lore.kernel.org/r/f95ae1085f9f3c137a122c4d95728711613c15f7.1566298834.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 5ebdd1d9afde..525e4ef654a1 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -866,7 +866,7 @@ 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 const char *rin_text[] = { "IN1R", "IN2R", "IN3R" @@ -882,7 +882,7 @@ 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 const char *aif_text[] = { "Left", "Right" From 0a05f2e865ad6e461cada8f931b34551287dbba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 20 Aug 2019 13:02:37 +0200 Subject: [PATCH 22/23] ASoC: wm8904: implement input mode select as a mux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make '* Capture Mode' a mux. This makes DAPM know that in single-ended mode only inverting mux paths need to be enabled. Signed-off-by: Michał Mirosław Acked-by: Charles Keepax Link: https://lore.kernel.org/r/125cd3c9f298da9b08a4d6002d4c00d70a898950.1566298834.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 52 +++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 525e4ef654a1..bcb3c9d5abf0 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -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" }; @@ -868,6 +857,13 @@ static SOC_ENUM_SINGLE_DECL(lin_inv_enum, WM8904_ANALOGUE_LEFT_INPUT_1, 4, static const struct snd_kcontrol_new lin_inv_mux = 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" }; @@ -884,6 +880,13 @@ static SOC_ENUM_SINGLE_DECL(rin_inv_enum, WM8904_ANALOGUE_RIGHT_INPUT_1, 4, static const struct snd_kcontrol_new rin_inv_mux = 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" }, From bf283a05c09b58db83afbb1a8a3c6a684c56c1bb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 19 Aug 2019 21:25:08 +0200 Subject: [PATCH 23/23] ASoC: sun4i-i2s: Register regmap and PCM before our component So far the regmap and the dmaengine PCM are registered after our component has been, which means that our driver isn't properly initialised by then. Let's fix that. Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/67e303f37f141ef73ce9ed47d7f831b63c694424.1566242458.git-series.maxime.ripard@bootlin.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-i2s.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 7fa5c61169db..85c3b2c8cd77 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -1148,11 +1148,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; } @@ -1162,9 +1160,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; }