[PATCH v2 0/4] ASoC: rt5645: Enable internal mic and headset on ECS EF20
These patches are trying to fix the jack detection and internal microphone problems on ECS EF20 series laptops which are empowered by Intel Atom x5-Z8350 CPU (CherryTrail) with Realtek rt5645 audio codec.
--- v1 -> v2: Invoke callback() of the DMI quirk if it exists, because the dmi_first_match() doesn't.
---
Chris Chiu (4): ASoC: rt5645: Introduce mapping for ACPI-defined GPIO ASoC: rt5645: Add ACPI-defined GPIO for ECS EF20 series ASoC: rt5645: add inv_hp_det flag ASoC: rt5645: Enable internal microphone and JD on ECS EF20
include/sound/rt5645.h | 2 ++ sound/soc/codecs/rt5645.c | 48 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-)
On at least one laptop (ECS EF20EA) the 'hp-detect' GPIO is defined in the DSDT table by the ACPI GpioIo resources in _CRS. The GPIO related information should be mapped to the rt5645 driver to enable the jack detection also on non-DT platforms.
Signed-off-by: Chris Chiu chiu@endlessos.org --- v1 -> v2: - none
sound/soc/codecs/rt5645.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 420003d062c7..78f0ab0a008e 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -42,6 +42,8 @@ static unsigned int quirk = -1; module_param(quirk, uint, 0444); MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override");
+static const struct acpi_gpio_mapping *cht_rt5645_gpios; + #define RT5645_DEVICE_ID 0x6308 #define RT5650_DEVICE_ID 0x6419
@@ -3780,7 +3782,6 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&intel_braswell_platform_data, }, - { } };
static bool rt5645_check_dp(struct device *dev) @@ -3848,6 +3849,10 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); }
+ if (cht_rt5645_gpios && has_acpi_companion(&i2c->dev)) + if (devm_acpi_dev_add_driver_gpios(&i2c->dev, cht_rt5645_gpios)) + dev_dbg(&i2c->dev, "Failed to add driver gpios\n"); + rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", GPIOD_IN);
Add the hp-detect gpio for ECS EF20 series laptops based on the _CRS defined in DSDT table.
Method (_CRS, 0, NotSerialized) { Name (SBUF, ResourceTemplate () { I2cSerialBusV2 (0x001A, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\_SB.PCI0.I2C2", 0x00, ResourceConsumer, , Exclusive, ) GpioInt (Edge, ActiveBoth, SharedAndWake, PullNone, 0x0000, "\_SB.GPO3", 0x00, ResourceConsumer, , ) { // Pin list 0x004F } GpioIo (Shared, PullDefault, 0x0000, 0x0000, IoRestrictionInputOnly, "\_SB.GPO3", 0x00, ResourceConsumer, , ) { // Pin list 0x004F } }) Return (SBUF) /* _SB_.PCI0.I2C2.RTK2._CRS.SBUF */ }
Signed-off-by: Chris Chiu chiu@endlessos.org --- v1 -> v2: - Invoke callback() of the DMI quirk if it exists.
sound/soc/codecs/rt5645.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 78f0ab0a008e..94faa0a9561f 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3653,6 +3653,19 @@ static const struct rt5645_platform_data kahlee_platform_data = { .jd_mode = 3, };
+static const struct acpi_gpio_params ef20_hp_detect = { 1, 0, false }; + +static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[] = { + { "hp-detect-gpios", &ef20_hp_detect, 1 }, + { }, +}; + +static int cht_rt5645_ef20_quirk_cb(const struct dmi_system_id *id) +{ + cht_rt5645_gpios = cht_rt5645_ef20_gpios; + return 1; +} + static const struct dmi_system_id dmi_platform_data[] = { { .ident = "Chrome Buddy", @@ -3782,6 +3795,20 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&intel_braswell_platform_data, }, + { + .ident = "EF20", + .callback = cht_rt5645_ef20_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20"), + }, + }, + { + .ident = "EF20EA", + .callback = cht_rt5645_ef20_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), + }, + }, };
static bool rt5645_check_dp(struct device *dev) @@ -3831,6 +3858,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, if (dmi_data) { dev_info(&i2c->dev, "Detected %s platform\n", dmi_data->ident); pdata = dmi_data->driver_data; + if (dmi_data->callback) + dmi_data->callback(dmi_data); }
if (pdata)
The ECS EF20EA laptop use gpio for jack detection instead of rt5645 rt5645 JD. However, the GPIO polarity is inverse for hp-detect based on the _DSD property of the RTK2 device.
Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"hp-detect-gpio", Package() {^RTK2, 0, 0, 1 }}, } })
This flag will invert the hp-detect gpio polarity.
Signed-off-by: Chris Chiu chiu@endlessos.org --- v1 -> v2: - none
include/sound/rt5645.h | 2 ++ sound/soc/codecs/rt5645.c | 4 ++++ 2 files changed, 6 insertions(+)
diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h index 39a77c7cea36..710c95be5509 100644 --- a/include/sound/rt5645.h +++ b/include/sound/rt5645.h @@ -22,6 +22,8 @@ struct rt5645_platform_data { bool level_trigger_irq; /* Invert JD1_1 status polarity */ bool inv_jd1_1; + /* Invert HP detect status polarity */ + bool inv_hp_pol;
/* Value to asign to snd_soc_card.long_name */ const char *long_name; diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 94faa0a9561f..ca1bdb67ecc5 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -34,6 +34,7 @@ #define QUIRK_INV_JD1_1(q) ((q) & 1) #define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1) #define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1) +#define QUIRK_INV_HP_POL(q) (((q) >> 3) & 1) #define QUIRK_JD_MODE(q) (((q) >> 4) & 7) #define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3) #define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3) @@ -3263,6 +3264,8 @@ static void rt5645_jack_detect_work(struct work_struct *work) case 0: /* Not using rt5645 JD */ if (rt5645->gpiod_hp_det) { gpio_state = gpiod_get_value(rt5645->gpiod_hp_det); + if (rt5645->pdata.inv_hp_pol) + gpio_state ^= 1; dev_dbg(rt5645->component->dev, "gpio_state = %d\n", gpio_state); report = rt5645_jack_detect(rt5645->component, gpio_state); @@ -3873,6 +3876,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk); + rt5645->pdata.inv_hp_pol = QUIRK_INV_HP_POL(quirk); rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk); rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk);
On ECS EF20 series laptops, the internal mic is on DMIC2/IN2P. And they need the inv_hp_det to make jack detection to work as exoected.
Signed-off-by: Chris Chiu chiu@endlessos.org --- v1 -> v2: - none
sound/soc/codecs/rt5645.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index ca1bdb67ecc5..6628b7e5a583 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3656,6 +3656,12 @@ static const struct rt5645_platform_data kahlee_platform_data = { .jd_mode = 3, };
+static const struct rt5645_platform_data ecs_ef20_platform_data = { + .dmic1_data_pin = RT5645_DMIC1_DISABLE, + .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, + .inv_hp_pol = 1, +}; + static const struct acpi_gpio_params ef20_hp_detect = { 1, 0, false };
static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[] = { @@ -3804,6 +3810,7 @@ static const struct dmi_system_id dmi_platform_data[] = { .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "EF20"), }, + .driver_data = (void *)&ecs_ef20_platform_data, }, { .ident = "EF20EA", @@ -3811,6 +3818,7 @@ static const struct dmi_system_id dmi_platform_data[] = { .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), }, + .driver_data = (void *)&ecs_ef20_platform_data, }, };
participants (1)
-
Chris Chiu