ASoC: rt5640: Delay requesting IRQ until the machine-drv calls set_jack
Delay requesting the IRQ until the machine-drv calls set_jack. The main reason for this is that the codec's IRQ is unused on some boards, in which case we really should not call request_irq at all. On some boards there is an IRQ listed at index 0 for the codec, but this is not connected to the codec, but rather is directly connected to the jack's jack-detect pin. These special setups will be handled by the machine-driver, but the machine driver can only request the IRQ if it is not first requested by the codec driver. Moving the request_irq to the set_jack callback (which will not get called in this case) avoids the codec-driver clobbering the IRQ. Moving the request_irq also removes the need to disable the IRQ immediately after requesting it, avoiding a small race (this could also have been fixed by using the new IRQF_NO_AUTOEN flag when requesting the IRQ). Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20210819190543.784415-3-hdegoede@redhat.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
5caab9f48b
commit
15d54840ec
|
@ -2373,7 +2373,7 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
|
|||
if (!rt5640->jack)
|
||||
return;
|
||||
|
||||
disable_irq(rt5640->irq);
|
||||
free_irq(rt5640->irq, rt5640);
|
||||
rt5640_cancel_work(rt5640);
|
||||
|
||||
if (rt5640->jack->status & SND_JACK_MICROPHONE) {
|
||||
|
@ -2389,6 +2389,7 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
|
|||
struct snd_soc_jack *jack)
|
||||
{
|
||||
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
|
||||
int ret;
|
||||
|
||||
/* Select JD-source */
|
||||
snd_soc_component_update_bits(component, RT5640_JD_CTRL,
|
||||
|
@ -2446,7 +2447,17 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
|
|||
rt5640_enable_micbias1_ovcd_irq(component);
|
||||
}
|
||||
|
||||
enable_irq(rt5640->irq);
|
||||
ret = request_irq(rt5640->irq, rt5640_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
"rt5640", rt5640);
|
||||
if (ret) {
|
||||
dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);
|
||||
rt5640->irq = -ENXIO;
|
||||
/* Undo above settings */
|
||||
rt5640_disable_jack_detect(component);
|
||||
return;
|
||||
}
|
||||
|
||||
/* sync initial jack state */
|
||||
queue_work(system_long_wq, &rt5640->jack_work);
|
||||
}
|
||||
|
@ -2836,21 +2847,6 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rt5640->irq) {
|
||||
/* enabled by rt5640_set_jack() */
|
||||
ret = devm_request_irq(&i2c->dev, rt5640->irq, rt5640_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN |
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
"rt5640", rt5640);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
|
||||
rt5640->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
rt5640->irq = -ENXIO;
|
||||
}
|
||||
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_component_dev_rt5640,
|
||||
rt5640_dai, ARRAY_SIZE(rt5640_dai));
|
||||
|
|
Loading…
Reference in New Issue