[alsa-devel] [PATCH v2 0/7] Asoc: Various Intel rt5651 patches
Hi All,
Here is a v2 of my previous set with various Intel rt5651 patches.
This version contains a small fix to: [PATCH v2 6/7] ASoC: Intel: bytcr_rt5651: Add support for jack-detect
I forgot to pass the gpio to snd_soc_component_set_jack from the resume handler too (instead of only from the init function).
Other then that there are no changes, so I've kept Pierre-Louis' Acked-by for the entire series.
Regards,
Hans
The Point of View TAB-P1006W-232 (v1.0) tablet uses 10EC5640 as ACPI HID, but it has a rt5651 codec add a quirk for this.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- .../intel/common/soc-acpi-intel-byt-match.c | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c index 097dc06377ba..027dc27262b7 100644 --- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c @@ -21,6 +21,7 @@ static unsigned long byt_machine_id;
#define BYT_THINKPAD_10 1 +#define BYT_POV_P1006W 2
static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id) { @@ -28,6 +29,11 @@ static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id) return 1; }
+static int byt_pov_p1006w_quirk_cb(const struct dmi_system_id *id) +{ + byt_machine_id = BYT_POV_P1006W; + return 1; +}
static const struct dmi_system_id byt_table[] = { { @@ -58,6 +64,17 @@ static const struct dmi_system_id byt_table[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"), }, }, + { + /* Point of View mobii wintab p1006w (v1.0) */ + .callback = byt_pov_p1006w_quirk_cb, + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"), + /* Note 105b is Foxcon's USB/PCI vendor id */ + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"), + }, + }, { } };
@@ -71,16 +88,30 @@ static struct snd_soc_acpi_mach byt_thinkpad_10 = { .asoc_plat_name = "sst-mfld-platform", };
+static struct snd_soc_acpi_mach byt_pov_p1006w = { + .id = "10EC5640", + .drv_name = "bytcr_rt5651", + .fw_filename = "intel/fw_sst_0f28.bin", + .board = "bytcr_rt5651", + .sof_fw_filename = "intel/sof-byt.ri", + .sof_tplg_filename = "intel/sof-byt-rt5651.tplg", + .asoc_plat_name = "sst-mfld-platform", +}; + static struct snd_soc_acpi_mach *byt_quirk(void *arg) { struct snd_soc_acpi_mach *mach = arg;
dmi_check_system(byt_table);
- if (byt_machine_id == BYT_THINKPAD_10) + switch (byt_machine_id) { + case BYT_THINKPAD_10: return &byt_thinkpad_10; - else + case BYT_POV_P1006W: + return &byt_pov_p1006w; + default: return mach; + } }
struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[] = {
Some BYT platforms have a RT5651 codec while using an ACPI node with a HID of 10EC5640 to describe the coded. Add the 10EC5640 HID to the acpi_device_id list, so that the rt5651 will bind to the codec on these devices.
Like the rt5645 and rt5670 drivers which also have the 10EC5640 ACPI HID in their acpi_device_id list for similar reasons, the rt5651 driver checks the codecs device-id register so that it will only bind if the codec actually is a rt5651 and it will ignore actual rt5640 codecs.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5651.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index b7ba64350a07..95183a7de305 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -2138,6 +2138,7 @@ MODULE_DEVICE_TABLE(of, rt5651_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id rt5651_acpi_match[] = { { "10EC5651", 0 }, + { "10EC5640", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, rt5651_acpi_match);
Some board designs hook the jack-detect up to an external GPIO, rather then to one of the codec pins, add support for this.
Figuring out which GPIO to use is pretty much board specific so I've chosen to let the machine driver pass the gpio_desc as data argument to snd_soc_component_set_jack() rather then add support for getting the GPIO to the codec driver. This keeps the codec code nice and clean.
Note that using an external GPIO for this conflicts with button-press support, so this commit disables button-press support when an external GPIO is used.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5651.c | 54 +++++++++++++++++++++++++++------------ sound/soc/codecs/rt5651.h | 1 + 2 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 95183a7de305..673dc1631b9c 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/pm.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/platform_device.h> @@ -1621,6 +1622,12 @@ static bool rt5651_jack_inserted(struct snd_soc_component *component) struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); int val;
+ if (rt5651->gpiod_hp_det) { + val = gpiod_get_value_cansleep(rt5651->gpiod_hp_det); + dev_dbg(component->dev, "jack-detect gpio %d\n", val); + return val; + } + val = snd_soc_component_read32(component, RT5651_INT_IRQ_ST); dev_dbg(component->dev, "irq status %#04x\n", val);
@@ -1761,6 +1768,13 @@ static int rt5651_detect_headset(struct snd_soc_component *component) return SND_JACK_HEADPHONE; }
+static bool rt5651_support_button_press(struct rt5651_priv *rt5651) +{ + /* Button press support only works with internal jack-detection */ + return (rt5651->hp_jack->status & SND_JACK_MICROPHONE) && + rt5651->gpiod_hp_det == NULL; +} + static void rt5651_jack_detect_work(struct work_struct *work) { struct rt5651_priv *rt5651 = @@ -1785,15 +1799,15 @@ static void rt5651_jack_detect_work(struct work_struct *work) WARN_ON(rt5651->ovcd_irq_enabled); rt5651_enable_micbias1_for_ovcd(component); report = rt5651_detect_headset(component); - if (report == SND_JACK_HEADSET) { + dev_dbg(component->dev, "detect report %#02x\n", report); + snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET); + if (rt5651_support_button_press(rt5651)) { /* Enable ovcd IRQ for button press detect. */ rt5651_enable_micbias1_ovcd_irq(component); } else { /* No more need for overcurrent detect. */ rt5651_disable_micbias1_for_ovcd(component); } - dev_dbg(component->dev, "detect report %#02x\n", report); - snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET); } else if (rt5651->ovcd_irq_enabled && rt5651_micbias1_ovcd(component)) { dev_dbg(component->dev, "OVCD IRQ\n");
@@ -1837,16 +1851,20 @@ static void rt5651_cancel_work(void *data) }
static void rt5651_enable_jack_detect(struct snd_soc_component *component, - struct snd_soc_jack *hp_jack) + struct snd_soc_jack *hp_jack, + struct gpio_desc *gpiod_hp_det) { struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); - - /* IRQ output on GPIO1 */ - snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1, - RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ); + bool using_internal_jack_detect = true;
/* Select jack detect source */ switch (rt5651->jd_src) { + case RT5651_JD_NULL: + rt5651->gpiod_hp_det = gpiod_hp_det; + if (!rt5651->gpiod_hp_det) + return; /* No jack detect */ + using_internal_jack_detect = false; + break; case RT5651_JD1_1: snd_soc_component_update_bits(component, RT5651_JD_CTRL2, RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_1); @@ -1865,16 +1883,20 @@ static void rt5651_enable_jack_detect(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1, RT5651_JD2_IRQ_EN, RT5651_JD2_IRQ_EN); break; - case RT5651_JD_NULL: - return; default: dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n"); return; }
- /* Enable jack detect power */ - snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, - RT5651_PWR_JD_M, RT5651_PWR_JD_M); + if (using_internal_jack_detect) { + /* IRQ output on GPIO1 */ + snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1, + RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ); + + /* Enable jack detect power */ + snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, + RT5651_PWR_JD_M, RT5651_PWR_JD_M); + }
/* Set OVCD threshold current and scale-factor */ snd_soc_component_write(component, RT5651_PR_BASE + RT5651_BIAS_CUR4, @@ -1903,7 +1925,7 @@ static void rt5651_enable_jack_detect(struct snd_soc_component *component, RT5651_MB1_OC_STKY_MASK, RT5651_MB1_OC_STKY_EN);
rt5651->hp_jack = hp_jack; - if (rt5651->hp_jack->status & SND_JACK_MICROPHONE) { + if (rt5651_support_button_press(rt5651)) { rt5651_enable_micbias1_for_ovcd(component); rt5651_enable_micbias1_ovcd_irq(component); } @@ -1920,7 +1942,7 @@ static void rt5651_disable_jack_detect(struct snd_soc_component *component) disable_irq(rt5651->irq); rt5651_cancel_work(rt5651);
- if (rt5651->hp_jack->status & SND_JACK_MICROPHONE) { + if (rt5651_support_button_press(rt5651)) { rt5651_disable_micbias1_ovcd_irq(component); rt5651_disable_micbias1_for_ovcd(component); snd_soc_jack_report(rt5651->hp_jack, 0, SND_JACK_BTN_0); @@ -1933,7 +1955,7 @@ static int rt5651_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jack, void *data) { if (jack) - rt5651_enable_jack_detect(component, jack); + rt5651_enable_jack_detect(component, jack, data); else rt5651_disable_jack_detect(component);
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h index ac6de6fb5414..41fcb8b5eb40 100644 --- a/sound/soc/codecs/rt5651.h +++ b/sound/soc/codecs/rt5651.h @@ -2073,6 +2073,7 @@ struct rt5651_priv { struct regmap *regmap; /* Jack and button detect data */ struct snd_soc_jack *hp_jack; + struct gpio_desc *gpiod_hp_det; struct work_struct jack_detect_work; struct delayed_work bp_work; bool ovcd_irq_enabled;
Commit 37c7401e8c1f ("ASoC: Intel: bytcr_rt5651: Fix DMIC map headsetmic mapping"), changed the headsetmic mapping from IN3P to IN2P, this was based on the observation that all bytcr_rt5651 devices I have access to (7 devices) where all using IN3P for the headsetmic. This was an attempt to unifify / simplify the mapping, but it was wrong.
None of those devices was actually using a digital internal mic. Now I've access to a Point of View TAB-P1006W-232 (v1.0) tabler, which does use a DMIC and it does have its headsetmic connected to IN2P, showing that the original mapping was correct, so this commit reverts the change changing the mapping back to IN2P.
Fixes: 37c7401e8c1f ("ASoC: Intel: bytcr_rt5651: Fix DMIC map ... mapping") 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_rt5651.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index e528995668b7..0ed844f2ad01 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -266,7 +266,7 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = { {"DMIC L1", NULL, "Internal Mic"}, {"DMIC R1", NULL, "Internal Mic"}, - {"IN3P", NULL, "Headset Mic"}, + {"IN2P", NULL, "Headset Mic"}, };
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
Add quirks module parameter to allow manually specifying quirks from the kernel commandline (or modprobe.conf).
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_rt5651.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 0ed844f2ad01..6d8ef9dd106e 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -98,6 +98,10 @@ struct byt_rt5651_private { static unsigned long byt_rt5651_quirk = BYT_RT5651_DEFAULT_QUIRKS | BYT_RT5651_IN2_MAP;
+static unsigned int quirk_override; +module_param_named(quirk, quirk_override, uint, 0444); +MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + static void log_quirks(struct device *dev) { if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP) @@ -973,6 +977,12 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) /* check quirks before creating card */ dmi_check_system(byt_rt5651_quirk_table);
+ if (quirk_override) { + dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n", + (unsigned int)byt_rt5651_quirk, quirk_override); + byt_rt5651_quirk = quirk_override; + } + /* Must be called before register_card, also see declaration comment. */ ret_val = byt_rt5651_add_codec_device_props(codec_dev); if (ret_val) {
Some board designs hook the jack-detect up to an external GPIO, rather then to one of the codec pins, add support for this.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- Changes in v2: -Also pass the gpio to snd_soc_component_set_jack from the resume handler --- sound/soc/intel/boards/bytcr_rt5651.c | 43 ++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 6d8ef9dd106e..9a2ee9080897 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -91,6 +91,7 @@ enum { struct byt_rt5651_private { struct clk *mclk; struct gpio_desc *ext_amp_gpio; + struct gpio_desc *hp_detect; struct snd_soc_jack jack; };
@@ -499,6 +500,7 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; + int report; int ret;
card->dapm.idle_bias_off = true; @@ -582,20 +584,27 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) dev_err(card->dev, "unable to set MCLK rate\n"); }
- if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) { + report = 0; + if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) + report = SND_JACK_HEADSET | SND_JACK_BTN_0; + else if (priv->hp_detect) + report = SND_JACK_HEADSET; + + if (report) { ret = snd_soc_card_jack_new(runtime->card, "Headset", - SND_JACK_HEADSET | SND_JACK_BTN_0, - &priv->jack, bytcr_jack_pins, + report, &priv->jack, bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins)); if (ret) { dev_err(runtime->dev, "jack creation failed %d\n", ret); return ret; }
- snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, - KEY_PLAYPAUSE); + if (report & SND_JACK_BTN_0) + snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, + KEY_PLAYPAUSE);
- ret = snd_soc_component_set_jack(codec, &priv->jack, NULL); + ret = snd_soc_component_set_jack(codec, &priv->jack, + priv->hp_detect); if (ret) return ret; } @@ -767,7 +776,8 @@ static int byt_rt5651_resume(struct snd_soc_card *card) for_each_card_components(card, component) { if (!strcmp(component->name, byt_rt5651_codec_name)) { dev_dbg(component->dev, "re-enabling jack detect after resume\n"); - snd_soc_component_set_jack(component, &priv->jack, NULL); + snd_soc_component_set_jack(component, &priv->jack, + priv->hp_detect); break; } } @@ -1012,6 +1022,25 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) return ret_val; } } + priv->hp_detect = devm_fwnode_get_index_gpiod_from_child( + &pdev->dev, "hp-detect", 0, + codec_dev->fwnode, + GPIOD_IN, "hp-detect"); + if (IS_ERR(priv->hp_detect)) { + ret_val = PTR_ERR(priv->hp_detect); + switch (ret_val) { + case -ENOENT: + priv->hp_detect = NULL; + break; + default: + dev_err(&pdev->dev, "Failed to get hp-detect GPIO: %d\n", + ret_val); + /* fall through */ + case -EPROBE_DEFER: + put_device(codec_dev); + return ret_val; + } + } }
put_device(codec_dev);
The patch
ASoC: Intel: bytcr_rt5651: Add support for jack-detect using an external GPIO
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From 90768eaf064041937ef4d6ca95c7e86774cd34a4 Mon Sep 17 00:00:00 2001
From: Hans de Goede hdegoede@redhat.com Date: Sun, 30 Dec 2018 00:00:24 +0100 Subject: [PATCH] ASoC: Intel: bytcr_rt5651: Add support for jack-detect using an external GPIO
Some board designs hook the jack-detect up to an external GPIO, rather then to one of the codec pins, add support for this.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/boards/bytcr_rt5651.c | 43 ++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 6d8ef9dd106e..9a2ee9080897 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -91,6 +91,7 @@ enum { struct byt_rt5651_private { struct clk *mclk; struct gpio_desc *ext_amp_gpio; + struct gpio_desc *hp_detect; struct snd_soc_jack jack; };
@@ -499,6 +500,7 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; + int report; int ret;
card->dapm.idle_bias_off = true; @@ -582,20 +584,27 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) dev_err(card->dev, "unable to set MCLK rate\n"); }
- if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) { + report = 0; + if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) + report = SND_JACK_HEADSET | SND_JACK_BTN_0; + else if (priv->hp_detect) + report = SND_JACK_HEADSET; + + if (report) { ret = snd_soc_card_jack_new(runtime->card, "Headset", - SND_JACK_HEADSET | SND_JACK_BTN_0, - &priv->jack, bytcr_jack_pins, + report, &priv->jack, bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins)); if (ret) { dev_err(runtime->dev, "jack creation failed %d\n", ret); return ret; }
- snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, - KEY_PLAYPAUSE); + if (report & SND_JACK_BTN_0) + snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, + KEY_PLAYPAUSE);
- ret = snd_soc_component_set_jack(codec, &priv->jack, NULL); + ret = snd_soc_component_set_jack(codec, &priv->jack, + priv->hp_detect); if (ret) return ret; } @@ -767,7 +776,8 @@ static int byt_rt5651_resume(struct snd_soc_card *card) for_each_card_components(card, component) { if (!strcmp(component->name, byt_rt5651_codec_name)) { dev_dbg(component->dev, "re-enabling jack detect after resume\n"); - snd_soc_component_set_jack(component, &priv->jack, NULL); + snd_soc_component_set_jack(component, &priv->jack, + priv->hp_detect); break; } } @@ -1012,6 +1022,25 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) return ret_val; } } + priv->hp_detect = devm_fwnode_get_index_gpiod_from_child( + &pdev->dev, "hp-detect", 0, + codec_dev->fwnode, + GPIOD_IN, "hp-detect"); + if (IS_ERR(priv->hp_detect)) { + ret_val = PTR_ERR(priv->hp_detect); + switch (ret_val) { + case -ENOENT: + priv->hp_detect = NULL; + break; + default: + dev_err(&pdev->dev, "Failed to get hp-detect GPIO: %d\n", + ret_val); + /* fall through */ + case -EPROBE_DEFER: + put_device(codec_dev); + return ret_val; + } + } }
put_device(codec_dev);
Add a DMI quirk for the Point of View TAB-P1006W-232 (v1.0) tablet, this tablet is special in a number of ways:
1) It uses the 2nd GPIO resource in the ACPI tables for jack-detect rather then using the rt5651 codec's builtin jack-detect functionality
2) It uses the 3th GPIO resource in the ACPI tables to control the external amplifier rather then the usual first non GpioInt resource and the GPIO is active-low.
3) It is a BYTCR device, without a CHAN package and it uses SSP0-AIF1 rather then the default SSP0-AIF2.
4) Its internal mic is a digital mic (the first x86 rt5651 device that I'm aware of which does this), combined with having its headset-mic connected to IN2.
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_rt5651.c | 48 ++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 9a2ee9080897..b618d984e2d5 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -95,6 +95,8 @@ struct byt_rt5651_private { struct snd_soc_jack jack; };
+static const struct acpi_gpio_mapping *byt_rt5651_gpios; + /* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */ static unsigned long byt_rt5651_quirk = BYT_RT5651_DEFAULT_QUIRKS | BYT_RT5651_IN2_MAP; @@ -365,6 +367,22 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, return byt_rt5651_prepare_and_enable_pll1(codec_dai, rate, bclk_ratio); }
+static const struct acpi_gpio_params pov_p1006w_hp_detect = { 1, 0, false }; +static const struct acpi_gpio_params pov_p1006w_ext_amp_en = { 2, 0, true }; + +static const struct acpi_gpio_mapping byt_rt5651_pov_p1006w_gpios[] = { + { "hp-detect-gpios", &pov_p1006w_hp_detect, 1, }, + { "ext-amp-enable-gpios", &pov_p1006w_ext_amp_en, 1, }, + { }, +}; + +static int byt_rt5651_pov_p1006w_quirk_cb(const struct dmi_system_id *id) +{ + byt_rt5651_quirk = (unsigned long)id->driver_data; + byt_rt5651_gpios = byt_rt5651_pov_p1006w_gpios; + return 1; +} + static int byt_rt5651_quirk_cb(const struct dmi_system_id *id) { byt_rt5651_quirk = (unsigned long)id->driver_data; @@ -440,6 +458,23 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { .driver_data = (void *)(BYT_RT5651_MCLK_EN | BYT_RT5651_IN1_MAP), }, + { + /* Point of View mobii wintab p1006w (v1.0) */ + .callback = byt_rt5651_pov_p1006w_quirk_cb, + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"), + /* Note 105b is Foxcon's USB/PCI vendor id */ + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"), + }, + .driver_data = (void *)(BYT_RT5651_DMIC_MAP | + BYT_RT5651_OVCD_TH_2000UA | + BYT_RT5651_OVCD_SF_0P75 | + BYT_RT5651_DMIC_EN | + BYT_RT5651_MCLK_EN | + BYT_RT5651_SSP0_AIF1), + }, { /* VIOS LTH17 */ .callback = byt_rt5651_quirk_cb, @@ -848,7 +883,7 @@ static int snd_byt_rt5651_acpi_resource(struct acpi_resource *ares, void *arg) return 0; }
-static void snd_byt_rt5651_mc_add_amp_en_gpio_mapping(struct device *codec) +static void snd_byt_rt5651_mc_pick_amp_en_gpio_mapping(struct device *codec) { struct byt_rt5651_acpi_resource_data data = { 0, -1 }; LIST_HEAD(resources); @@ -866,10 +901,10 @@ static void snd_byt_rt5651_mc_add_amp_en_gpio_mapping(struct device *codec)
switch (data.gpio_int_idx) { case 0: - devm_acpi_dev_add_driver_gpios(codec, byt_rt5651_amp_en_second); + byt_rt5651_gpios = byt_rt5651_amp_en_second; break; case 1: - devm_acpi_dev_add_driver_gpios(codec, byt_rt5651_amp_en_first); + byt_rt5651_gpios = byt_rt5651_amp_en_first; break; default: dev_warn(codec, "Unknown GpioInt index %d, not adding external amplifier GPIO mapping\n", @@ -1001,8 +1036,11 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) }
/* Cherry Trail devices use an external amplifier enable gpio */ - if (x86_match_cpu(cherrytrail_cpu_ids)) { - snd_byt_rt5651_mc_add_amp_en_gpio_mapping(codec_dev); + if (x86_match_cpu(cherrytrail_cpu_ids) && !byt_rt5651_gpios) + snd_byt_rt5651_mc_pick_amp_en_gpio_mapping(codec_dev); + + if (byt_rt5651_gpios) { + devm_acpi_dev_add_driver_gpios(codec_dev, byt_rt5651_gpios); priv->ext_amp_gpio = devm_fwnode_get_index_gpiod_from_child( &pdev->dev, "ext-amp-enable", 0, codec_dev->fwnode,
participants (2)
-
Hans de Goede
-
Mark Brown