[PATCH v2 0/4] ASoC: Intel: bytcr_wm5102: add various quirks
Hi Mark,
As requested here is a v2 of my series to add various quirks to the bytcr_wm5102 Intel board driver to make it more flexible.
Changes in v2: - Dropped 2 already merged patches - Rebased on top of broonie/sound/for-6.7
Regards,
Hans
Hans de Goede (4): ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_SSP2 quirk ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_MCLK_19_2MHZ quirk ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_OUT_MAP quirk ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_IN_MAP quirk
sound/soc/intel/boards/bytcr_wm5102.c | 229 +++++++++++++++++++++++--- 1 file changed, 202 insertions(+), 27 deletions(-)
Add the standard intel board file quirk mechanism also used in many other intel board drivers and add a BYT_WM5102_SSP2 quirk setting for designs using SSP2 instead of SSP0.
And enable the new BYT_WM5102_SSP2 quirk on Cherry Trail devices since those always use SSP2.
The logging of the quirks uses dev_info_once() because probe() may run multiple times because of snd_soc_register_card() returning -EPROBE_DEFER.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_wm5102.c | 93 +++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 13 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index fd7d5fdfd3fd..932a5523b682 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/platform_data/x86/soc.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spi/spi.h> @@ -37,6 +38,21 @@ struct byt_wm5102_private { struct gpio_desc *spkvdd_en_gpio; };
+/* Bits 0-15 are reserved for things like an input-map */ +#define BYT_WM5102_SSP2 BIT(16) + +static unsigned long quirk; + +static int quirk_override = -1; +module_param_named(quirk, quirk_override, int, 0444); +MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + +static void log_quirks(struct device *dev) +{ + if (quirk & BYT_WM5102_SSP2) + dev_info_once(dev, "quirk SSP2 enabled"); +} + static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -166,14 +182,24 @@ static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { {"Headset Mic", NULL, "MICBIAS1"}, {"Headset Mic", NULL, "MICBIAS2"}, {"IN1L", NULL, "Headset Mic"}, +};
+static const struct snd_soc_dapm_route bytcr_wm5102_ssp0_map[] = { {"AIF1 Playback", NULL, "ssp0 Tx"}, {"ssp0 Tx", NULL, "modem_out"}, - {"modem_in", NULL, "ssp0 Rx"}, {"ssp0 Rx", NULL, "AIF1 Capture"}, };
+static const struct snd_soc_dapm_route bytcr_wm5102_ssp2_map[] = { + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + static const struct snd_kcontrol_new byt_wm5102_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -202,7 +228,8 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_card *card = runtime->card; struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; - int ret, jack_type; + const struct snd_soc_dapm_route *custom_map = NULL; + int ret, jack_type, num_routes = 0;
card->dapm.idle_bias_off = true;
@@ -213,6 +240,17 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) return ret; }
+ if (quirk & BYT_WM5102_SSP2) { + custom_map = bytcr_wm5102_ssp2_map; + num_routes = ARRAY_SIZE(bytcr_wm5102_ssp2_map); + } else { + custom_map = bytcr_wm5102_ssp0_map; + num_routes = ARRAY_SIZE(bytcr_wm5102_ssp0_map); + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + /* * The firmware might enable the clock at boot (this information * may or may not be reflected in the enable clock register). @@ -253,7 +291,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - int ret; + int ret, bits;
/* The DSP will convert the FE rate to 48k, stereo */ rate->min = 48000; @@ -261,8 +299,15 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = 2; channels->max = 2;
- /* set SSP0 to 16-bit */ - params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + if (quirk & BYT_WM5102_SSP2) { + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + bits = 24; + } else { + /* set SSP0 to 16-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + bits = 16; + }
/* * Default mode for SSP configuration is TDM 4 slot, override config @@ -278,7 +323,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; }
- ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret) { dev_err(rtd->dev, "Error setting I2S config: %d\n", ret); return ret; @@ -345,12 +390,9 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = { /* back ends */ { /* - * This must be named SSP2-Codec even though this machine driver - * always uses SSP0. Most machine drivers support both and dynamically - * update the dailink to point to SSP0 or SSP2, while keeping the name - * as "SSP2-Codec". The SOF tplg files hardcode the "SSP2-Codec" even - * in the byt-foo-ssp0.tplg versions because the other machine-drivers - * use "SSP2-Codec" even when SSP0 is used. + * This dailink is updated dynamically to point to SSP0 or SSP2. + * Yet its name is always kept as "SSP2-Codec" because the SOF + * tplg files hardcode "SSP2-Codec" even in byt-foo-ssp0.tplg. */ .name = "SSP2-Codec", .id = 0, @@ -393,8 +435,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) const char *platform_name; struct acpi_device *adev; struct device *codec_dev; + int dai_index = 0; bool sof_parent; - int ret; + int i, ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -441,6 +484,26 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "getting spkvdd-GPIO\n"); }
+ if (soc_intel_is_cht()) { + /* On CHT default to SSP2 */ + quirk = BYT_WM5102_SSP2; + } + if (quirk_override != -1) { + dev_info_once(dev, "Overriding quirk 0x%lx => 0x%x\n", + quirk, quirk_override); + quirk = quirk_override; + } + log_quirks(dev); + + /* find index of codec dai */ + for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { + if (!strcmp(byt_wm5102_dais[i].codecs->name, + "wm5102-codec")) { + dai_index = i; + break; + } + } + /* override platform name, if required */ byt_wm5102_card.dev = dev; platform_name = mach->mach_params.platform; @@ -448,6 +511,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) if (ret) goto out_put_gpio;
+ /* override SSP port, if required */ + if (quirk & BYT_WM5102_SSP2) + byt_wm5102_dais[dai_index].cpus->dai_name = "ssp2-port"; + /* set card and driver name and pm-ops */ sof_parent = snd_soc_acpi_sof_parent(dev); if (sof_parent) {
The Cherry Trail SoC only supports 19200000 as clk-frequency for the pmc_plt_clk used for the audio codec.
Add a BYT_WM5102_MCLK_19_2MHZ quirk for this and enable this by default on Cherry Trail SoCs.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_wm5102.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 932a5523b682..05a07b25e0f2 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -27,8 +27,6 @@ #include "../../codecs/wm5102.h" #include "../atom/sst-atom-controls.h"
-#define MCLK_FREQ 25000000 - #define WM5102_MAX_SYSCLK_4K 49152000 /* max sysclk for 4K family */ #define WM5102_MAX_SYSCLK_11025 45158400 /* max sysclk for 11.025K family */
@@ -36,10 +34,12 @@ struct byt_wm5102_private { struct snd_soc_jack jack; struct clk *mclk; struct gpio_desc *spkvdd_en_gpio; + int mclk_freq; };
/* Bits 0-15 are reserved for things like an input-map */ #define BYT_WM5102_SSP2 BIT(16) +#define BYT_WM5102_MCLK_19_2MHZ BIT(17)
static unsigned long quirk;
@@ -51,6 +51,8 @@ static void log_quirks(struct device *dev) { if (quirk & BYT_WM5102_SSP2) dev_info_once(dev, "quirk SSP2 enabled"); + if (quirk & BYT_WM5102_MCLK_19_2MHZ) + dev_info_once(dev, "quirk MCLK 19.2MHz enabled"); }
static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, @@ -68,6 +70,7 @@ static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int rate) { struct snd_soc_component *codec_component = codec_dai->component; + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(codec_component->card); int sr_mult = ((rate % 4000) == 0) ? (WM5102_MAX_SYSCLK_4K / rate) : (WM5102_MAX_SYSCLK_11025 / rate); @@ -79,7 +82,7 @@ static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int
/* Configure the FLL1 PLL before selecting it */ ret = snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_CLK_SRC_MCLK1, - MCLK_FREQ, rate * sr_mult); + priv->mclk_freq, rate * sr_mult); if (ret) { dev_err(codec_component->dev, "Error setting PLL: %d\n", ret); return ret; @@ -251,6 +254,11 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) if (ret) return ret;
+ if (quirk & BYT_WM5102_MCLK_19_2MHZ) + priv->mclk_freq = 19200000; + else + priv->mclk_freq = 25000000; + /* * The firmware might enable the clock at boot (this information * may or may not be reflected in the enable clock register). @@ -263,7 +271,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) if (!ret) clk_disable_unprepare(priv->mclk);
- ret = clk_set_rate(priv->mclk, MCLK_FREQ); + ret = clk_set_rate(priv->mclk, priv->mclk_freq); if (ret) { dev_err(card->dev, "Error setting MCLK rate: %d\n", ret); return ret; @@ -486,7 +494,7 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
if (soc_intel_is_cht()) { /* On CHT default to SSP2 */ - quirk = BYT_WM5102_SSP2; + quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ; } if (quirk_override != -1) { dev_info_once(dev, "Overriding quirk 0x%lx => 0x%x\n",
Some x86 WM5102 designs don't use the SPK pins for speaker output instead they use the HPOUT2L + HPOUT2R for the speakers.
Add an BYT_WM5102_OUT_MAP quirk mechanism to allow selecting between 2 output maps, one for the speakers on the SPK output pins and one for the speakers on the HPOUT2 pins.
The new HPOUT2 map is enabled by default on CHT because this is used on the Lenovo Yoga Tab 3 YT3-X90 model which is the only Cherry Trail design currently supported. If different CHT designs turn up which need different output maps we can add DMI quirks to select a different map later.
The userspace UCM profile also needs to know about this so setup a components string with this info too.
While at it also drop the unused "Line Out" route.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_wm5102.c | 72 +++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 9 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 05a07b25e0f2..5425f757c2bb 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -10,6 +10,7 @@ */
#include <linux/acpi.h> +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/device.h> #include <linux/init.h> @@ -37,10 +38,17 @@ struct byt_wm5102_private { int mclk_freq; };
-/* Bits 0-15 are reserved for things like an input-map */ +/* Bits 0-3 are reserved for the input-map */ +#define BYT_WM5102_OUT_MAP GENMASK(7, 4) #define BYT_WM5102_SSP2 BIT(16) #define BYT_WM5102_MCLK_19_2MHZ BIT(17)
+/* Note these values are pre-shifted for easy use of setting quirks */ +enum { + BYT_WM5102_SPK_SPK_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 0), + BYT_WM5102_SPK_HPOUT2_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 1), +}; + static unsigned long quirk;
static int quirk_override = -1; @@ -49,6 +57,20 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev) { + switch (quirk & BYT_WM5102_OUT_MAP) { + case BYT_WM5102_SPK_SPK_MAP: + dev_info_once(dev, "quirk SPK_SPK_MAP enabled\n"); + break; + case BYT_WM5102_SPK_HPOUT2_MAP: + dev_info_once(dev, "quirk SPK_HPOUT2_MAP enabled\n"); + break; + default: + dev_warn_once(dev, "quirk sets invalid output map: 0x%lx, defaulting to SPK_SPK_MAP\n", + quirk & BYT_WM5102_OUT_MAP); + quirk &= ~BYT_WM5102_OUT_MAP; + quirk |= BYT_WM5102_SPK_SPK_MAP; + break; + } if (quirk & BYT_WM5102_SSP2) dev_info_once(dev, "quirk SSP2 enabled"); if (quirk & BYT_WM5102_MCLK_19_2MHZ) @@ -164,12 +186,6 @@ static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { {"Headset Mic", NULL, "Platform Clock"}, {"Internal Mic", NULL, "Platform Clock"}, {"Speaker", NULL, "Platform Clock"}, - {"Line Out", NULL, "Platform Clock"}, - - {"Speaker", NULL, "SPKOUTLP"}, - {"Speaker", NULL, "SPKOUTLN"}, - {"Speaker", NULL, "SPKOUTRP"}, - {"Speaker", NULL, "SPKOUTRN"}, {"Speaker", NULL, "Speaker VDD"},
{"Headphone", NULL, "HPOUT1L"}, @@ -203,6 +219,18 @@ static const struct snd_soc_dapm_route bytcr_wm5102_ssp2_map[] = { {"ssp2 Rx", NULL, "AIF1 Capture"}, };
+static const struct snd_soc_dapm_route byt_wm5102_spk_spk_map[] = { + {"Speaker", NULL, "SPKOUTLP"}, + {"Speaker", NULL, "SPKOUTLN"}, + {"Speaker", NULL, "SPKOUTRP"}, + {"Speaker", NULL, "SPKOUTRN"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_spk_hpout2_map[] = { + {"Speaker", NULL, "HPOUT2L"}, + {"Speaker", NULL, "HPOUT2R"}, +}; + static const struct snd_kcontrol_new byt_wm5102_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -243,6 +271,20 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) return ret; }
+ switch (quirk & BYT_WM5102_OUT_MAP) { + case BYT_WM5102_SPK_SPK_MAP: + custom_map = byt_wm5102_spk_spk_map; + num_routes = ARRAY_SIZE(byt_wm5102_spk_spk_map); + break; + case BYT_WM5102_SPK_HPOUT2_MAP: + custom_map = byt_wm5102_spk_hpout2_map; + num_routes = ARRAY_SIZE(byt_wm5102_spk_hpout2_map); + break; + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + if (quirk & BYT_WM5102_SSP2) { custom_map = bytcr_wm5102_ssp2_map; num_routes = ARRAY_SIZE(bytcr_wm5102_ssp2_map); @@ -434,8 +476,11 @@ static struct snd_soc_card byt_wm5102_card = { .fully_routed = true, };
+static char byt_wm5102_components[64]; /* = "cfg-spk:* cfg-int-mic:* cfg-hs-mic:* ..." */ + static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) { + static const char * const out_map_name[] = { "spk", "hpout2" }; char codec_name[SND_ACPI_I2C_ID_LEN]; struct device *dev = &pdev->dev; struct byt_wm5102_private *priv; @@ -493,8 +538,13 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) }
if (soc_intel_is_cht()) { - /* On CHT default to SSP2 */ - quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ; + /* + * CHT always uses SSP2 and 19.2 MHz; and + * the one currently supported CHT design uses HPOUT2 as + * speaker output. + */ + quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ | + BYT_WM5102_SPK_HPOUT2_MAP; } if (quirk_override != -1) { dev_info_once(dev, "Overriding quirk 0x%lx => 0x%x\n", @@ -503,6 +553,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) } log_quirks(dev);
+ snprintf(byt_wm5102_components, sizeof(byt_wm5102_components), + "cfg-spk:%s", out_map_name[FIELD_GET(BYT_WM5102_OUT_MAP, quirk)]); + byt_wm5102_card.components = byt_wm5102_components; + /* find index of codec dai */ for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { if (!strcmp(byt_wm5102_dais[i].codecs->name,
Unlike all designs supported sofar the Lenovo Yoga Tab 3 YT3-X90 does not have its internal microphone (intmic) on IN3L with the headset microphone on IN1L. Instead this tablet has the intmic on IN1L and the hsmic on IN2L.
Add a BYT_WM5102_IN_MAP quirk mechanism to allow selecting between different input maps and add support for both setups with the current settings being the default map.
The new INTMIC_IN1L_HSMIC_IN2L map is enabled by default on CHT because the Lenovo Yoga Tab 3 YT3-X90 model is the only Cherry Trail design currently supported. If different CHT designs turn up which need different input maps we can add DMI quirks to select a different map later.
The userspace UCM profile also needs to know about this so extend the components string with this info too.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_wm5102.c | 60 +++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 5425f757c2bb..6978ebde6693 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -38,11 +38,16 @@ struct byt_wm5102_private { int mclk_freq; };
-/* Bits 0-3 are reserved for the input-map */ +#define BYT_WM5102_IN_MAP GENMASK(3, 0) #define BYT_WM5102_OUT_MAP GENMASK(7, 4) #define BYT_WM5102_SSP2 BIT(16) #define BYT_WM5102_MCLK_19_2MHZ BIT(17)
+enum { + BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L, + BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L, +}; + /* Note these values are pre-shifted for easy use of setting quirks */ enum { BYT_WM5102_SPK_SPK_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 0), @@ -57,6 +62,20 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev) { + switch (quirk & BYT_WM5102_IN_MAP) { + case BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L: + dev_info_once(dev, "quirk INTMIC_IN3L_HSMIC_IN1L enabled\n"); + break; + case BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L: + dev_info_once(dev, "quirk INTMIC_IN1L_HSMIC_IN2L enabled\n"); + break; + default: + dev_warn_once(dev, "quirk sets invalid input map: 0x%lx, defaulting to INTMIC_IN3L_HSMIC_IN1L\n", + quirk & BYT_WM5102_IN_MAP); + quirk &= ~BYT_WM5102_IN_MAP; + quirk |= BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L; + break; + } switch (quirk & BYT_WM5102_OUT_MAP) { case BYT_WM5102_SPK_SPK_MAP: dev_info_once(dev, "quirk SPK_SPK_MAP enabled\n"); @@ -191,16 +210,13 @@ static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { {"Headphone", NULL, "HPOUT1L"}, {"Headphone", NULL, "HPOUT1R"},
- {"Internal Mic", NULL, "MICBIAS3"}, - {"IN3L", NULL, "Internal Mic"}, - /* * The Headset Mix uses MICBIAS1 or 2 depending on if a CTIA/OMTP Headset * is connected, as the MICBIAS is applied after the CTIA/OMTP cross-switch. */ {"Headset Mic", NULL, "MICBIAS1"}, {"Headset Mic", NULL, "MICBIAS2"}, - {"IN1L", NULL, "Headset Mic"}, + {"Internal Mic", NULL, "MICBIAS3"}, };
static const struct snd_soc_dapm_route bytcr_wm5102_ssp0_map[] = { @@ -231,6 +247,16 @@ static const struct snd_soc_dapm_route byt_wm5102_spk_hpout2_map[] = { {"Speaker", NULL, "HPOUT2R"}, };
+static const struct snd_soc_dapm_route byt_wm5102_intmic_in3l_hsmic_in1l_map[] = { + {"IN3L", NULL, "Internal Mic"}, + {"IN1L", NULL, "Headset Mic"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_intmic_in1l_hsmic_in2l_map[] = { + {"IN1L", NULL, "Internal Mic"}, + {"IN2L", NULL, "Headset Mic"}, +}; + static const struct snd_kcontrol_new byt_wm5102_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -271,6 +297,20 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) return ret; }
+ switch (quirk & BYT_WM5102_IN_MAP) { + case BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L: + custom_map = byt_wm5102_intmic_in3l_hsmic_in1l_map; + num_routes = ARRAY_SIZE(byt_wm5102_intmic_in3l_hsmic_in1l_map); + break; + case BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L: + custom_map = byt_wm5102_intmic_in1l_hsmic_in2l_map; + num_routes = ARRAY_SIZE(byt_wm5102_intmic_in1l_hsmic_in2l_map); + break; + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + switch (quirk & BYT_WM5102_OUT_MAP) { case BYT_WM5102_SPK_SPK_MAP: custom_map = byt_wm5102_spk_spk_map; @@ -481,6 +521,8 @@ static char byt_wm5102_components[64]; /* = "cfg-spk:* cfg-int-mic:* cfg-hs-mic: static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) { static const char * const out_map_name[] = { "spk", "hpout2" }; + static const char * const intmic_map_name[] = { "in3l", "in1l" }; + static const char * const hsmic_map_name[] = { "in1l", "in2l" }; char codec_name[SND_ACPI_I2C_ID_LEN]; struct device *dev = &pdev->dev; struct byt_wm5102_private *priv; @@ -541,9 +583,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) /* * CHT always uses SSP2 and 19.2 MHz; and * the one currently supported CHT design uses HPOUT2 as - * speaker output. + * speaker output and has the intmic on IN1L + hsmic on IN2L. */ quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ | + BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L | BYT_WM5102_SPK_HPOUT2_MAP; } if (quirk_override != -1) { @@ -554,7 +597,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) log_quirks(dev);
snprintf(byt_wm5102_components, sizeof(byt_wm5102_components), - "cfg-spk:%s", out_map_name[FIELD_GET(BYT_WM5102_OUT_MAP, quirk)]); + "cfg-spk:%s cfg-intmic:%s cfg-hsmic:%s", + out_map_name[FIELD_GET(BYT_WM5102_OUT_MAP, quirk)], + intmic_map_name[FIELD_GET(BYT_WM5102_IN_MAP, quirk)], + hsmic_map_name[FIELD_GET(BYT_WM5102_IN_MAP, quirk)]); byt_wm5102_card.components = byt_wm5102_components;
/* find index of codec dai */
On Wed, 25 Oct 2023 16:35:09 +0200, Hans de Goede wrote:
As requested here is a v2 of my series to add various quirks to the bytcr_wm5102 Intel board driver to make it more flexible.
Changes in v2:
- Dropped 2 already merged patches
- Rebased on top of broonie/sound/for-6.7
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_SSP2 quirk commit: 95504218c688d286fb6bfd5f4dd394b74c80832f [2/4] ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_MCLK_19_2MHZ quirk commit: bce4b014cc215afd1eca06977dbe91a1eb63551c [3/4] ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_OUT_MAP quirk commit: c556d202bef1b74dbfa0369bf221ccd83dfa7a59 [4/4] ASoC: Intel: bytcr_wm5102: Add BYT_WM5102_IN_MAP quirk commit: 8619fd0e9026c10841e162ec403f4223fe1f3846
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Hans de Goede
-
Mark Brown