diff options
25 files changed, 528 insertions, 82 deletions
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml index 476dcb49ece6..5c368674d11a 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml @@ -71,4 +71,24 @@ patternProperties: description: CPU to Codec rate channels. $ref: /schemas/types.yaml#/definitions/uint32 + dai-tdm-slot-width-map: + description: Mapping of sample widths to slot widths. For hardware + that cannot support a fixed slot width or a slot width always + equal to sample width. A matrix of one or more 3-tuples. + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - + description: Sample width in bits + minimum: 8 + maximum: 64 + - + description: Slot width in bits + minimum: 8 + maximum: 256 + - + description: Slot count + minimum: 1 + maximum: 64 + additionalProperties: true diff --git a/Documentation/devicetree/bindings/sound/awinic,aw8738.yaml b/Documentation/devicetree/bindings/sound/awinic,aw8738.yaml new file mode 100644 index 000000000000..dce86dafe382 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/awinic,aw8738.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/awinic,aw8738.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Awinic AW8738 Audio Amplifier + +maintainers: + - Stephan Gerhold <stephan@gerhold.net> + +description: + The Awinic AW8738 is a simple audio amplifier with different operation modes + (set using one-wire pulse control). The mode configures the speaker-guard + function (primarily the power limit for the amplifier). + +allOf: + - $ref: name-prefix.yaml# + +properties: + compatible: + const: awinic,aw8738 + + mode-gpios: + description: + GPIO used for one-wire pulse control. The pin is typically called SHDN + (active-low), but this is misleading since it is actually more than + just a simple shutdown/enable control. + maxItems: 1 + + awinic,mode: + description: Operation mode (number of pulses for one-wire pulse control) + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + sound-name-prefix: true + +required: + - compatible + - mode-gpios + - awinic,mode + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + audio-amplifier { + compatible = "awinic,aw8738"; + mode-gpios = <&msmgpio 114 GPIO_ACTIVE_HIGH>; + awinic,mode = <5>; + sound-name-prefix = "Speaker Amp"; + }; diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c index 0ca2a3e3a02e..747983743a14 100644 --- a/drivers/soundwire/dmi-quirks.c +++ b/drivers/soundwire/dmi-quirks.c @@ -59,7 +59,7 @@ static const struct dmi_system_id adr_remap_quirk_table[] = { { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"), }, .driver_data = (void *)intel_tgl_bios, }, diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 5ee269c59aac..8faa649f712b 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -16,6 +16,12 @@ #define asoc_simple_init_mic(card, sjack, prefix) \ asoc_simple_init_jack(card, sjack, 0, prefix, NULL) +struct asoc_simple_tdm_width_map { + u8 sample_bits; + u8 slot_count; + u16 slot_width; +}; + struct asoc_simple_dai { const char *name; unsigned int sysclk; @@ -26,6 +32,8 @@ struct asoc_simple_dai { unsigned int rx_slot_mask; struct clk *clk; bool clk_fixed; + struct asoc_simple_tdm_width_map *tdm_width_map; + int n_tdm_widths; }; struct asoc_simple_data { @@ -132,6 +140,9 @@ int asoc_simple_parse_daifmt(struct device *dev, struct device_node *codec, char *prefix, unsigned int *retfmt); +int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np, + struct asoc_simple_dai *dai); + __printf(3, 4) int asoc_simple_set_dailink_name(struct device *dev, struct snd_soc_dai_link *dai_link, diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 738cf2e2b973..75c9229ece97 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -282,9 +282,10 @@ static int renoir_audio_probe(struct platform_device *pdev) if (!adata->acp_base) return -ENOMEM; - adata->i2s_irq = platform_get_irq_byname(pdev, "acp_dai_irq"); - if (adata->i2s_irq < 0) - return -ENODEV; + ret = platform_get_irq_byname(pdev, "acp_dai_irq"); + if (ret < 0) + return ret; + adata->i2s_irq = ret; adata->dev = dev; adata->dai_driver = acp_renoir_dai; diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index e4f8dbf0d11d..6aec11cf0a6a 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -394,9 +394,10 @@ static int acp3x_audio_probe(struct platform_device *pdev) if (!adata->acp3x_base) return -ENOMEM; - adata->i2s_irq = platform_get_irq(pdev, 0); - if (adata->i2s_irq < 0) - return -ENODEV; + status = platform_get_irq(pdev, 0); + if (status < 0) + return status; + adata->i2s_irq = status; dev_set_drvdata(&pdev->dev, adata); status = devm_snd_soc_register_component(&pdev->dev, diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c index 88a242538461..8c42345ee41e 100644 --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c @@ -399,9 +399,10 @@ static int acp_pdm_audio_probe(struct platform_device *pdev) if (!adata->acp_base) return -ENOMEM; - adata->pdm_irq = platform_get_irq(pdev, 0); - if (adata->pdm_irq < 0) - return -ENODEV; + status = platform_get_irq(pdev, 0); + if (status < 0) + return status; + adata->pdm_irq = status; adata->capture_stream = NULL; diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c index e4e668593b3d..31fa166df98a 100644 --- a/sound/soc/amd/vangogh/acp5x-pcm-dma.c +++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c @@ -388,9 +388,10 @@ static int acp5x_audio_probe(struct platform_device *pdev) if (!adata->acp5x_base) return -ENOMEM; - adata->i2s_irq = platform_get_irq(pdev, 0); - if (adata->i2s_irq < 0) - return -ENODEV; + status = platform_get_irq(pdev, 0); + if (status < 0) + return status; + adata->i2s_irq = status; dev_set_drvdata(&pdev->dev, adata); status = devm_snd_soc_register_component(&pdev->dev, diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 915da92e1ec8..33e43013ff77 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -214,6 +214,7 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); if (!cpu_np) { dev_err(&pdev->dev, "dai and pcm info missing\n"); + of_node_put(codec_np); return -EINVAL; } at91sam9g20ek_dai.cpus->of_node = cpu_np; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 4de029ae377c..f46a22660103 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -53,6 +53,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_AK5558 imply SND_SOC_ALC5623 imply SND_SOC_ALC5632 + imply SND_SOC_AW8738 imply SND_SOC_BT_SCO imply SND_SOC_BD28623 imply SND_SOC_CQ0093VC @@ -579,6 +580,15 @@ config SND_SOC_ALC5632 tristate depends on I2C +config SND_SOC_AW8738 + tristate "Awinic AW8738 Audio Amplifier" + select GPIOLIB + help + Enable support for the Awinic AW8738 audio amplifier (or similar). + The driver supports simple audio amplifiers similar to + SND_SOC_SIMPLE_AMPLIFIER, but additionally allows setting the + operation mode using the Awinic-specific one-wire pulse control. + config SND_SOC_BD28623 tristate "ROHM BD28623 CODEC" help diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index c3c6059a5f8a..8637e9e869e3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -45,6 +45,7 @@ snd-soc-ak4671-objs := ak4671.o snd-soc-ak5386-objs := ak5386.o snd-soc-ak5558-objs := ak5558.o snd-soc-arizona-objs := arizona.o arizona-jack.o +snd-soc-aw8738-objs := aw8738.o snd-soc-bd28623-objs := bd28623.o snd-soc-bt-sco-objs := bt-sco.o snd-soc-cpcap-objs := cpcap.o @@ -388,6 +389,7 @@ obj-$(CONFIG_SND_SOC_AK5558) += snd-soc-ak5558.o obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o +obj-$(CONFIG_SND_SOC_AW8738) += snd-soc-aw8738.o obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o diff --git a/sound/soc/codecs/aw8738.c b/sound/soc/codecs/aw8738.c new file mode 100644 index 000000000000..0fe8af160319 --- /dev/null +++ b/sound/soc/codecs/aw8738.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <sound/soc.h> + +struct aw8738_priv { + struct gpio_desc *gpiod_mode; + unsigned int mode; +}; + +static int aw8738_drv_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct aw8738_priv *aw = snd_soc_component_get_drvdata(c); + int i; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + for (i = 0; i < aw->mode; i++) { + gpiod_set_value_cansleep(aw->gpiod_mode, 0); + udelay(2); + gpiod_set_value_cansleep(aw->gpiod_mode, 1); + udelay(2); + } + msleep(40); + break; + case SND_SOC_DAPM_PRE_PMD: + gpiod_set_value_cansleep(aw->gpiod_mode, 0); + usleep_range(1000, 2000); + break; + default: + WARN(1, "Unexpected event"); + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dapm_widget aw8738_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN"), + SND_SOC_DAPM_OUT_DRV_E("DRV", SND_SOC_NOPM, 0, 0, NULL, 0, aw8738_drv_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_OUTPUT("OUT"), +}; + +static const struct snd_soc_dapm_route aw8738_dapm_routes[] = { + { "DRV", NULL, "IN" }, + { "OUT", NULL, "DRV" }, +}; + +static const struct snd_soc_component_driver aw8738_component_driver = { + .dapm_widgets = aw8738_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aw8738_dapm_widgets), + .dapm_routes = aw8738_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(aw8738_dapm_routes), +}; + +static int aw8738_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct aw8738_priv *aw; + int ret; + + aw = devm_kzalloc(dev, sizeof(*aw), GFP_KERNEL); + if (!aw) + return -ENOMEM; + platform_set_drvdata(pdev, aw); + + aw->gpiod_mode = devm_gpiod_get(dev, "mode", GPIOD_OUT_LOW); + if (IS_ERR(aw->gpiod_mode)) + return dev_err_probe(dev, PTR_ERR(aw->gpiod_mode), + "Failed to get 'mode' gpio"); + + ret = device_property_read_u32(dev, "awinic,mode", &aw->mode); + if (ret) + return -EINVAL; + + return devm_snd_soc_register_component(&pdev->dev, + &aw8738_component_driver, + NULL, 0); +} + +#ifdef CONFIG_OF +static const struct of_device_id aw8738_of_match[] = { + { .compatible = "awinic,aw8738" }, + { } +}; +MODULE_DEVICE_TABLE(of, aw8738_of_match); +#endif + +static struct platform_driver aw8738_driver = { + .probe = aw8738_probe, + .driver = { + .name = "aw8738", + .of_match_table = of_match_ptr(aw8738_of_match), + }, +}; +module_platform_driver(aw8738_driver); + +MODULE_DESCRIPTION("Awinic AW8738 Amplifier Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 77a017694645..e10d1276a937 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -1091,7 +1091,7 @@ static struct snd_soc_dai_driver cs35l41_dai[] = { .capture = { .stream_name = "AMP Capture", .channels_min = 1, - .channels_max = 8, + .channels_max = 4, .rates = SNDRV_PCM_RATE_KNOT, .formats = CS35L41_TX_FORMATS, }, @@ -1115,9 +1115,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { .set_sysclk = cs35l41_component_set_sysclk, }; -static int cs35l41_handle_pdata(struct device *dev, - struct cs35l41_platform_data *pdata, - struct cs35l41_private *cs35l41) +static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_platform_data *pdata) { struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; @@ -1260,7 +1258,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, if (pdata) { cs35l41->pdata = *pdata; } else { - ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41); + ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata); if (ret != 0) return ret; } diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index db6ef6cdce15..c8409d50e934 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1012,7 +1012,14 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) } } else { if (!cs42l42->stream_use) { - /* SCLK must be running before codec unmute */ + /* SCLK must be running before codec unmute. + * + * PLL must not be started with ADC and HP both off + * otherwise the FILT+ supply will not charge properly. + * DAPM widgets power-up before stream unmute so at least + * one of the "DAC" or "ADC" widgets will already have + * powered-up. + */ if (pll_ratio_table[cs42l42->pll_config].mclk_src_sel) { snd_soc_component_update_bits(component, CS42L42_PLL_CTL1, CS42L42_PLL_START_MASK, 1); @@ -1830,6 +1837,10 @@ static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) cs42l42->hs_type = CS42L42_PLUG_INVALID; + /* + * DETECT_MODE must always be 0 with ADC and HP both off otherwise the + * FILT+ supply will not charge properly. + */ regmap_update_bits(cs42l42->regmap, CS42L42_MISC_DET_CTL, CS42L42_DETECT_MODE_MASK, 0); diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 244b24d1f5e9..60d3bdf5d7c9 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -491,7 +491,10 @@ #define CS42L42_TS_UNPLUG 0 #define CS42L42_TS_TRANS 1 -/* Page 0x15 Fractional-N PLL Registers */ +/* + * NOTE: PLL_START must be 0 while both ADC_PDN=1 and HP_PDN=1. + * Otherwise it will prevent FILT+ from charging properly. + */ #define CS42L42_PLL_CTL1 (CS42L42_PAGE_15 + 0x01) #define CS42L42_PLL_START_SHIFT 0 #define CS42L42_PLL_START_MASK (1 << CS42L42_PLL_START_SHIFT) @@ -574,6 +577,10 @@ #define CS42L42_TIP_SENSE_CTRL_MASK (3 << \ CS42L42_TIP_SENSE_CTRL_SHIFT) +/* + * NOTE: DETECT_MODE must be 0 while both ADC_PDN=1 and HP_PDN=1. + * Otherwise it will prevent FILT+ from charging properly. + */ #define CS42L42_MISC_DET_CTL (CS42L42_PAGE_1B + 0x74) #define CS42L42_PDN_MIC_LVL_DET_SHIFT 0 #define CS42L42_PDN_MIC_LVL_DET_MASK (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT) diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index efa1016831dd..8f3d59c75aa0 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -644,8 +644,7 @@ enum { SAR_PWR_SAVING, }; -static void rt5682s_sar_power_mode(struct snd_soc_component *component, - int mode, int jd_step) +static void rt5682s_sar_power_mode(struct snd_soc_component *component, int mode) { struct rt5682s_priv *rt5682s = snd_soc_component_get_drvdata(component); @@ -675,16 +674,17 @@ static void rt5682s_sar_power_mode(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK, RT5682S_CTRL_MB1_FSM | RT5682S_CTRL_MB2_FSM); - if (!jd_step) { - snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, - RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_SEL_MB1_2_AUTO); - usleep_range(5000, 5500); - snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, - RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK, - RT5682S_SAR_BUTDET_EN | RT5682S_SAR_BUTDET_POW_NORM); - } + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_SEL_MB1_2_AUTO); + usleep_range(5000, 5500); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK, + RT5682S_SAR_BUTDET_EN | RT5682S_SAR_BUTDET_POW_NORM); break; case SAR_PWR_OFF: + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, + RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK, + RT5682S_CTRL_MB1_FSM | RT5682S_CTRL_MB2_FSM); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | @@ -702,6 +702,10 @@ static void rt5682s_enable_push_button_irq(struct snd_soc_component *component) { snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_13, RT5682S_SAR_SOUR_MASK, RT5682S_SAR_SOUR_BTN); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_EN | + RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_AUTO); snd_soc_component_write(component, RT5682S_IL_CMD_1, 0x0040); snd_soc_component_update_bits(component, RT5682S_4BTN_IL_CMD_2, RT5682S_4BTN_IL_MASK | RT5682S_4BTN_IL_RST_MASK, @@ -718,6 +722,10 @@ static void rt5682s_disable_push_button_irq(struct snd_soc_component *component) RT5682S_4BTN_IL_MASK, RT5682S_4BTN_IL_DIS); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_13, RT5682S_SAR_SOUR_MASK, RT5682S_SAR_SOUR_TYPE); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | + RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); } /** @@ -753,7 +761,8 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ RT5682S_OSW_L_DIS | RT5682S_OSW_R_DIS); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_13, RT5682S_SAR_SOUR_MASK, RT5682S_SAR_SOUR_TYPE); - rt5682s_sar_power_mode(component, SAR_PWR_NORMAL, 1); + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_3, + RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_EN); snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, RT5682S_TRIG_JD_MASK, RT5682S_TRIG_JD_LOW); usleep_range(45000, 50000); @@ -779,9 +788,8 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_EN); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT); - if (!snd_soc_dapm_get_pin_status(&component->dapm, "SAR")) - rt5682s_sar_power_mode(component, SAR_PWR_SAVING, 1); rt5682s_enable_push_button_irq(component); + rt5682s_sar_power_mode(component, SAR_PWR_SAVING); break; default: jack_type = SND_JACK_HEADPHONE; @@ -792,7 +800,7 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ RT5682S_OSW_L_EN | RT5682S_OSW_R_EN); usleep_range(35000, 40000); } else { - rt5682s_sar_power_mode(component, SAR_PWR_OFF, 1); + rt5682s_sar_power_mode(component, SAR_PWR_OFF); rt5682s_disable_push_button_irq(component); snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, RT5682S_TRIG_JD_MASK, RT5682S_TRIG_JD_LOW); @@ -1403,10 +1411,10 @@ static int sar_power_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - rt5682s_sar_power_mode(component, SAR_PWR_NORMAL, 0); + rt5682s_sar_power_mode(component, SAR_PWR_NORMAL); break; case SND_SOC_DAPM_POST_PMD: - rt5682s_sar_power_mode(component, SAR_PWR_SAVING, 0); + rt5682s_sar_power_mode(component, SAR_PWR_SAVING); break; } @@ -2835,9 +2843,8 @@ static int rt5682s_suspend(struct snd_soc_component *component) cancel_delayed_work_sync(&rt5682s->jack_detect_work); cancel_delayed_work_sync(&rt5682s->jd_check_work); - if (rt5682s->hs_jack && rt5682s->jack_type == SND_JACK_HEADSET) - snd_soc_component_update_bits(component, RT5682S_4BTN_IL_CMD_2, - RT5682S_4BTN_IL_MASK, RT5682S_4BTN_IL_DIS); + if (rt5682s->hs_jack) + rt5682s->jack_type = rt5682s_headset_detect(component, 0); regcache_cache_only(rt5682s->regmap, true); regcache_mark_dirty(rt5682s->regmap); @@ -2853,8 +2860,6 @@ static int rt5682s_resume(struct snd_soc_component *component) regcache_sync(rt5682s->regmap); if (rt5682s->hs_jack) { - rt5682s->jack_type = 0; - rt5682s_sar_power_mode(component, SAR_PWR_NORMAL, 0); mod_delayed_work(system_power_efficient_wq, &rt5682s->jack_detect_work, msecs_to_jiffies(0)); } diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 15d42ce3b21d..41504ce2a682 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1537,18 +1537,38 @@ static int wm8350_component_probe(struct snd_soc_component *component) wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, WM8350_JDL_ENA | WM8350_JDR_ENA); - wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, wm8350_hpl_jack_handler, 0, "Left jack detect", priv); - wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, + if (ret != 0) + goto err; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, wm8350_hpr_jack_handler, 0, "Right jack detect", priv); - wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, + if (ret != 0) + goto free_jck_det_l; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, wm8350_mic_handler, 0, "Microphone short", priv); - wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, + if (ret != 0) + goto free_jck_det_r; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, wm8350_mic_handler, 0, "Microphone detect", priv); + if (ret != 0) + goto free_micscd; return 0; + +free_micscd: + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv); +free_jck_det_r: + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); +free_jck_det_l: + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); +err: + return ret; } static void wm8350_component_remove(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index c8c8338cb401..375cb14aaccd 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -749,21 +749,48 @@ static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, } static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, - const struct firmware **firmware, - char **filename, - char *suffix) + const struct firmware **firmware, char **filename, + const char *dir, const char *system_name, + const char *asoc_component_prefix, + const char *filetype) { struct cs_dsp *cs_dsp = &dsp->cs_dsp; + char *s, c; int ret = 0; - *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, - wm_adsp_fw[dsp->fw].file, suffix); + if (system_name && asoc_component_prefix) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, dsp->part, + dsp->fwf_name, wm_adsp_fw[dsp->fw].file, system_name, + asoc_component_prefix, filetype); + else if (system_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part, + dsp->fwf_name, wm_adsp_fw[dsp->fw].file, system_name, + filetype); + else + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, dsp->fwf_name, + wm_adsp_fw[dsp->fw].file, filetype); + if (*filename == NULL) return -ENOMEM; - ret = request_firmware(firmware, *filename, cs_dsp->dev); + /* + * Make sure that filename is lower-case and any non alpha-numeric + * characters except full stop and forward slash are replaced with + * hyphens. + */ + s = *filename; + while (*s) { + c = *s; + if (isalnum(c)) + *s = tolower(c); + else if ((c != '.') && (c != '/')) + *s = '-'; + s++; + } + + ret = firmware_request_nowarn(firmware, *filename, cs_dsp->dev); if (ret != 0) { - adsp_err(dsp, "Failed to request '%s'\n", *filename); + adsp_dbg(dsp, "Failed to request '%s'\n", *filename); kfree(*filename); *filename = NULL; } @@ -771,21 +798,69 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, return ret; } +static const char *cirrus_dir = "cirrus/"; static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, const struct firmware **wmfw_firmware, char **wmfw_filename, const struct firmware **coeff_firmware, char **coeff_filename) { + const char *system_name = dsp->system_name; + const char *asoc_component_prefix = dsp->component->name_prefix; int ret = 0; - ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, "wmfw"); - if (ret != 0) - return ret; + if (system_name && asoc_component_prefix) { + if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, + cirrus_dir, system_name, + asoc_component_prefix, "wmfw")) { + adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); + wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, + cirrus_dir, system_name, + asoc_component_prefix, "bin"); + return 0; + } + } - wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, "bin"); + if (system_name) { + if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, + cirrus_dir, system_name, + NULL, "wmfw")) { + adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); + if (asoc_component_prefix) + wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, + cirrus_dir, system_name, + asoc_component_prefix, "bin"); + + if (!*coeff_firmware) + wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, + cirrus_dir, system_name, + NULL, "bin"); + return 0; + } + } - return 0; + if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, + "", NULL, NULL, "wmfw")) { + adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); + wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, + "", NULL, NULL, "bin"); + return 0; + } + + ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, + cirrus_dir, NULL, NULL, "wmfw"); + if (!ret) { + adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); + wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, + cirrus_dir, NULL, NULL, "bin"); + return 0; + } + + adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n", + cirrus_dir, dsp->part, dsp->fwf_name, wm_adsp_fw[dsp->fw].file, + system_name, asoc_component_prefix); + + return -ENOENT; } static int wm_adsp_common_init(struct wm_adsp *dsp) diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 7f4fabbc6ad3..375009a65828 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -28,6 +28,7 @@ struct wm_adsp { struct cs_dsp cs_dsp; const char *part; const char *fwf_name; + const char *system_name; struct snd_soc_component *component; unsigned int sys_config_size; diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index c3947347dda3..c0f3907a01fd 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -503,6 +503,10 @@ static int __graph_parse_node(struct asoc_simple_priv *priv, if (ret < 0) return ret; + ret = asoc_simple_parse_tdm_width_map(dev, ep, dai); + if (ret < 0) + return ret; + ret = asoc_simple_parse_clk(dev, ep, dai, dlc); if (ret < 0) return ret; diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index a4babfb63175..14c8b3a74c2d 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -12,6 +12,7 @@ #include <linux/of_gpio.h> #include <linux/of_graph.h> #include <sound/jack.h> +#include <sound/pcm_params.h> #include <sound/simple_card_utils.h> void asoc_simple_convert_fixup(struct asoc_simple_data *data, @@ -87,6 +88,51 @@ int asoc_simple_parse_daifmt(struct device *dev, } EXPORT_SYMBOL_GPL(asoc_simple_parse_daifmt); +int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np, + struct asoc_simple_dai *dai) +{ + u32 *array_values, *p; + int n, i, ret; + + if (!of_property_read_bool(np, "dai-tdm-slot-width-map")) + return 0; + + n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32)); + if (n % 3) { + dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n"); + return -EINVAL; + } + + dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL); + if (!dai->tdm_width_map) + return -ENOMEM; + + array_values = kcalloc(n, sizeof(*array_values), GFP_KERNEL); + if (!array_values) + return -ENOMEM; + + ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n); + if (ret < 0) { + dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret); + goto out; + } + + p = array_values; + for (i = 0; i < n / 3; ++i) { + dai->tdm_width_map[i].sample_bits = *p++; + dai->tdm_width_map[i].slot_width = *p++; + dai->tdm_width_map[i].slot_count = *p++; + } + + dai->n_tdm_widths = i; + ret = 0; +out: + kfree(array_values); + + return ret; +} +EXPORT_SYMBOL_GPL(asoc_simple_parse_tdm_width_map); + int asoc_simple_set_dailink_name(struct device *dev, struct snd_soc_dai_link *dai_link, const char *fmt, ...) @@ -309,6 +355,42 @@ static int asoc_simple_set_clk_rate(struct device *dev, return clk_set_rate(simple_dai->clk, rate); } +static int asoc_simple_set_tdm(struct snd_soc_dai *dai, + struct asoc_simple_dai *simple_dai, + struct snd_pcm_hw_params *params) +{ + int sample_bits = params_width(params); + int slot_width = simple_dai->slot_width; + int slot_count = simple_dai->slots; + int i, ret; + + if (!simple_dai || !simple_dai->tdm_width_map) + return 0; + + if (slot_width == 0) + slot_width = sample_bits; + + for (i = 0; i < simple_dai->n_tdm_widths; ++i) { + if (simple_dai->tdm_width_map[i].sample_bits == sample_bits) { + slot_width = simple_dai->tdm_width_map[i].slot_width; + slot_count = simple_dai->tdm_width_map[i].slot_count; + break; + } + } + + ret = snd_soc_dai_set_tdm_slot(dai, + simple_dai->tx_slot_mask, + simple_dai->rx_slot_mask, + slot_count, + slot_width); + if (ret && ret != -ENOTSUPP) { + dev_err(dai->dev, "simple-card: set_tdm_slot error: %d\n", ret); + return ret; + } + + return 0; +} + int asoc_simple_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -362,6 +444,21 @@ int asoc_simple_hw_params(struct snd_pcm_substream *substream, return ret; } } + + for_each_prop_dai_codec(props, i, pdai) { + sdai = asoc_rtd_to_codec(rtd, i); + ret = asoc_simple_set_tdm(sdai, pdai, params); + if (ret < 0) + return ret; + } + + for_each_prop_dai_cpu(props, i, pdai) { + sdai = asoc_rtd_to_cpu(rtd, i); + ret = asoc_simple_set_tdm(sdai, pdai, params); + if (ret < 0) + return ret; + } + return 0; } EXPORT_SYMBOL_GPL(asoc_simple_hw_params); diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index da59504d2322..6884ddf9edad 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -103,6 +103,7 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH tristate "Baytrail and Baytrail-CR with RT5640 codec" depends on I2C && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_ACPI select SND_SOC_RT5640 help @@ -115,6 +116,7 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH tristate "Baytrail and Baytrail-CR with RT5651 codec" depends on I2C && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_ACPI select SND_SOC_RT5651 help @@ -127,6 +129,7 @@ config SND_SOC_INTEL_BYTCR_WM5102_MACH tristate "Baytrail and Baytrail-CR with WM5102 codec" depends on MFD_ARIZONA && MFD_WM5102 && SPI_MASTER && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_ACPI select SND_SOC_WM5102 help @@ -139,6 +142,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH tristate "Cherrytrail & Braswell with RT5672 codec" depends on I2C && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_ACPI select SND_SOC_RT5670 help @@ -163,6 +167,7 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH tristate "Cherrytrail & Braswell with MAX98090 & TI codec" depends on I2C && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_MAX98090 select SND_SOC_TS3A227E help @@ -187,6 +192,7 @@ config SND_SOC_INTEL_BYT_CHT_CX2072X_MACH tristate "Baytrail & Cherrytrail with CX2072X codec" depends on I2C && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_ACPI select SND_SOC_CX2072X help @@ -211,6 +217,7 @@ config SND_SOC_INTEL_BYT_CHT_ES8316_MACH tristate "Baytrail & Cherrytrail with ES8316 codec" depends on I2C && ACPI depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_ACPI select SND_SOC_ES8316 help @@ -242,7 +249,7 @@ if SND_SOC_INTEL_SKL config SND_SOC_INTEL_SKL_RT286_MACH tristate "SKL with RT286 I2S mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_RT286 select SND_SOC_DMIC @@ -255,7 +262,7 @@ config SND_SOC_INTEL_SKL_RT286_MACH config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH tristate "SKL with NAU88L25 and SSM4567 in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_NAU8825 select SND_SOC_SSM4567 @@ -269,7 +276,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH tristate "SKL with NAU88L25 and MAX98357A in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_NAU8825 select SND_SOC_MAX98357A @@ -300,7 +307,7 @@ if SND_SOC_INTEL_APL config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH tristate "Broxton with DA7219 and MAX98357A/MAX98390 in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON @@ -312,7 +319,7 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH config SND_SOC_INTEL_BXT_RT298_MACH tristate "Broxton with RT298 I2S mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_RT298 select SND_SOC_DMIC @@ -332,6 +339,7 @@ config SND_SOC_INTEL_SOF_WM8804_MACH tristate "SOF with Wolfson/Cirrus WM8804 codec" depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_WM8804_I2C help This adds support for ASoC machine driver for Intel platforms @@ -345,7 +353,7 @@ if SND_SOC_INTEL_KBL config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH tristate "KBL with RT5663 and MAX98927 in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_RT5663 select SND_SOC_MAX98927 @@ -377,7 +385,7 @@ config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH tristate "KBL with DA7219 and MAX98357A in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC help @@ -387,7 +395,7 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH tristate "KBL with DA7219 and MAX98927 in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_DA7219 select SND_SOC_MAX98927 @@ -404,6 +412,7 @@ config SND_SOC_INTEL_KBL_RT5660_MACH tristate "KBL with RT5660 in I2S Mode" depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST select SND_SOC_RT5660 select SND_SOC_HDAC_HDMI help @@ -417,7 +426,7 @@ if SND_SOC_SOF_GEMINILAKE config SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH tristate "GLK with DA7219 and MAX98357A in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON @@ -429,7 +438,7 @@ config SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH tristate "GLK with RT5682 and MAX98357A in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_RT5682_I2C @@ -451,7 +460,6 @@ if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH tristate "Skylake+ with HDA Codecs" depends on SND_HDA_CODEC_HDMI - depends on GPIOLIB select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_DMIC @@ -468,7 +476,7 @@ endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC if SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL config SND_SOC_INTEL_SOF_RT5682_MACH tristate "SOF with rt5682 codec in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on ((SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC) &&\ (MFD_INTEL_LPSS || COMPILE_TEST)) ||\ (SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST)) @@ -523,8 +531,9 @@ config SND_SOC_INTEL_SOF_PCM512x_MACH config SND_SOC_INTEL_SOF_ES8336_MACH tristate "SOF with ES8336 codec in I2S mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_ES8316 select SND_SOC_DMIC @@ -537,7 +546,7 @@ config SND_SOC_INTEL_SOF_ES8336_MACH config SND_SOC_INTEL_SOF_NAU8825_MACH tristate "SOF with nau8825 codec in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on ((SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC) &&\ (MFD_INTEL_LPSS || COMPILE_TEST)) select SND_SOC_NAU8825 @@ -560,7 +569,7 @@ if (SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK) config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH tristate "CML_LP with DA7219 and MAX98357A in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON help @@ -571,7 +580,7 @@ config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH tristate "CML with RT1011 and RT5682 in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_RT1011 @@ -591,7 +600,7 @@ if SND_SOC_SOF_JASPERLAKE config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH tristate "SOF with DA7219 and MAX98373/MAX98360A in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_INTEL_HDA_DSP_COMMON @@ -608,7 +617,7 @@ endif ## SND_SOC_SOF_JASPERLAKE config SND_SOC_INTEL_SOF_SSP_AMP_MACH tristate "SOF with amplifiers in I2S Mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST select SND_SOC_RT1308 select SND_SOC_CS35L41_I2C @@ -627,7 +636,7 @@ if SND_SOC_SOF_ELKHARTLAKE config SND_SOC_INTEL_EHL_RT5660_MACH tristate "EHL with RT5660 in I2S mode" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_RT5660 @@ -643,7 +652,7 @@ if SND_SOC_SOF_INTEL_SOUNDWIRE config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH tristate "SoundWire generic machine driver" - depends on I2C && ACPI && GPIOLIB + depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST depends on SOUNDWIRE diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index da515eb1ddbe..1f00679b4240 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -185,7 +185,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 0cd0dae5c545..82f5eafb2f6c 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -193,7 +193,7 @@ config SND_SOC_SC7280 select SND_SOC_QCOM_COMMON select SND_SOC_LPASS_SC7280 select SND_SOC_MAX98357A - select SND_SOC_WCD938X + select SND_SOC_WCD938X_SDW select SND_SOC_LPASS_MACRO_COMMON select SND_SOC_LPASS_RX_MACRO select SND_SOC_LPASS_TX_MACRO diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index cdf3b7f69ba7..e9a1eb6bdf66 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -816,14 +816,27 @@ static int fsi_clk_enable(struct device *dev, return ret; } - clk_enable(clock->xck); - clk_enable(clock->ick); - clk_enable(clock->div); + ret = clk_enable(clock->xck); + if (ret) + goto err; + ret = clk_enable(clock->ick); + if (ret) + goto disable_xck; + ret = clk_enable(clock->div); + if (ret) + goto disable_ick; clock->count++; } return ret; + +disable_ick: + clk_disable(clock->ick); +disable_xck: + clk_disable(clock->xck); +err: + return ret; } static int fsi_clk_disable(struct device *dev, |