All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>,
	Cezary Rojewski <cezary.rojewski@intel.com>,
	Liam Girdwood <liam.r.girdwood@linux.intel.com>,
	Jie Yang <yang.jie@linux.intel.com>,
	Mark Brown <broonie@kernel.org>
Cc: alsa-devel@alsa-project.org, Bard Liao <bard.liao@intel.com>
Subject: Re: [PATCH 5/5] ASoC: Intel: bytcr_rt5640: Add support for HP Elite Pad 1000G2 jack-detect
Date: Wed, 18 Aug 2021 17:46:36 +0200	[thread overview]
Message-ID: <2ea10f32-8810-8257-845e-ec16835fbf19@redhat.com> (raw)
In-Reply-To: <f29d3c63-05ef-73f6-760c-e1b715d96651@linux.intel.com>

Hi Pierre-Louis,

On 8/16/21 3:31 PM, Pierre-Louis Bossart wrote:
> Hi Hans,
> I am a bit confused by the use of acpi_dev_add_driver_gpios().

I understand admittedly my solution there is a bit hacky.

> You call
> it from the dailink .init function, and you call
> acpi_dev_remove_driver_gpios() from the .exit function.
> 
>> @@ -1172,9 +1250,60 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
>>  		snd_soc_component_set_jack(component, &priv->jack, NULL);
>>  	}
>>  
>> +	if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
>> +		ret = snd_soc_card_jack_new(card, "Headset",
>> +					    SND_JACK_HEADSET,
>> +					    &priv->jack, rt5640_pins,
>> +					    ARRAY_SIZE(rt5640_pins));
>> +		if (ret)
>> +			return ret;
>> +
>> +		ret = snd_soc_card_jack_new(card, "Headset 2",
>> +					    SND_JACK_HEADSET,
>> +					    &priv->jack2, rt5640_pins2,
>> +					    ARRAY_SIZE(rt5640_pins2));
>> +		if (ret)
>> +			return ret;
>> +
>> +		acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
>> +					  byt_rt5640_hp_elitepad_1000g2_gpios);
>> +
>> +		rt5640_jack_gpio.data = priv;
>> +		rt5640_jack_gpio.gpiod_dev = priv->codec_dev;
>> +		rt5640_jack_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack1_check;
>> +		ret = snd_soc_jack_add_gpios(&priv->jack, 1, &rt5640_jack_gpio);
>> +		if (ret) {
>> +			acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
>> +			return ret;
>> +		}
>> +
>> +		rt5640_set_ovcd_params(component);
>> +		rt5640_jack2_gpio.data = component;
>> +		rt5640_jack2_gpio.gpiod_dev = priv->codec_dev;
>> +		rt5640_jack2_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack2_check;
>> +		ret = snd_soc_jack_add_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
>> +		if (ret) {
>> +			snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
>> +			acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
>> +			return ret;
>> +		}
>> +	}
>> +
>>  	return 0;
>>  }
>>  
>> +static void byt_rt5640_exit(struct snd_soc_pcm_runtime *runtime)
>> +{
>> +	struct snd_soc_card *card = runtime->card;
>> +	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
>> +
>> +	if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
>> +		snd_soc_jack_free_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
>> +		snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
>> +		acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
>> +	}
>> +}
> 
> so far so good, but you also add/remove gpios in the machine driver probe

Ack.

>> @@ -1490,6 +1620,20 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>  		return -EPROBE_DEFER;
>>  	priv->codec_dev = get_device(codec_dev);
>>  
>> +	if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
>> +		acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
>> +					  byt_rt5640_hp_elitepad_1000g2_gpios);

So this second add here (which runs first, so it really is the first add)

>> +		priv->hsmic_detect = devm_fwnode_gpiod_get(&pdev->dev, codec_dev->fwnode,
>> +							   "headset-mic-detect", GPIOD_IN,
>> +							   "headset-mic-detect");

Is to make sure this call can succeed.

>> +		acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));

And this is to not have to add yet an other error-exit path which does this
to the probe() function. By simply always removing the lookup here after the
gpiod_get() we keep the error-exit paths as they were, rather then making
them more complicated.

But I guess things won't be so bad wrt err-exit-path complexity as for
them to really be a problem, so if you prefer I can also:

1. Remove the second acpi_dev_add_driver_gpios + acpi_dev_remove_driver_gpios
pair from the dai_link .init/.exit.
2. Remove the acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev) call here
moving it to snd_byt_rt5640_mc_remove()
3. Introduce a acpi_dev_remove_driver_gpios() remove in the error-exit paths
of snd_byt_rt5640_mc_probe where necessary.

>> +		if (IS_ERR(priv->hsmic_detect)) {
>> +			ret_val = PTR_ERR(priv->hsmic_detect);
>> +			dev_err_probe(&pdev->dev, ret_val, "getting hsmic-detect GPIO\n");
>> +			goto err_device;
>> +		}
>> +	}
> Does this part need to be part of the machine driver probe, or could it
> be moved in the dailink .init function?

The idea here is that the gpiod_get may fail with -EPROBE_DEFER and then I want
to fail as early as possible, so right in the probe function.

This is also why the error is logged with dev_err_probe() which does not
log anything for EPROBE_DEFER as retval.

> Is this because you wanted to use devm_ function?

No, I did consider adding the gpiod_get() for priv->hsmic_detect to the
dai_link .init function and then I would just use a normal get, combined
with an explicit _put in the dailink exit. I put this gpiod_get in
the platform_driver probe to handle EPROBE_DEFER early on, rather then
having it happen deep inside the devm_snd_soc_register_card() call-graph
(when it calls the dailink .init).

I would prefer to keep the gpiod_get inside snd_byt_rt5640_mc_probe for this
reason, but as mentioned I can removed the second acpi_dev_add_driver_gpios +
acpi_dev_remove_driver_gpios call pair from the dai_link .init/.exit.

Please let me know how you want to proceed with this.

Regards,

Hans


  reply	other threads:[~2021-08-18 15:47 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-15 15:49 [PATCH 0/5] ASoC: Intel/rt5640: Add support for HP Elite Pad 1000G2 jack-detect Hans de Goede
2021-08-15 15:49 ` [PATCH 1/5] ASoC: rt5640: Move rt5640_disable_jack_detect() up in the rt5640.c file Hans de Goede
2021-08-18 16:12   ` Mark Brown
2021-08-15 15:49 ` [PATCH 2/5] ASoC: rt5640: Delay requesting IRQ until the machine-drv calls set_jack Hans de Goede
2021-08-15 15:49 ` [PATCH 3/5] ASoC: rt5640: Add optional hp_det_gpio parameter to rt5640_detect_headset() Hans de Goede
2021-08-15 15:49 ` [PATCH 4/5] ASoC: rt5640: Add rt5640_set_ovcd_params() helper Hans de Goede
2021-08-15 15:49 ` [PATCH 5/5] ASoC: Intel: bytcr_rt5640: Add support for HP Elite Pad 1000G2 jack-detect Hans de Goede
2021-08-16 13:31   ` Pierre-Louis Bossart
2021-08-18 15:46     ` Hans de Goede [this message]
2021-08-18 15:57       ` Pierre-Louis Bossart
2021-08-20 14:39 ` [PATCH 0/5] ASoC: Intel/rt5640: " Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2ea10f32-8810-8257-845e-ec16835fbf19@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=bard.liao@intel.com \
    --cc=broonie@kernel.org \
    --cc=cezary.rojewski@intel.com \
    --cc=liam.r.girdwood@linux.intel.com \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=yang.jie@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.