From ecbb1b8d97a78a72003fcb19292da502d393bf80 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 6 Jul 2017 00:39:29 +0000 Subject: ASoC: hdmi-codec: ELD control corresponds to the PCM stream Current hdmi-codec driver is using hdmi_controls for "ELD" control. But, hdmi-codec driver might be used from many HDMIs. Thus, we need to correspond device number, otherwise we will receive below error. xxx: control x:x:x:ELD:x is already present This patch registers ELD control in .pcm_new by using .device = rtd->pcm->device to corresponding to PCM stream. Signed-off-by: Kuninori Morimoto [Takashi: use snd_ctl_new1()/snd_ctl_add()] Signed-off-by: Takashi Iwai Acked-by: Arnaud Pouliquen Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi-codec.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 22ed0dc88f0a..7686a80861f1 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -399,18 +399,6 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol, return 0; } - -static const struct snd_kcontrol_new hdmi_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "ELD", - .info = hdmi_eld_ctl_info, - .get = hdmi_eld_ctl_get, - }, -}; - static int hdmi_codec_new_stream(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -668,6 +656,16 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, { struct snd_soc_dai_driver *drv = dai->driver; struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + struct snd_kcontrol *kctl; + struct snd_kcontrol_new hdmi_eld_ctl = { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "ELD", + .info = hdmi_eld_ctl_info, + .get = hdmi_eld_ctl_get, + .device = rtd->pcm->device, + }; int ret; dev_dbg(dai->dev, "%s()\n", __func__); @@ -686,7 +684,12 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - return 0; + /* add ELD ctl with the device number corresponding to the PCM stream */ + kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component); + if (!kctl) + return -ENOMEM; + + return snd_ctl_add(rtd->card->snd_card, kctl); } static struct snd_soc_dai_driver hdmi_i2s_dai = { @@ -732,8 +735,6 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component, static struct snd_soc_codec_driver hdmi_codec = { .component_driver = { - .controls = hdmi_controls, - .num_controls = ARRAY_SIZE(hdmi_controls), .dapm_widgets = hdmi_widgets, .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), .dapm_routes = hdmi_routes, -- cgit v1.2.3 From 1d6463a3e23e55621101a1b9b842101988c596ff Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 11 Jul 2017 15:08:55 +0100 Subject: ASoC: hdmi-codec: make const array hdmi_codec_eld_spk_alloc_bits static Don't populate array hdmi_codec_eld_spk_alloc_bits on the stack but make it static. Makes the object code smaller by over 260 bytes: Before: text data bss dec hex filename 10882 3384 64 14330 37fa sound/soc/codecs/hdmi-codec.o After: text data bss dec hex filename 10557 3440 64 14061 36ed sound/soc/codecs/hdmi-codec.o Signed-off-by: Colin Ian King Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 7686a80861f1..509ab513b4b2 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -326,7 +326,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) { int i; - const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { + static 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, }; -- cgit v1.2.3 From e7b2e30a3f88b02b13a9bde05044142b38456004 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 30 Jun 2017 16:46:33 -0500 Subject: ASoC: kirkwood-i2s: fix error return code in kirkwood_i2s_dev_probe() platform_get_irq() returns an error code, but the kirkwood-i2s driver ignores it and always returns -ENXIO. This is not correct, and prevents -EPROBE_DEFER from being propagated properly. Notice that platform_get_irq() no longer returns 0 on error. Print and propagate the return value of platform_get_irq on failure. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 3a36d60e1785..3b09f71b9535 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -550,9 +550,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) return PTR_ERR(priv->io); priv->irq = platform_get_irq(pdev, 0); - if (priv->irq <= 0) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); - return -ENXIO; + if (priv->irq < 0) { + dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq); + return priv->irq; } if (np) { -- cgit v1.2.3 From ea4daf81fc5a37766a606479f592cd9dfe6f1da8 Mon Sep 17 00:00:00 2001 From: "oder_chiou@realtek.com" Date: Mon, 10 Jul 2017 10:03:12 +0800 Subject: ASoC: rt5514: Move the auto disable DSP function to set_bias_level() Move the auto disable DSP function from the widget event "DAPM Pre" to the set_bias_level() function to avoid the unexpected behavior. While the SPI was recording using the DAI "rt5514-dsp-cpu-dai", the event "DAPM Pre" would be manipulated even the DAPM widgets were not connected, and it also would power off the DSP that cause the DSP buffered data lost. So the auto disable DSP function should move to the set_bias_level() function to make sure that it is only manipulated by the DAPM widgets are connected. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5514.c | 49 +++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 31 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 1b6796c4c471..a71e63097aaf 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -471,35 +471,6 @@ static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, return 0; } -static int rt5514_pre_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /** - * If the DSP is enabled in start of recording, the DSP - * should be disabled, and sync back to normal recording - * settings to make sure recording properly. - */ - if (rt5514->dsp_enabled) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write(rt5514->i2c_regmap, - rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - } - break; - - default: - return 0; - } - - return 0; -} - static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { /* Input Lines */ SND_SOC_DAPM_INPUT("DMIC1L"), @@ -607,8 +578,6 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { /* Audio Interface */ SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_PRE("DAPM Pre", rt5514_pre_event), }; static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { @@ -975,6 +944,24 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec, } break; + case SND_SOC_BIAS_STANDBY: + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { + /* + * If the DSP is enabled in start of recording, the DSP + * should be disabled, and sync back to normal recording + * settings to make sure recording properly. + */ + if (rt5514->dsp_enabled) { + rt5514->dsp_enabled = 0; + regmap_multi_reg_write(rt5514->i2c_regmap, + rt5514_i2c_patch, + ARRAY_SIZE(rt5514_i2c_patch)); + regcache_mark_dirty(rt5514->regmap); + regcache_sync(rt5514->regmap); + } + } + break; + default: break; } -- cgit v1.2.3 From 7d8e00c78924d50eb71d3cf991096021eadce641 Mon Sep 17 00:00:00 2001 From: "oder_chiou@realtek.com" Date: Fri, 7 Jul 2017 16:58:57 +0800 Subject: ASoC: rt5663: Update the calibration funciton The patch updates the calibration funciton for getting the correct DC offset of headphone output. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 100 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 21 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index a33202affeb1..18b3b526b7c5 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -2986,47 +2986,75 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) { int value, count; - regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0280); + regmap_write(rt5663->regmap, RT5663_RESET, 0x0000); + msleep(20); + regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_4, 0x00a1); + regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0380); regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000); - regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); + regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1000); regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be); - msleep(20); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be); - regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); - regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); - regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); - regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0003); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); - regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1111); + regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c); + regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324); + regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b); + msleep(30); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8000); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x0008); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_1, 0xffff); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_2, 0xffff); + regmap_write(rt5663->regmap, RT5663_CBJ_1, 0x8c10); + regmap_write(rt5663->regmap, RT5663_IL_CMD_2, 0x00c1); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb880); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4110); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4118); + + count = 0; + while (true) { + regmap_read(rt5663->regmap, RT5663_INT_ST_2, &value); + if (!(value & 0x80)) + usleep_range(10000, 10005); + else + break; + + if (count > 200) + break; + } + + regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x0000); regmap_write(rt5663->regmap, RT5663_DEPOP_2, 0x3003); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0038); regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); - regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371); regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b); - regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x2080); + regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000); regmap_write(rt5663->regmap, RT5663_BYPASS_STO_DAC, 0x000c); - regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xabba); + regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xafaa); regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_1, 0x2224); regmap_write(rt5663->regmap, RT5663_HP_OUT_EN, 0x8088); regmap_write(rt5663->regmap, RT5663_STO_DRE_9, 0x0017); regmap_write(rt5663->regmap, RT5663_STO_DRE_10, 0x0017); regmap_write(rt5663->regmap, RT5663_STO1_ADC_MIXER, 0x4040); + regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); regmap_write(rt5663->regmap, RT5663_RECMIX, 0x0005); regmap_write(rt5663->regmap, RT5663_ADDA_RST, 0xc000); regmap_write(rt5663->regmap, RT5663_STO1_HPF_ADJ1, 0x3320); regmap_write(rt5663->regmap, RT5663_HP_CALIB_2, 0x00c9); regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x004c); - regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766); - regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4702); - msleep(200); + regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x1111); + regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4402); + regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x3311); regmap_write(rt5663->regmap, RT5663_HP_CALIB_1, 0x0069); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06c2); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x7b00); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xfb00); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06ce); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6800); + regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x1100); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0057); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe800); + count = 0; while (true) { regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); @@ -3039,6 +3067,36 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) return; count++; } + + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6200); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0059); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe200); + + count = 0; + while (true) { + regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); + if (value & 0x8000) + usleep_range(10000, 10005); + else + break; + + if (count > 200) + return; + count++; + } + + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb8e0); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0x003b); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x0000); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x000b); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0008); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0000); + usleep_range(10000, 10005); } static int rt5663_i2c_probe(struct i2c_client *i2c, -- cgit v1.2.3 From 8f24412784bd0f544307bb184e3f264064f68ff0 Mon Sep 17 00:00:00 2001 From: "oder_chiou@realtek.com" Date: Fri, 7 Jul 2017 16:58:58 +0800 Subject: ASoC: rt5663: Optimize the Jack Type detection The patch optimizes the Jack Type detection. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 18b3b526b7c5..ebd9ae00e04d 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -1508,7 +1508,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert) static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) { struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); - int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; + int val, i = 0; dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); @@ -1543,17 +1543,22 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); snd_soc_update_bits(codec, RT5663_IRQ_1, RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); - while (i < 5) { - msleep(sleep_time[i]); - val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & - 0x0003; - dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", - __func__, val, sleep_time[i]); - i++; - if (val == 0x1 || val == 0x2 || val == 0x3) + + while (true) { + regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val); + if (!(val & 0x80)) + usleep_range(10000, 10005); + else + break; + + if (i > 200) break; + i++; } + + val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003; dev_dbg(codec->dev, "%s val = %d\n", __func__, val); + switch (val) { case 1: case 2: -- cgit v1.2.3 From 1325734c97c533c2042794f2bd873486b4905cdb Mon Sep 17 00:00:00 2001 From: "oder_chiou@realtek.com" Date: Fri, 7 Jul 2017 16:58:59 +0800 Subject: ASoC: rt5663: Modify the power sequence for reducing the pop sound The patch modifies the power sequence for reducing the pop sound. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index ebd9ae00e04d..82edbcf39caa 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -2029,10 +2029,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, RT5663_HP_SIG_SRC1_SILENCE); } else { snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, - 0x000b); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, - 0x0030); snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS); snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); @@ -2055,9 +2051,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0); snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, - 0x000b); } break; @@ -2068,6 +2061,31 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (rt5663->codec_ver == CODEC_VER_0) + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x003b, + 0x003b); + break; + + case SND_SOC_DAPM_POST_PMD: + if (rt5663->codec_ver == CODEC_VER_0) + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x003b, 0); + break; + + default: + return 0; + } + + return 0; +} + static int rt5663_bst2_power(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2187,6 +2205,9 @@ static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0), /* Headphone*/ + SND_SOC_DAPM_SUPPLY("HP Charge Pump", SND_SOC_NOPM, 0, 0, + rt5663_charge_pump_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), @@ -2343,6 +2364,7 @@ static const struct snd_soc_dapm_route rt5663_dapm_routes[] = { { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" }, { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" }, + { "HP Amp", NULL, "HP Charge Pump" }, { "HP Amp", NULL, "DAC L" }, { "HP Amp", NULL, "DAC R" }, }; -- cgit v1.2.3 From 09b8852c759917e3ea10062b374692a5313cbfd8 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 10 Jul 2017 16:20:45 +0100 Subject: ASoC: rt5663: add in missing loop counter to avoid infinite loop The loop counter 'count' is missing an increment, so we could end up with an infinite loop. Add in a pre-increment to count to fix this. Detected by CoverityScan, CID#1450120 ("Logically Dead Code") Fixes: 1a425dbf1a10 ("ASoC: rt5663: Update the calibration funciton") Signed-off-by: Colin Ian King Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 82edbcf39caa..5b3c50c641d8 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -3044,7 +3044,7 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) else break; - if (count > 200) + if (++count > 200) break; } -- cgit v1.2.3 From 450f0f6a8fb499a6ef3d10ab5c29a7c4650a9958 Mon Sep 17 00:00:00 2001 From: "oder_chiou@realtek.com" Date: Mon, 10 Jul 2017 11:14:56 +0800 Subject: ASoC: rt5663: Add the manual offset field to compensate the DC offset The patch adds the manual offset field in the devicetree to compensate the DC offset that will be different between the PCB layout. It only can be measured by the real production. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 55 ++++++++++++++++++++++++++++++++++++++++++----- sound/soc/codecs/rt5663.h | 2 ++ 2 files changed, 52 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 5b3c50c641d8..963cda9c995a 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -40,6 +40,7 @@ enum { struct rt5663_priv { struct snd_soc_codec *codec; + struct rt5663_platform_data pdata; struct regmap *regmap; struct delayed_work jack_detect_work; struct snd_soc_jack *hs_jack; @@ -57,6 +58,10 @@ struct rt5663_priv { int jack_type; }; +static const struct reg_sequence rt5663_patch_list[] = { + { 0x002a, 0x8080 }, +}; + static const struct reg_default rt5663_v2_reg[] = { { 0x0000, 0x0000 }, { 0x0001, 0xc8c8 }, @@ -476,7 +481,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0023, 0x0039 }, { 0x0026, 0xc0c0 }, { 0x0029, 0x8080 }, - { 0x002a, 0xa0a0 }, + { 0x002a, 0x8080 }, { 0x002c, 0x000c }, { 0x002d, 0x0000 }, { 0x0040, 0x0808 }, @@ -1958,15 +1963,11 @@ static const struct snd_kcontrol_new rt5663_adda_r_mix[] = { static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = { SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, RT5663_M_DAC_L1_STO_L_SHIFT, 1, 1), - SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, - RT5663_M_DAC_R1_STO_L_SHIFT, 1, 1), }; static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = { SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, RT5663_M_DAC_L1_STO_R_SHIFT, 1, 1), - SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, - RT5663_M_DAC_R1_STO_R_SHIFT, 1, 1), }; /* Out Switch */ @@ -3126,9 +3127,20 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) usleep_range(10000, 10005); } +static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) +{ + device_property_read_u32(dev, "realtek,dc_offset_l_manual", + &rt5663->pdata.dc_offset_l_manual); + device_property_read_u32(dev, "realtek,dc_offset_r_manual", + &rt5663->pdata.dc_offset_r_manual); + + return 0; +} + static int rt5663_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5663_priv *rt5663; int ret; unsigned int val; @@ -3142,6 +3154,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5663); + if (pdata) + rt5663->pdata = *pdata; + else + rt5663_parse_dp(rt5663, &i2c->dev); + regmap = devm_regmap_init_i2c(i2c, &temp_regmap); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); @@ -3190,6 +3207,34 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, regmap_write(rt5663->regmap, RT5663_RESET, 0); dev_dbg(&i2c->dev, "calibrate done\n"); + switch (rt5663->codec_ver) { + case CODEC_VER_1: + break; + case CODEC_VER_0: + ret = regmap_register_patch(rt5663->regmap, rt5663_patch_list, + ARRAY_SIZE(rt5663_patch_list)); + if (ret != 0) + dev_warn(&i2c->dev, + "Failed to apply regmap patch: %d\n", ret); + break; + default: + dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); + } + + if (rt5663->pdata.dc_offset_l_manual) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, + rt5663->pdata.dc_offset_l_manual >> 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3, + rt5663->pdata.dc_offset_l_manual & 0xffff); + } + + if (rt5663->pdata.dc_offset_r_manual) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5, + rt5663->pdata.dc_offset_r_manual >> 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6, + rt5663->pdata.dc_offset_r_manual & 0xffff); + } + /* GPIO1 as IRQ */ regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5663_GP1_PIN_MASK, RT5663_GP1_PIN_IRQ); diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h index 4621812c94d8..c5a9b69579ad 100644 --- a/sound/soc/codecs/rt5663.h +++ b/sound/soc/codecs/rt5663.h @@ -12,6 +12,8 @@ #ifndef __RT5663_H__ #define __RT5663_H__ +#include + /* Info */ #define RT5663_RESET 0x0000 #define RT5663_VENDOR_ID 0x00fd -- cgit v1.2.3 From 4720c2fe196fc16fca9c902bec5c786ae4689842 Mon Sep 17 00:00:00 2001 From: Jaechul Lee Date: Fri, 7 Jul 2017 10:31:10 +0900 Subject: ASoC: samsung: i2s: Support more resolution rates This driver can support more frequencies over 96KHz. There are no reasons to limit the frequency range below 96KHz. If codecs/amps or something else can't support higher resolution rates, the constraints would be set rates properly because each drivers have its own limits. I added the 'pcm_rates' field to the dai_data to be set rates by the compatibilities. As a result, rates will be set each devices respectively. For example of exynos5433, rates will be set from 8KHz to 192KHz. Signed-off-by: Jaechul Lee Reviewed-by: Krzysztof Kozlowski Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'sound') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index af3ba4d4ccc5..c9f87f7bae99 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -50,6 +50,7 @@ struct samsung_i2s_variant_regs { struct samsung_i2s_dai_data { u32 quirks; + unsigned int pcm_rates; const struct samsung_i2s_variant_regs *i2s_variant_regs; }; @@ -1076,13 +1077,13 @@ static const struct snd_soc_component_driver samsung_i2s_component = { .name = "samsung-i2s", }; -#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 - #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, + const struct samsung_i2s_dai_data *i2s_dai_data, + bool sec) { struct i2s_dai *i2s; @@ -1101,13 +1102,13 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) i2s->i2s_dai_drv.resume = i2s_resume; i2s->i2s_dai_drv.playback.channels_min = 1; i2s->i2s_dai_drv.playback.channels_max = 2; - i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.playback.rates = i2s_dai_data->pcm_rates; i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; if (!sec) { i2s->i2s_dai_drv.capture.channels_min = 1; i2s->i2s_dai_drv.capture.channels_max = 2; - i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.capture.rates = i2s_dai_data->pcm_rates; i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; } return i2s; @@ -1242,7 +1243,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) i2s_dai_data = (struct samsung_i2s_dai_data *) platform_get_device_id(pdev)->driver_data; - pri_dai = i2s_alloc_dai(pdev, false); + pri_dai = i2s_alloc_dai(pdev, i2s_dai_data, false); if (!pri_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); return -ENOMEM; @@ -1316,7 +1317,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) goto err_disable_clk; if (quirks & QUIRK_SEC_DAI) { - sec_dai = i2s_alloc_dai(pdev, true); + sec_dai = i2s_alloc_dai(pdev, i2s_dai_data, true); if (!sec_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); ret = -ENOMEM; @@ -1452,29 +1453,34 @@ static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = { static const struct samsung_i2s_dai_data i2sv3_dai_type = { .quirks = QUIRK_NO_MUXPSR, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_IDMA, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv6_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv6_regs, }; static const struct samsung_i2s_dai_data i2sv7_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM, + .pcm_rates = SNDRV_PCM_RATE_8000_192000, .i2s_variant_regs = &i2sv7_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv5_i2s1_regs, }; -- cgit v1.2.3 From 27d30400c448264c1ac9434cb836de0c230af213 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 30 Jun 2017 15:43:50 -0500 Subject: ASoC: spear: fix error return code in spdif_in_probe() platform_get_irq() returns an error code, but the spdif_in driver ignores it and always returns -EINVAL. This is not correct, and prevents -EPROBE_DEFER from being propagated properly. Notice that platform_get_irq() no longer returns 0 on error: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af Print error message and propagate the return value of platform_get_irq on failure. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/spear/spdif_in.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index 977a078eb92f..7f32527fc3c8 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -223,8 +223,10 @@ static int spdif_in_probe(struct platform_device *pdev) host->io_base = io_base; host->irq = platform_get_irq(pdev, 0); - if (host->irq < 0) - return -EINVAL; + if (host->irq < 0) { + dev_warn(&pdev->dev, "failed to get IRQ: %d\n", host->irq); + return host->irq; + } host->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) -- cgit v1.2.3 From cfe267da9de756d15eab095358b0b122c57816a6 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 30 Jun 2017 17:26:48 -0500 Subject: ASoC: twl6040: fix error return code in twl6040_probe() platform_get_irq() returns an error code, but the twl6040 driver ignores it and always returns -EINVAL. This is not correct, and prevents -EPROBE_DEFER from being propagated properly. Notice that platform_get_irq() no longer returns 0 on error. Print and propagate the return value of platform_get_irq on failure. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/codecs/twl6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 2b6ad09e0886..96cf94a2b7a0 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1123,8 +1123,8 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->plug_irq = platform_get_irq(pdev, 0); if (priv->plug_irq < 0) { - dev_err(codec->dev, "invalid irq\n"); - return -EINVAL; + dev_err(codec->dev, "invalid irq: %d\n", priv->plug_irq); + return priv->plug_irq; } INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); -- cgit v1.2.3 From 2d397c518eead8b6c3cd817c29bc2d4fb1c41830 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 17 Jul 2017 07:44:21 +0200 Subject: ASoC: samsung: Remove non-existing CONFIG_CPU_S3C2413 There is no CONFIG_CPU_S3C2413 so get rid of it. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Mark Brown --- sound/soc/samsung/s3c-i2s-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 8f42deaa184b..ca522a95160b 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -27,7 +27,7 @@ #undef S3C_IIS_V2_SUPPORTED -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \ +#if defined(CONFIG_CPU_S3C2412) \ || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210) #define S3C_IIS_V2_SUPPORTED #endif -- cgit v1.2.3 From 4b2983da22d30c53d778b2e5035dc347dc4b0037 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 16 Jul 2017 21:12:21 -0500 Subject: ASoC: fsi: constify dev_pm_ops structure This dev_pm_ops structure is only stored in the pm field of a device_driver structure. This field is declared const, so dev_pm_ops structures that have this property can be declared as const also. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 7c4bdd82bb95..005b21506556 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -2109,7 +2109,7 @@ static int fsi_resume(struct device *dev) return 0; } -static struct dev_pm_ops fsi_pm_ops = { +static const struct dev_pm_ops fsi_pm_ops = { .suspend = fsi_suspend, .resume = fsi_resume, }; -- cgit v1.2.3 From da61a11823395c87db0471d8d54055fa5a961688 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 16 Jul 2017 21:12:39 -0500 Subject: ASoC: psc-ac97: constify dev_pm_ops structure This dev_pm_ops structure is only stored in the pm field of a device_driver structure. This field is declared const, so dev_pm_ops structures that have this property can be declared as const also. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/au1x/psc-ac97.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index bb53c7059005..a2050ae5a3fe 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -474,7 +474,7 @@ static int au1xpsc_ac97_drvresume(struct device *dev) return 0; } -static struct dev_pm_ops au1xpscac97_pmops = { +static const struct dev_pm_ops au1xpscac97_pmops = { .suspend = au1xpsc_ac97_drvsuspend, .resume = au1xpsc_ac97_drvresume, }; -- cgit v1.2.3 From 90982dcdda4f0163bc5e53f49301e155c2cd8547 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 16 Jul 2017 21:12:49 -0500 Subject: ASoC: au1x: psc-i2s: constify dev_pm_ops structure This dev_pm_ops structure is only stored in the pm field of a device_driver structure. This field is declared const, so dev_pm_ops structures that have this property can be declared as const also. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/au1x/psc-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 0bf9d62b91a0..e6eec081eaae 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -392,7 +392,7 @@ static int au1xpsc_i2s_drvresume(struct device *dev) return 0; } -static struct dev_pm_ops au1xpsci2s_pmops = { +static const struct dev_pm_ops au1xpsci2s_pmops = { .suspend = au1xpsc_i2s_drvsuspend, .resume = au1xpsc_i2s_drvresume, }; -- cgit v1.2.3 From d5c6d43b3d94e7bf421ec2aaf21b4b7c79fa1850 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 14 Jul 2017 00:04:06 +0100 Subject: ASoC: Intel: Skylake: fix type in debug message Trivial fix to typo in debug message, dst_instacne should be dst_instance Signed-off-by: Colin Ian King Acked-By: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-messages.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index fb2f1f603f3c..c5b4e0a9946c 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -950,7 +950,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg { dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", __func__, src_module->id.module_id, src_module->id.pvt_id); - dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, + dev_dbg(ctx->dev, "%s: dst_module=%d dst_instance=%d\n", __func__, dst_module->id.module_id, dst_module->id.pvt_id); dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", -- cgit v1.2.3 From 82e2b1e081906d3d86c4597250ab2939b209079f Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 13 Jul 2017 01:16:46 -0500 Subject: ASoC: Intel: Skylake: constify snd_soc_dai_ops structures These structures are only stored in the ops field of a snd_soc_dai_driver structure. That field is declared const, so snd_soc_dai_ops structures that have this property can be declared as const also. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-pcm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 0ebea34a4988..b1f2dba642c4 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops skl_pcm_dai_ops = { +static const struct snd_soc_dai_ops skl_pcm_dai_ops = { .startup = skl_pcm_open, .shutdown = skl_pcm_close, .prepare = skl_pcm_prepare, @@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = { .trigger = skl_pcm_trigger, }; -static struct snd_soc_dai_ops skl_dmic_dai_ops = { +static const struct snd_soc_dai_ops skl_dmic_dai_ops = { .hw_params = skl_be_hw_params, }; -static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { +static const struct snd_soc_dai_ops skl_be_ssp_dai_ops = { .hw_params = skl_be_hw_params, }; -static struct snd_soc_dai_ops skl_link_dai_ops = { +static const struct snd_soc_dai_ops skl_link_dai_ops = { .prepare = skl_link_pcm_prepare, .hw_params = skl_link_hw_params, .hw_free = skl_link_hw_free, -- cgit v1.2.3 From c115a3178b1dfacd57b643934bb6bbbd1a9557f0 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 13 Jul 2017 01:26:06 -0500 Subject: ASoC: Intel: Atom: constify snd_soc_dai_ops structures These structures are only stored in the ops field of a snd_soc_dai_driver structure. That field is declared const, so snd_soc_dai_ops structures that have this property can be declared as const also. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst-mfld-platform-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index b082b31023d5..49c7b88b5bdc 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream, } } -static struct snd_soc_dai_ops sst_media_dai_ops = { +static const struct snd_soc_dai_ops sst_media_dai_ops = { .startup = sst_media_open, .shutdown = sst_media_close, .prepare = sst_media_prepare, @@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = { .mute_stream = sst_media_digital_mute, }; -static struct snd_soc_dai_ops sst_compr_dai_ops = { +static const struct snd_soc_dai_ops sst_compr_dai_ops = { .mute_stream = sst_media_digital_mute, }; -static struct snd_soc_dai_ops sst_be_dai_ops = { +static const struct snd_soc_dai_ops sst_be_dai_ops = { .startup = sst_enable_ssp, .hw_params = sst_be_hw_params, .set_fmt = sst_set_format, -- cgit v1.2.3 From fa05899c12d54d3a1befa742f62d3188e551a87c Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 14 Jul 2017 14:36:32 +0800 Subject: ASoC: rt5665: force using PLL if MCLK is not suitable Idealy PLL will be set in machine driver if MCLK doesn't meet the requirement of codec. To let the codec driver be more general, we can use a common PLL setting once sysclk/pll doesn't set properly in machine driver. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5665.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 370ed54d1e15..d3103efcb135 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4098,9 +4098,12 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, rt5665->lrck[dai->id] = params_rate(params); pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]); if (pre_div < 0) { - dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", - rt5665->lrck[dai->id], dai->id); - return -EINVAL; + dev_warn(codec->dev, "Force using PLL"); + snd_soc_codec_set_pll(codec, 0, RT5665_PLL1_S_MCLK, + rt5665->sysclk, rt5665->lrck[dai->id] * 512); + snd_soc_codec_set_sysclk(codec, RT5665_SCLK_S_PLL1, 0, + rt5665->lrck[dai->id] * 512, 0); + pre_div = 1; } frame_size = snd_soc_params_to_frame_size(params); if (frame_size < 0) { -- cgit v1.2.3 From 53ba2aa314164f7fcd3acf9594313811256a52c4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 Jul 2017 09:19:07 +0200 Subject: ASoC: rsnd: add missing of_node_put for_each_child_of_node performs an of_node_get on each iteration, so a jump out of the loop requires an of_node_put. The semantic patch that fixes this problem is as follows (http://coccinelle.lip6.fr): // @@ local idexpression n; expression e,e1; identifier l; @@ for_each_child_of_node(e1,n) { ... ( of_node_put(n); | e = n | + of_node_put(n); ? goto l; ) ... } ... l: ... when != n // Signed-off-by: Julia Lawall Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ctu.c | 5 ++++- sound/soc/sh/rcar/dvc.c | 5 ++++- sound/soc/sh/rcar/mix.c | 5 ++++- sound/soc/sh/rcar/src.c | 6 +++++- sound/soc/sh/rcar/ssi.c | 6 +++++- 5 files changed, 22 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 4ba8f2fe7a4c..e7f53f44165d 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -394,13 +394,16 @@ int rsnd_ctu_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_ctu_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, clk, rsnd_mod_get_status, RSND_MOD_CTU, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_ctu_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 99d2d9459e75..1743ade3cc55 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -380,13 +380,16 @@ int rsnd_dvc_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_dvc_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, clk, rsnd_mod_get_status, RSND_MOD_DVC, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_dvc_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 195fc7bb22af..6c4826c189a4 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -168,13 +168,16 @@ int rsnd_mix_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_mix_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, clk, rsnd_mod_get_status, RSND_MOD_MIX, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_mix_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 7aa239e28491..8e9a1de0ec25 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -581,20 +581,24 @@ int rsnd_src_probe(struct rsnd_priv *priv) src->irq = irq_of_parse_and_map(np, 0); if (!src->irq) { ret = -EINVAL; + of_node_put(np); goto rsnd_src_probe_done; } clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_src_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(src), &rsnd_src_ops, clk, rsnd_mod_get_status, RSND_MOD_SRC, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_src_probe_done; + } skip: i++; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 46feddd78ee2..49cdc5e007b3 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -1079,6 +1079,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_ssi_probe_done; } @@ -1091,6 +1092,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ssi->irq = irq_of_parse_and_map(np, 0); if (!ssi->irq) { ret = -EINVAL; + of_node_put(np); goto rsnd_ssi_probe_done; } @@ -1101,8 +1103,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, rsnd_ssi_get_status, RSND_MOD_SSI, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_ssi_probe_done; + } i++; } -- cgit v1.2.3 From d51579e6effa19c1ca4d6a29c3841cb454d56af6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:06 -0300 Subject: ASoC: sun4i-codec: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 150069987c0c..4c37231f254b 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -1171,9 +1171,8 @@ static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w, { struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card); - if (scodec->gpio_pa) - gpiod_set_value_cansleep(scodec->gpio_pa, - !!SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(scodec->gpio_pa, + !!SND_SOC_DAPM_EVENT_ON(event)); return 0; } -- cgit v1.2.3 From 68feed90070e5133c0bfe26648410a39e092018d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:08 -0300 Subject: ASoC: adau1977: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/adau1977.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index b319db6a69f8..ccc5cf0e4f80 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -388,8 +388,7 @@ static int adau1977_power_disable(struct adau1977 *adau1977) regcache_mark_dirty(adau1977->regmap); - if (adau1977->reset_gpio) - gpiod_set_value_cansleep(adau1977->reset_gpio, 0); + gpiod_set_value_cansleep(adau1977->reset_gpio, 0); regcache_cache_only(adau1977->regmap, true); @@ -420,8 +419,7 @@ static int adau1977_power_enable(struct adau1977 *adau1977) goto err_disable_avdd; } - if (adau1977->reset_gpio) - gpiod_set_value_cansleep(adau1977->reset_gpio, 1); + gpiod_set_value_cansleep(adau1977->reset_gpio, 1); regcache_cache_only(adau1977->regmap, false); -- cgit v1.2.3 From 89b13706c4bb6dae0263014051dd59986376faa5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:07 -0300 Subject: ASoC: wm8804: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index af95d648265b..fc69b87443d8 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -623,8 +623,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) return ret; } - if (wm8804->reset) - gpiod_set_value_cansleep(wm8804->reset, 1); + gpiod_set_value_cansleep(wm8804->reset, 1); ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); if (ret < 0) { -- cgit v1.2.3 From c5660778b4851b1aea5d848ccfde3f27949f6418 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:09 -0300 Subject: ASoC: cs35l33: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l33.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6df29fa30fb9..1eea91271ebb 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -869,8 +869,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev) dev_dbg(dev, "%s\n", __func__); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); ret = regulator_bulk_enable(cs35l33->num_core_supplies, cs35l33->core_supplies); @@ -881,8 +880,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev) regcache_cache_only(cs35l33->regmap, false); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); @@ -1191,8 +1189,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client, return ret; } - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); regcache_cache_only(cs35l33->regmap, false); @@ -1262,8 +1259,7 @@ static int cs35l33_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); pm_runtime_disable(&client->dev); regulator_bulk_disable(cs35l33->num_core_supplies, -- cgit v1.2.3 From db3be255a101da11f67c0f3053b750e767eb10fe Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:10 -0300 Subject: ASoC: cs35l34: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l34.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 0a747c66cc6c..dade899b38dc 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -1138,8 +1138,7 @@ static int cs35l34_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); - if (cs35l34->reset_gpio) - gpiod_set_value_cansleep(cs35l34->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l34->reset_gpio, 0); pm_runtime_disable(&client->dev); regulator_bulk_disable(cs35l34->num_core_supplies, -- cgit v1.2.3 From 205cbac065f9589c77a79f26339cf63023f08f6e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:11 -0300 Subject: ASoC: cs42l42: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l42.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 55e4520cdcaf..55caf5ff3e64 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1898,8 +1898,7 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) snd_soc_unregister_codec(&i2c_client->dev); /* Hold down reset */ - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); return 0; } @@ -1913,8 +1912,7 @@ static int cs42l42_runtime_suspend(struct device *dev) regcache_mark_dirty(cs42l42->regmap); /* Hold down reset */ - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); /* remove power */ regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), @@ -1937,8 +1935,7 @@ static int cs42l42_runtime_resume(struct device *dev) return ret; } - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); regcache_cache_only(cs42l42->regmap, false); regcache_sync(cs42l42->regmap); -- cgit v1.2.3 From 55be663dc71ec50f0e383c50886cbd3be69fcd2e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:12 -0300 Subject: ASoC: cs53l30: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/cs53l30.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 06933a5d0a75..92fbe6303dd4 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -842,8 +842,7 @@ static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream) { struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); - if (priv->mute_gpio) - gpiod_set_value_cansleep(priv->mute_gpio, mute); + gpiod_set_value_cansleep(priv->mute_gpio, mute); return 0; } @@ -960,8 +959,7 @@ static int cs53l30_i2c_probe(struct i2c_client *client, goto error; } - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); i2c_set_clientdata(client, cs53l30); @@ -1056,8 +1054,7 @@ static int cs53l30_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); /* Hold down reset */ - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), cs53l30->supplies); @@ -1073,8 +1070,7 @@ static int cs53l30_runtime_suspend(struct device *dev) regcache_cache_only(cs53l30->regmap, true); /* Hold down reset */ - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), cs53l30->supplies); @@ -1094,8 +1090,7 @@ static int cs53l30_runtime_resume(struct device *dev) return ret; } - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); regcache_cache_only(cs53l30->regmap, false); ret = regcache_sync(cs53l30->regmap); -- cgit v1.2.3 From c5efe232e09ef29cc2f9e8333a49dd8891366c22 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Jul 2017 18:11:13 -0300 Subject: ASoC: sta32x: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/sta32x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 0790ae8530d9..5b888476d9ff 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -847,8 +847,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, msleep(300); sta32x_watchdog_stop(sta32x); - if (sta32x->gpiod_nreset) - gpiod_set_value(sta32x->gpiod_nreset, 0); + gpiod_set_value(sta32x->gpiod_nreset, 0); regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); -- cgit v1.2.3 From 173f4612690ac569d9f912a31aa69af15b84047c Mon Sep 17 00:00:00 2001 From: "oder_chiou@realtek.com" Date: Thu, 13 Jul 2017 19:42:20 +0800 Subject: ASoC: rt5514: Support the DSP recording continuously after the hotwording triggered The patch uses the IRQ to copy the PCM data to userspace continuously after the hotwording triggered from DSP. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5514-spi.c | 139 ++++++++++++++++++++++-------------------- sound/soc/codecs/rt5514-spi.h | 7 +-- 2 files changed, 76 insertions(+), 70 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 7ed62e8c80b4..950d1ffdc06c 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c @@ -43,9 +43,7 @@ struct rt5514_dsp { struct mutex dma_lock; struct snd_pcm_substream *substream; unsigned int buf_base, buf_limit, buf_rp; - size_t buf_size; - size_t dma_offset; - size_t dsp_offset; + size_t buf_size, get_size, dma_offset; }; static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = { @@ -80,6 +78,8 @@ static void rt5514_spi_copy_work(struct work_struct *work) container_of(work, struct rt5514_dsp, copy_work.work); struct snd_pcm_runtime *runtime; size_t period_bytes, truncated_bytes = 0; + unsigned int cur_wp, remain_data; + u8 buf[8]; mutex_lock(&rt5514_dsp->dma_lock); if (!rt5514_dsp->substream) { @@ -90,8 +90,24 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime = rt5514_dsp->substream->runtime; period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream); - if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes) - period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset; + if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) { + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + if (cur_wp >= rt5514_dsp->buf_rp) + remain_data = (cur_wp - rt5514_dsp->buf_rp); + else + remain_data = + (rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) + + (cur_wp - rt5514_dsp->buf_base); + + if (remain_data < period_bytes) { + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + goto done; + } + } if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) { rt5514_spi_burst_read(rt5514_dsp->buf_rp, @@ -112,24 +128,58 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime->dma_area + rt5514_dsp->dma_offset + truncated_bytes, period_bytes - truncated_bytes); - rt5514_dsp->buf_rp = rt5514_dsp->buf_base + - period_bytes - truncated_bytes; + rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes - + truncated_bytes; } + rt5514_dsp->get_size += period_bytes; rt5514_dsp->dma_offset += period_bytes; if (rt5514_dsp->dma_offset >= runtime->dma_bytes) rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset += period_bytes; - snd_pcm_period_elapsed(rt5514_dsp->substream); - if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 5); + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + done: mutex_unlock(&rt5514_dsp->dma_lock); } +static irqreturn_t rt5514_spi_irq(int irq, void *data) +{ + struct rt5514_dsp *rt5514_dsp = data; + u8 buf[8]; + + rt5514_dsp->get_size = 0; + rt5514_dsp->dma_offset = 0; + + /** + * The address area x1800XXXX is the register address, and it cannot + * support spi burst read perfectly. So we use the spi burst read + * individually to make sure the data correctly. + */ + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base; + + schedule_delayed_work(&rt5514_dsp->copy_work, 0); + + return IRQ_HANDLED; +} + /* PCM for streaming audio from the DSP buffer */ static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream) { @@ -170,59 +220,6 @@ static int rt5514_spi_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_vmalloc_buffer(substream); } -static int rt5514_spi_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - u8 buf[8]; - - rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset = 0; - - /** - * The address area x1800XXXX is the register address, and it cannot - * support spi burst read perfectly. So we use