Skip to content

Commit 701d636

Browse files
jwrdegoedebroonie
authored andcommitted
ASoC: rt5640: Add support for boards with an external jack-detect GPIO
Some boards have the codec IRQ hooked-up as normally, so the driver can still do things like headset vs headphones and button-press detection, but instead of using one of the JD pins of the codec, an external GPIO is used to report the jack-presence switch status of the jack. Add support for this. Signed-off-by: Hans de Goede <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent b35a9ab commit 701d636

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

sound/soc/codecs/rt5640.c

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,7 +2160,11 @@ static bool rt5640_jack_inserted(struct snd_soc_component *component)
21602160
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
21612161
int val;
21622162

2163-
val = snd_soc_component_read(component, RT5640_INT_IRQ_ST);
2163+
if (rt5640->jd_gpio)
2164+
val = gpiod_get_value(rt5640->jd_gpio) ? RT5640_JD_STATUS : 0;
2165+
else
2166+
val = snd_soc_component_read(component, RT5640_INT_IRQ_ST);
2167+
21642168
dev_dbg(component->dev, "irq status %#04x\n", val);
21652169

21662170
if (rt5640->jd_inverted)
@@ -2395,6 +2399,16 @@ static irqreturn_t rt5640_irq(int irq, void *data)
23952399
return IRQ_HANDLED;
23962400
}
23972401

2402+
static irqreturn_t rt5640_jd_gpio_irq(int irq, void *data)
2403+
{
2404+
struct rt5640_priv *rt5640 = data;
2405+
2406+
queue_delayed_work(system_long_wq, &rt5640->jack_work,
2407+
msecs_to_jiffies(JACK_SETTLE_TIME));
2408+
2409+
return IRQ_HANDLED;
2410+
}
2411+
23982412
static void rt5640_cancel_work(void *data)
23992413
{
24002414
struct rt5640_priv *rt5640 = data;
@@ -2439,7 +2453,12 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
24392453
if (!rt5640->jack)
24402454
return;
24412455

2442-
free_irq(rt5640->irq, rt5640);
2456+
if (rt5640->jd_gpio_irq_requested)
2457+
free_irq(rt5640->jd_gpio_irq, rt5640);
2458+
2459+
if (rt5640->irq_requested)
2460+
free_irq(rt5640->irq, rt5640);
2461+
24432462
rt5640_cancel_work(rt5640);
24442463

24452464
if (rt5640->jack->status & SND_JACK_MICROPHONE) {
@@ -2448,6 +2467,9 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
24482467
snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
24492468
}
24502469

2470+
rt5640->jd_gpio_irq_requested = false;
2471+
rt5640->irq_requested = false;
2472+
rt5640->jd_gpio = NULL;
24512473
rt5640->jack = NULL;
24522474
}
24532475

@@ -2500,16 +2522,31 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
25002522
if (jack_data && jack_data->codec_irq_override)
25012523
rt5640->irq = jack_data->codec_irq_override;
25022524

2525+
if (jack_data && jack_data->jd_gpio) {
2526+
rt5640->jd_gpio = jack_data->jd_gpio;
2527+
rt5640->jd_gpio_irq = gpiod_to_irq(rt5640->jd_gpio);
2528+
2529+
ret = request_irq(rt5640->jd_gpio_irq, rt5640_jd_gpio_irq,
2530+
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
2531+
"rt5640-jd-gpio", rt5640);
2532+
if (ret) {
2533+
dev_warn(component->dev, "Failed to request jd GPIO IRQ %d: %d\n",
2534+
rt5640->jd_gpio_irq, ret);
2535+
rt5640_disable_jack_detect(component);
2536+
return;
2537+
}
2538+
rt5640->jd_gpio_irq_requested = true;
2539+
}
2540+
25032541
ret = request_irq(rt5640->irq, rt5640_irq,
25042542
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
25052543
"rt5640", rt5640);
25062544
if (ret) {
25072545
dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);
2508-
rt5640->irq = -ENXIO;
2509-
/* Undo above settings */
25102546
rt5640_disable_jack_detect(component);
25112547
return;
25122548
}
2549+
rt5640->irq_requested = true;
25132550

25142551
/* sync initial jack state */
25152552
queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);

sound/soc/codecs/rt5640.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,7 @@ struct rt5640_priv {
21242124

21252125
int ldo1_en; /* GPIO for LDO1_EN */
21262126
int irq;
2127+
int jd_gpio_irq;
21272128
int sysclk;
21282129
int sysclk_src;
21292130
int lrck[RT5640_AIFS];
@@ -2136,6 +2137,8 @@ struct rt5640_priv {
21362137

21372138
bool hp_mute;
21382139
bool asrc_en;
2140+
bool irq_requested;
2141+
bool jd_gpio_irq_requested;
21392142

21402143
/* Jack and button detect data */
21412144
bool ovcd_irq_enabled;
@@ -2147,6 +2150,7 @@ struct rt5640_priv {
21472150
struct delayed_work bp_work;
21482151
struct delayed_work jack_work;
21492152
struct snd_soc_jack *jack;
2153+
struct gpio_desc *jd_gpio;
21502154
unsigned int jd_src;
21512155
bool jd_inverted;
21522156
unsigned int ovcd_th;
@@ -2155,6 +2159,7 @@ struct rt5640_priv {
21552159

21562160
struct rt5640_set_jack_data {
21572161
int codec_irq_override;
2162+
struct gpio_desc *jd_gpio;
21582163
};
21592164

21602165
int rt5640_dmic_enable(struct snd_soc_component *component,

0 commit comments

Comments
 (0)