-
Notifications
You must be signed in to change notification settings - Fork 140
Fix sof_8336 gpio problems #4066
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix sof_8336 gpio problems #4066
Conversation
Currently the driver uses quirks to define gpios, which means when the machine has two gpios, the user won't get sound from headphone by default. The patch fix the following problems: 1. Use two gpios by default 2. remove redundant quirks 3. Invert gpio status so that true means on and false means off. Signed-off-by: Zhu Ning <zhuning@everest-semi.com>
|
Basically using two GPIOs by default is fine and the system won't crash. See [gpio.zip].(https://github.com/thesofproject/linux/files/10138979/gpio.zip) |
|
Problems remains: how should the Headphone GPIO be controled? Should another power event, i.e., headphone_power_event be used? @plbossart |
plbossart
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very very difficult to review this, this PR removes things that were added to deal with GPIO inversions and this also changes the GPIO level?
| { "headphone-enable-gpios", &enable_gpio0, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO }, | ||
| { } | ||
| }; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this removed? this was added for a reason...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When two GPIOs are used, Speaker GPIO is always the first and HP GPIO the second. The user may need a quirk to invert the GPIO level.
| gpiod_set_value_cansleep(priv->gpio_speakers, false); | ||
|
|
||
| priv->gpio_headphone = gpiod_get_optional(codec_dev, "headphone-enable", GPIOD_OUT_LOW); | ||
| priv->gpio_headphone = gpiod_get_optional(codec_dev, "headphone-enable", GPIOD_OUT_HIGH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this intentional? why would the GPIO level change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the past speaker_en false means on (high) and true means off (low) because the code is taken from bytcht driver. The patch inverts this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this is going to break existing solutions, I really don't understand this change.
| SOF_HDMI_CAPTURE_1_SSP(0) | | ||
| SOF_HDMI_CAPTURE_2_SSP(2) | | ||
| SOF_SSP_HDMI_CAPTURE_PRESENT | | ||
| SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if gpio1 was used, why did you remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Windows GPIO0 is always the speaker GPIO. The quirk may be reused to invert the GPIO level. (The results are the same: either invert the level or invert the order.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't follow this "either invert the level or invert the order". How is this equivalent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| GPIO1 | GPIO2 | |
|---|---|---|
| Speaker on | high | low |
| Headphone on | low | high |
Inverting the high/low level or changing the GPIO order are basically the same.
plbossart
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still fundamentally do not understand how the levels of the GPIOs is determined. It seems that for speakers it was changed from LOW to HIGH, so it must have some effects on existing users.
Can we not use the _DSM information to determine what the active level is for GPIO0 and GPIO1?
|
|
||
| if (quirk & SOF_ES8336_HEADPHONE_GPIO) | ||
| gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en); | ||
| gpiod_set_value_cansleep(priv->gpio_headphone, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the setting for headphone independent from the speaker enablement? Shouldn't the value be !priv->speaker_en?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Speaker GPIO | Headphone GPIO | |
|---|---|---|
| Playing music Speaker on | high | low |
| Playing music Headphone on | low | high |
| Suspend | low | low |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When only one GPIO is used things are simple. The GPIO is high by default. Before playing music, the SPEAKER_ON dapm event is called and the GPIO set to high. When music stop, the GPIO is set to low so that there is no pop noise.
When HP GPIO is involved things become complicated. I want to do the same for HP GPIO but I don't know how. Maybe another SND_SOC_DAPM_SUPPLY for headphone should be invloved or maybe the headphone status can be read by snd_soc_dapm_get_pin_status(&card->dapm, "Headphone"); and the headphone can be turned on and off in sof_8336_trigger
| if (priv->speaker_en == !SND_SOC_DAPM_EVENT_ON(event)) | ||
| return 0; | ||
| dev_info(card->dev, "sof_es8316_speaker_power_event %d\n",SND_SOC_DAPM_EVENT_ON(event)); | ||
| /* Redundant check, removed */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it redundant? and if yes, it should be a separate patch to avoid confusing reviewers between different functionality and code cleanups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check will return 0 when first time the event is called. So the gpios are always the default value the first time sound is played. Should be a seperate patch.
|
|
||
| if (priv->speaker_en == !SND_SOC_DAPM_EVENT_ON(event)) | ||
| return 0; | ||
| dev_info(card->dev, "sof_es8316_speaker_power_event %d\n",SND_SOC_DAPM_EVENT_ON(event)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dev_info is way too verbose.
|
|
||
| snd_soc_component_set_jack(codec, &priv->jack, NULL); | ||
| ret = snd_soc_dapm_get_pin_status(&card->dapm, "Speaker"); | ||
| dev_info(card->dev, "Speaker status %d", ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this needed?
| goto err_put_codec; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spurious line change
| gpiod_set_value_cansleep(priv->gpio_speakers, false); | ||
|
|
||
| priv->gpio_headphone = gpiod_get_optional(codec_dev, "headphone-enable", GPIOD_OUT_LOW); | ||
| priv->gpio_headphone = gpiod_get_optional(codec_dev, "headphone-enable", GPIOD_OUT_HIGH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this is going to break existing solutions, I really don't understand this change.
Yes there are values defined for GPIO in the DSM, but I don't know how to get them in the machine driver. |
|
@yangxiaohua2009 I'll close this PR since we have no line-of-sight for any update or merge timeline. I have done enough on my side to try and help with this ES8336 support, I don't have time to help further. |
Currently the driver uses quirks to define gpios, which means when the machine has two gpios, the user won't get sound from headphone by default. The patch fix the following problems:
Signed-off-by: Zhu Ning zhuning@everest-semi.com