diff options
Diffstat (limited to 'sound/soc/intel/boards/bytcht_es8316.c')
-rw-r--r-- | sound/soc/intel/boards/bytcht_es8316.c | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index d2a7e6ba11ae..2fe1ce879123 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * bytcht_es8316.c - ASoc Machine driver for Intel Baytrail/Cherrytrail * platforms with Everest ES8316 SoC @@ -8,20 +9,12 @@ * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/acpi.h> #include <linux/clk.h> #include <linux/device.h> +#include <linux/dmi.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/init.h> @@ -40,6 +33,9 @@ #include "../atom/sst-atom-controls.h" #include "../common/sst-dsp.h" +/* jd-inv + terminating entry */ +#define MAX_NO_PROPS 2 + struct byt_cht_es8316_private { struct clk *mclk; struct snd_soc_jack jack; @@ -55,8 +51,9 @@ enum { #define BYT_CHT_ES8316_MAP(quirk) ((quirk) & GENMASK(3, 0)) #define BYT_CHT_ES8316_SSP0 BIT(16) #define BYT_CHT_ES8316_MONO_SPEAKER BIT(17) +#define BYT_CHT_ES8316_JD_INVERTED BIT(18) -static int quirk; +static unsigned long quirk; static int quirk_override = -1; module_param_named(quirk, quirk_override, int, 0444); @@ -72,6 +69,8 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk SSP0 enabled"); if (quirk & BYT_CHT_ES8316_MONO_SPEAKER) dev_info(dev, "quirk MONO_SPEAKER enabled\n"); + if (quirk & BYT_CHT_ES8316_JD_INVERTED) + dev_info(dev, "quirk JD_INVERTED enabled\n"); } static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, @@ -435,15 +434,31 @@ static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = { { }, }; +/* Please keep this list alphabetically sorted */ +static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { + { /* Teclast X98 Plus II */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), + DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"), + }, + .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN1_MAP + | BYT_CHT_ES8316_JD_INVERTED), + }, + {} +}; + static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) { static const char * const mic_name[] = { "in1", "in2" }; + struct property_entry props[MAX_NO_PROPS] = {}; struct byt_cht_es8316_private *priv; + const struct dmi_system_id *dmi_id; struct device *dev = &pdev->dev; struct snd_soc_acpi_mach *mach; const char *platform_name; - const char *i2c_name = NULL; + struct acpi_device *adev; struct device *codec_dev; + unsigned int cnt = 0; int dai_index = 0; int i; int ret = 0; @@ -463,14 +478,16 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) } /* fixup codec name based on HID */ - i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); - if (i2c_name) { + adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); + if (adev) { snprintf(codec_name, sizeof(codec_name), - "%s%s", "i2c-", i2c_name); + "i2c-%s", acpi_dev_name(adev)); + put_device(&adev->dev); byt_cht_es8316_dais[dai_index].codec_name = codec_name; } /* override plaform name, if required */ + byt_cht_es8316_card.dev = dev; platform_name = mach->mach_params.platform; ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card, @@ -479,7 +496,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) return ret; /* Check for BYTCR or other platform and setup quirks */ - if (x86_match_cpu(baytrail_cpu_ids) && + dmi_id = dmi_first_match(byt_cht_es8316_quirk_table); + if (dmi_id) { + quirk = (unsigned long)dmi_id->driver_data; + } else if (x86_match_cpu(baytrail_cpu_ids) && mach->mach_params.acpi_ipc_irq_index == 0) { /* On BYTCR default to SSP0, internal-mic-in2-map, mono-spk */ quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP | @@ -490,7 +510,8 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) BYT_CHT_ES8316_MONO_SPEAKER; } if (quirk_override != -1) { - dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk, + dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", + (unsigned int)quirk, quirk_override); quirk = quirk_override; } @@ -512,6 +533,15 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) if (!codec_dev) return -EPROBE_DEFER; + if (quirk & BYT_CHT_ES8316_JD_INVERTED) + props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); + + if (cnt) { + ret = device_add_properties(codec_dev, props); + if (ret) + return ret; + } + devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios); priv->speaker_en_gpio = gpiod_get_index(codec_dev, "speaker-enable", 0, @@ -538,7 +568,6 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "mono" : "stereo", mic_name[BYT_CHT_ES8316_MAP(quirk)]); byt_cht_es8316_card.long_name = long_name; - byt_cht_es8316_card.dev = dev; snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv); ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card); |