diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/arizona.c | 16 | ||||
-rw-r--r-- | sound/soc/codecs/es8328.c | 16 | ||||
-rw-r--r-- | sound/soc/codecs/nau8825.c | 31 | ||||
-rw-r--r-- | sound/soc/codecs/rl6231.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/rt5645.c | 61 | ||||
-rw-r--r-- | sound/soc/codecs/rt5670.h | 12 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 12 | ||||
-rw-r--r-- | sound/soc/fsl/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 3 | ||||
-rw-r--r-- | sound/soc/intel/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 7 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 6 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 7 | ||||
-rw-r--r-- | sound/soc/soc-ops.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-topology.c | 1 |
17 files changed, 147 insertions, 40 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 9929efc6b9aa..b3ea24d64c50 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1023,24 +1023,18 @@ void arizona_init_dvfs(struct arizona_priv *priv) } EXPORT_SYMBOL_GPL(arizona_init_dvfs); -static unsigned int arizona_sysclk_48k_rates[] = { +static unsigned int arizona_opclk_ref_48k_rates[] = { 6144000, 12288000, 24576000, 49152000, - 73728000, - 98304000, - 147456000, }; -static unsigned int arizona_sysclk_44k1_rates[] = { +static unsigned int arizona_opclk_ref_44k1_rates[] = { 5644800, 11289600, 22579200, 45158400, - 67737600, - 90316800, - 135475200, }; static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, @@ -1065,11 +1059,11 @@ static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, } if (refclk % 8000) - rates = arizona_sysclk_44k1_rates; + rates = arizona_opclk_ref_44k1_rates; else - rates = arizona_sysclk_48k_rates; + rates = arizona_opclk_ref_48k_rates; - for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) && + for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) && rates[ref] <= refclk; ref++) { div = 1; while (rates[ref] / div >= freq && div < 32) { diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 969e337dc17c..84f5eb07a91b 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -205,18 +205,18 @@ static const struct snd_kcontrol_new es8328_right_line_controls = /* Left Mixer */ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { - SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 8, 1, 0), - SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 7, 1, 0), - SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 8, 1, 0), - SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 7, 1, 0), + SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0), + SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0), }; /* Right Mixer */ static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { - SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 8, 1, 0), - SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 7, 1, 0), - SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 8, 1, 0), - SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 7, 1, 0), + SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0), + SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0), }; static const char * const es8328_pga_sel[] = { diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 7fc7b4e3f444..c1b87c5800b1 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -1271,6 +1271,36 @@ static int nau8825_i2c_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM_SLEEP +static int nau8825_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct nau8825 *nau8825 = dev_get_drvdata(dev); + + disable_irq(client->irq); + regcache_cache_only(nau8825->regmap, true); + regcache_mark_dirty(nau8825->regmap); + + return 0; +} + +static int nau8825_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct nau8825 *nau8825 = dev_get_drvdata(dev); + + regcache_cache_only(nau8825->regmap, false); + regcache_sync(nau8825->regmap); + enable_irq(client->irq); + + return 0; +} +#endif + +static const struct dev_pm_ops nau8825_pm = { + SET_SYSTEM_SLEEP_PM_OPS(nau8825_suspend, nau8825_resume) +}; + static const struct i2c_device_id nau8825_i2c_ids[] = { { "nau8825", 0 }, { } @@ -1297,6 +1327,7 @@ static struct i2c_driver nau8825_driver = { .name = "nau8825", .of_match_table = of_match_ptr(nau8825_of_ids), .acpi_match_table = ACPI_PTR(nau8825_acpi_match), + .pm = &nau8825_pm, }, .probe = nau8825_i2c_probe, .remove = nau8825_i2c_remove, diff --git a/sound/soc/codecs/rl6231.c b/sound/soc/codecs/rl6231.c index aca479fa7670..1dc68ab08a17 100644 --- a/sound/soc/codecs/rl6231.c +++ b/sound/soc/codecs/rl6231.c @@ -80,8 +80,10 @@ int rl6231_calc_dmic_clk(int rate) } for (i = 0; i < ARRAY_SIZE(div); i++) { - /* find divider that gives DMIC frequency below 3MHz */ - if (3000000 * div[i] >= rate) + if ((div[i] % 3) == 0) + continue; + /* find divider that gives DMIC frequency below 3.072MHz */ + if (3072000 * div[i] >= rate) return i; } diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 28132375e427..ef76940f9dcb 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -245,7 +245,7 @@ struct rt5645_priv { struct snd_soc_jack *hp_jack; struct snd_soc_jack *mic_jack; struct snd_soc_jack *btn_jack; - struct delayed_work jack_detect_work; + struct delayed_work jack_detect_work, rcclock_work; struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; struct rt5645_eq_param_s *eq_param; @@ -565,12 +565,33 @@ static int rt5645_hweq_put(struct snd_kcontrol *kcontrol, .put = rt5645_hweq_put \ } +static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); + int ret; + + cancel_delayed_work_sync(&rt5645->rcclock_work); + + regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, + RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU); + + ret = snd_soc_put_volsw(kcontrol, ucontrol); + + queue_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work, + msecs_to_jiffies(200)); + + return ret; +} + static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), - SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, - RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), + SOC_DOUBLE_EXT_TLV("Speaker Playback Volume", RT5645_SPK_VOL, + RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, snd_soc_get_volsw, + rt5645_spk_put_volsw, out_vol_tlv), /* ClassD modulator Speaker Gain Ratio */ SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO, @@ -1498,7 +1519,7 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on) regmap_write(rt5645->regmap, RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140); - msleep(40); + msleep(70); rt5645->hp_on = true; } else { /* depop parameters */ @@ -3122,6 +3143,15 @@ static void rt5645_jack_detect_work(struct work_struct *work) SND_JACK_BTN_2 | SND_JACK_BTN_3); } +static void rt5645_rcclock_work(struct work_struct *work) +{ + struct rt5645_priv *rt5645 = + container_of(work, struct rt5645_priv, rcclock_work.work); + + regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, + RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PD); +} + static irqreturn_t rt5645_irq(int irq, void *data) { struct rt5645_priv *rt5645 = data; @@ -3348,6 +3378,27 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Reks"), }, }, + { + .ident = "Google Edgar", + .callback = strago_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"), + }, + }, + { + .ident = "Google Wizpig", + .callback = strago_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Wizpig"), + }, + }, + { + .ident = "Google Terra", + .callback = strago_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Terra"), + }, + }, { } }; @@ -3587,6 +3638,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, } INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work); + INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work); if (rt5645->i2c->irq) { ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, @@ -3621,6 +3673,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) free_irq(i2c->irq, rt5645); cancel_delayed_work_sync(&rt5645->jack_detect_work); + cancel_delayed_work_sync(&rt5645->rcclock_work); snd_soc_unregister_codec(&i2c->dev); regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h index dc2b46236c5c..3f1b0f1df809 100644 --- a/sound/soc/codecs/rt5670.h +++ b/sound/soc/codecs/rt5670.h @@ -973,12 +973,12 @@ #define RT5670_SCLK_SRC_MCLK (0x0 << 14) #define RT5670_SCLK_SRC_PLL1 (0x1 << 14) #define RT5670_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */ -#define RT5670_PLL1_SRC_MASK (0x3 << 12) -#define RT5670_PLL1_SRC_SFT 12 -#define RT5670_PLL1_SRC_MCLK (0x0 << 12) -#define RT5670_PLL1_SRC_BCLK1 (0x1 << 12) -#define RT5670_PLL1_SRC_BCLK2 (0x2 << 12) -#define RT5670_PLL1_SRC_BCLK3 (0x3 << 12) +#define RT5670_PLL1_SRC_MASK (0x7 << 11) +#define RT5670_PLL1_SRC_SFT 11 +#define RT5670_PLL1_SRC_MCLK (0x0 << 11) +#define RT5670_PLL1_SRC_BCLK1 (0x1 << 11) +#define RT5670_PLL1_SRC_BCLK2 (0x2 << 11) +#define RT5670_PLL1_SRC_BCLK3 (0x3 << 11) #define RT5670_PLL1_PD_MASK (0x1 << 3) #define RT5670_PLL1_PD_SFT 3 #define RT5670_PLL1_PD_1 (0x0 << 3) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 4495a40a9468..c1c9c2e3525b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -681,8 +681,8 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai, } mcasp->tdm_slots = slots; - mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask; - mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask; + mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask; + mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask; mcasp->slot_width = slot_width; return davinci_mcasp_set_ch_constraints(mcasp); @@ -908,6 +908,14 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRMOD(total_slots), FSRMOD(0x1FF)); + /* + * If McASP is set to be TX/RX synchronous and the playback is + * not running already we need to configure the TX slots in + * order to have correct FSX on the bus + */ + if (mcasp_is_synchronous(mcasp) && !mcasp->channels) + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, + FSXMOD(total_slots), FSXMOD(0x1FF)); } return 0; diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 19c302b0d763..14dfdee05fd5 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -283,6 +283,8 @@ config SND_SOC_IMX_MC13783 config SND_SOC_FSL_ASOC_CARD tristate "Generic ASoC Sound Card with ASRC support" depends on OF && I2C + # enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m: + depends on SND_AC97_CODEC || SND_AC97_CODEC=n select SND_SOC_IMX_AUDMUX select SND_SOC_IMX_PCM_DMA select SND_SOC_FSL_ESAI diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a4435f5e3be9..ffd5f9acc849 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -454,7 +454,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. */ - regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0); + regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, + sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 7b778ab85f8b..d430ef5a4f38 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -144,7 +144,7 @@ config SND_SOC_INTEL_SKYLAKE config SND_SOC_INTEL_SKL_RT286_MACH tristate "ASoC Audio driver for SKL with RT286 I2S mode" - depends on X86 && ACPI + depends on X86 && ACPI && I2C select SND_SOC_INTEL_SST select SND_SOC_INTEL_SKYLAKE select SND_SOC_RT286 diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index a7854c8fc523..ffea427aeca8 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1240,6 +1240,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus) */ ret = snd_soc_tplg_component_load(&platform->component, &skl_tplg_ops, fw, 0); + release_firmware(fw); if (ret < 0) { dev_err(bus->dev, "tplg component load failed%d\n", ret); return -EINVAL; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 76da7620904c..edcf4cc2e84f 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -235,7 +235,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev, RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc), RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0), - RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4), + RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4), RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 261b50217c48..68b439ed22d7 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -923,6 +923,7 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod, struct snd_soc_pcm_runtime *rtd) { struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); struct rsnd_src *src = rsnd_mod_to_src(mod); int ret; @@ -937,6 +938,12 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod, return 0; /* + * SRC In doesn't work if DVC was enabled + */ + if (dvc && !rsnd_io_is_play(io)) + return 0; + + /* * enable sync convert */ ret = rsnd_kctrl_new_s(mod, io, rtd, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 24b096066a07..a1305f827a98 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -795,12 +795,12 @@ static void soc_resume_deferred(struct work_struct *work) dev_dbg(card->dev, "ASoC: resume work completed\n"); - /* userspace can access us now we are back as we were before */ - snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); - /* Recheck all endpoints too, their state is affected by suspend */ dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm); + + /* userspace can access us now we are back as we were before */ + snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); } /* powers up audio subsystem after a suspend */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 016eba10b1ec..7d009428934a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2293,6 +2293,12 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) kfree(w); } +void snd_soc_dapm_reset_cache(struct snd_soc_dapm_context *dapm) +{ + dapm->path_sink_cache.widget = NULL; + dapm->path_source_cache.widget = NULL; +} + /* free all dapm widgets and resources */ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) { @@ -2303,6 +2309,7 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) continue; snd_soc_dapm_free_widget(w); } + snd_soc_dapm_reset_cache(dapm); } static struct snd_soc_dapm_widget *dapm_find_widget( diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index ecd38e52285a..2f67ba6d7a8f 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); /** * snd_soc_put_volsw_sx - double mixer set callback * @kcontrol: mixer control - * @uinfo: control element information + * @ucontrol: control element information * * Callback to set the value of a double mixer control that spans 2 registers. * diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 8d7ec80af51b..cce63fe65dd9 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1805,6 +1805,7 @@ void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm, snd_soc_tplg_widget_remove(w); snd_soc_dapm_free_widget(w); } + snd_soc_dapm_reset_cache(dapm); } EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_remove_all); |