sound/pci/hda/patch_conexant.c | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
When Z60MR100 startup, speaker will output a pop. To fix this issue,
we mute codec by init verbs in bios when system startup, and set GPIO
to low to unmute codec in codec driver when it loaded .
Signed-off-by: bo liu <bo.liu@senarytech.com>
---
sound/pci/hda/patch_conexant.c | 35 ++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index e851785ff058..62c53e64bcad 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -42,6 +42,7 @@ struct conexant_spec {
unsigned int gpio_led;
unsigned int gpio_mute_led_mask;
unsigned int gpio_mic_led_mask;
+ unsigned int gpio_unmute_bit_mask;
bool is_cx8070_sn6140;
};
@@ -308,6 +309,7 @@ enum {
CXT_FIXUP_HP_MIC_NO_PRESENCE,
CXT_PINCFG_SWS_JS201D,
CXT_PINCFG_TOP_SPEAKER,
+ CXT_FIXUP_HP_A_U,
};
/* for hda_fixup_thinkpad_acpi() */
@@ -762,6 +764,24 @@ static void cxt_setup_mute_led(struct hda_codec *codec,
}
}
+static void cxt_setup_mute_gpio_and_unmute(struct hda_codec *codec,
+ unsigned int gpio_mute_mask)
+{
+ struct conexant_spec *spec = codec->spec;
+
+ if (gpio_mute_mask) {
+ spec->gpio_unmute_bit_mask = gpio_mute_mask;
+
+ //set gpio data to 0.
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
+ spec->gpio_unmute_bit_mask);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
+ spec->gpio_unmute_bit_mask);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_STICKY_MASK, 0);
+ }
+}
+
static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
@@ -776,6 +796,15 @@ static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec,
cxt_setup_mute_led(codec, 0x10, 0x20);
}
+static void cxt_fixup_hp_a_u(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ //Init vers in BIOS mute the spk/hp by set gpio high to avoid pop noise,
+ //so need to unmute once by clearing the gpio data when runs into the system.
+ if (action == HDA_FIXUP_ACT_INIT)
+ cxt_setup_mute_gpio_and_unmute(codec, 0x2);
+}
+
/* ThinkPad X200 & co with cxt5051 */
static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -982,6 +1011,10 @@ static const struct hda_fixup cxt_fixups[] = {
{ }
},
},
+ [CXT_FIXUP_HP_A_U] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cxt_fixup_hp_a_u,
+ },
};
static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -1055,6 +1088,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
+ SND_PCI_QUIRK(0x14f1, 0x0252, "MBX-Z60MR100", CXT_FIXUP_HP_A_U),
SND_PCI_QUIRK(0x14f1, 0x0265, "SWS JS201D", CXT_PINCFG_SWS_JS201D),
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
@@ -1100,6 +1134,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
{ .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" },
{ .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" },
{ .id = CXT_PINCFG_TOP_SPEAKER, .name = "sirius-top-speaker" },
+ { .id = CXT_FIXUP_HP_A_U, .name = "HP-U-support" },
{}
};
--
2.34.1
On Thu, 28 Nov 2024 07:08:12 +0100, bo liu wrote: > > When Z60MR100 startup, speaker will output a pop. To fix this issue, > we mute codec by init verbs in bios when system startup, and set GPIO > to low to unmute codec in codec driver when it loaded . > > Signed-off-by: bo liu <bo.liu@senarytech.com> > --- > sound/pci/hda/patch_conexant.c | 35 ++++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c > index e851785ff058..62c53e64bcad 100644 > --- a/sound/pci/hda/patch_conexant.c > +++ b/sound/pci/hda/patch_conexant.c > @@ -42,6 +42,7 @@ struct conexant_spec { > unsigned int gpio_led; > unsigned int gpio_mute_led_mask; > unsigned int gpio_mic_led_mask; > + unsigned int gpio_unmute_bit_mask; > bool is_cx8070_sn6140; > }; > > @@ -308,6 +309,7 @@ enum { > CXT_FIXUP_HP_MIC_NO_PRESENCE, > CXT_PINCFG_SWS_JS201D, > CXT_PINCFG_TOP_SPEAKER, > + CXT_FIXUP_HP_A_U, > }; > > /* for hda_fixup_thinkpad_acpi() */ > @@ -762,6 +764,24 @@ static void cxt_setup_mute_led(struct hda_codec *codec, > } > } > > +static void cxt_setup_mute_gpio_and_unmute(struct hda_codec *codec, > + unsigned int gpio_mute_mask) > +{ > + struct conexant_spec *spec = codec->spec; > + > + if (gpio_mute_mask) { > + spec->gpio_unmute_bit_mask = gpio_mute_mask; Any reason to store this in spec? As far as I see the code below, it's used only locally here, so it doesn't have to be stored there. > + > + //set gpio data to 0. Put a space after "//". > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, > + spec->gpio_unmute_bit_mask); > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, > + spec->gpio_unmute_bit_mask); > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_STICKY_MASK, 0); > + } > +} > + > static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, > const struct hda_fixup *fix, int action) > { > @@ -776,6 +796,15 @@ static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, > cxt_setup_mute_led(codec, 0x10, 0x20); > } > > +static void cxt_fixup_hp_a_u(struct hda_codec *codec, > + const struct hda_fixup *fix, int action) > +{ > + //Init vers in BIOS mute the spk/hp by set gpio high to avoid pop noise, > + //so need to unmute once by clearing the gpio data when runs into the system. Ditto. thanks, Takashi
> On Thu, 28 Nov 2024 07:08:12 +0100, > bo liu wrote: > > > > When Z60MR100 startup, speaker will output a pop. To fix this issue, > > we mute codec by init verbs in bios when system startup, and set GPIO > > to low to unmute codec in codec driver when it loaded . > > > > Signed-off-by: bo liu <bo.liu@senarytech.com> > > --- > > sound/pci/hda/patch_conexant.c | 35 > > ++++++++++++++++++++++++++++++++++ > > 1 file changed, 35 insertions(+) > > > > diff --git a/sound/pci/hda/patch_conexant.c > > b/sound/pci/hda/patch_conexant.c index e851785ff058..62c53e64bcad > > 100644 > > --- a/sound/pci/hda/patch_conexant.c > > +++ b/sound/pci/hda/patch_conexant.c > > @@ -42,6 +42,7 @@ struct conexant_spec { > > unsigned int gpio_led; > > unsigned int gpio_mute_led_mask; > > unsigned int gpio_mic_led_mask; > > + unsigned int gpio_unmute_bit_mask; > > bool is_cx8070_sn6140; > > }; > > > > @@ -308,6 +309,7 @@ enum { > > CXT_FIXUP_HP_MIC_NO_PRESENCE, > > CXT_PINCFG_SWS_JS201D, > > CXT_PINCFG_TOP_SPEAKER, > > + CXT_FIXUP_HP_A_U, > > }; > > > > /* for hda_fixup_thinkpad_acpi() */ > > @@ -762,6 +764,24 @@ static void cxt_setup_mute_led(struct hda_codec *codec, > > } > > } > > > > +static void cxt_setup_mute_gpio_and_unmute(struct hda_codec *codec, > > + unsigned int gpio_mute_mask) > > +{ > > + struct conexant_spec *spec = codec->spec; > > + > > + if (gpio_mute_mask) { > > + spec->gpio_unmute_bit_mask = gpio_mute_mask; > > Any reason to store this in spec? As far as I see the code below, it's used only locally here, so it doesn't have to be stored there. The purpose of adding this is to differentiate the configuration of the LED_MUTE GPIO and to retain debugging information. Of course, this field can be removed if desired. > > + > > + //set gpio data to 0. > Put a space after "//". OK. > > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); > > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, > > + spec->gpio_unmute_bit_mask); > > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, > > + spec->gpio_unmute_bit_mask); > > + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_STICKY_MASK, 0); > > + } > > +} > > + > > static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, > > const struct hda_fixup *fix, int action) { @@ -776,6 +796,15 @@ > > static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, > > cxt_setup_mute_led(codec, 0x10, 0x20); } > > > > +static void cxt_fixup_hp_a_u(struct hda_codec *codec, > > + const struct hda_fixup *fix, int action) { > > + //Init vers in BIOS mute the spk/hp by set gpio high to avoid pop noise, > > + //so need to unmute once by clearing the gpio data when runs into the system. > Ditto. thanks, Takashi
On Thu, 28 Nov 2024 09:25:22 +0100, <bo.liu@senarytech.com> wrote: > > > On Thu, 28 Nov 2024 07:08:12 +0100, > > bo liu wrote: > > > > > > When Z60MR100 startup, speaker will output a pop. To fix this issue, > > > we mute codec by init verbs in bios when system startup, and set GPIO > > > to low to unmute codec in codec driver when it loaded . > > > > > > Signed-off-by: bo liu <bo.liu@senarytech.com> > > > --- > > > sound/pci/hda/patch_conexant.c | 35 > > > ++++++++++++++++++++++++++++++++++ > > > 1 file changed, 35 insertions(+) > > > > > > diff --git a/sound/pci/hda/patch_conexant.c > > > b/sound/pci/hda/patch_conexant.c index e851785ff058..62c53e64bcad > > > 100644 > > > --- a/sound/pci/hda/patch_conexant.c > > > +++ b/sound/pci/hda/patch_conexant.c > > > @@ -42,6 +42,7 @@ struct conexant_spec { > > > unsigned int gpio_led; > > > unsigned int gpio_mute_led_mask; > > > unsigned int gpio_mic_led_mask; > > > + unsigned int gpio_unmute_bit_mask; > > > bool is_cx8070_sn6140; > > > }; > > > > > > @@ -308,6 +309,7 @@ enum { > > > CXT_FIXUP_HP_MIC_NO_PRESENCE, > > > CXT_PINCFG_SWS_JS201D, > > > CXT_PINCFG_TOP_SPEAKER, > > > + CXT_FIXUP_HP_A_U, > > > }; > > > > > > /* for hda_fixup_thinkpad_acpi() */ > > > @@ -762,6 +764,24 @@ static void cxt_setup_mute_led(struct hda_codec > *codec, > > > } > > > } > > > > > > +static void cxt_setup_mute_gpio_and_unmute(struct hda_codec *codec, > > > + unsigned int gpio_mute_mask) > > > +{ > > > + struct conexant_spec *spec = codec->spec; > > > + > > > + if (gpio_mute_mask) { > > > + spec->gpio_unmute_bit_mask = gpio_mute_mask; > > > > Any reason to store this in spec? As far as I see the code below, it's > used only locally here, so it doesn't have to be stored there. > > The purpose of adding this is to differentiate the configuration of the > LED_MUTE GPIO and to retain debugging information. Of course, this field can > be removed if desired. Yes, please remove. Takashi
© 2016 - 2024 Red Hat, Inc.