[PATCH 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.
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 | 46 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 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 --- 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);
On Thu, Jan 07, 2021 at 05:06:22PM +0800, Chris Chiu wrote:
+static const struct acpi_gpio_mapping *cht_rt5645_gpios;
You're adding a read only static variable with no way to set it. This doesn't actually do anything?
@@ -3780,7 +3782,6 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&intel_braswell_platform_data, },
- { }
};
This is an unrelated change which removes the terminator on the array which will cause issues.
On Thu, Jan 7, 2021 at 10:28 PM Mark Brown broonie@kernel.org wrote:
On Thu, Jan 07, 2021 at 05:06:22PM +0800, Chris Chiu wrote:
+static const struct acpi_gpio_mapping *cht_rt5645_gpios;
You're adding a read only static variable with no way to set it. This doesn't actually do anything?
This is a pointer to a 'const 'struct acpi_gpio_mapping', and I will need it to point to the 'static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[]' in my consequent patch '[PATCH 2/4] ASoC: rt5645: Add ACPI-defined GPIO for ECS EF20 series'.
I take the same idea from 'sound/soc/intel/boards/bytcr_rt5651.c' line 90. And it did work as expected on my ECS EF20EA
@@ -3780,7 +3782,6 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&intel_braswell_platform_data, },
{ }
};
This is an unrelated change which removes the terminator on the array which will cause issues.
Thanks for pointing that out. It's not my intention. I accidentally removed it. I'll fix this in v3.
Chris
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 --- sound/soc/codecs/rt5645.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 78f0ab0a008e..24a6acb3c12f 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)
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 --- 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 24a6acb3c12f..530145cf8c5b 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); @@ -3871,6 +3874,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 --- 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 530145cf8c5b..154d9db9ceb3 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 (2)
-
Chris Chiu
-
Mark Brown