Re: [PATCH 18/48] ARM: pxa: hx4700: use gpio descriptors for audio
From: Arnd Bergmann <arnd@kernel.org>
Date: 2022-05-05 20:08:26
Also in:
dri-devel, linux-arm-kernel, linux-clk, linux-ide, linux-input, linux-leds, linux-mips, linux-mmc, linux-pm, linux-rtc, linux-usb, lkml
Subsystem:
arm port, pxa2xx/pxa3xx support, sound, sound - soc layer / dynamic audio power management (asoc), the rest · Maintainers:
Russell King, Daniel Mack, Haojian Zhuang, Robert Jarzmik, Jaroslav Kysela, Takashi Iwai, Liam Girdwood, Mark Brown, Linus Torvalds
On Thu, May 5, 2022 at 5:04 PM Mark Brown [off-list ref] wrote:
On Thu, May 05, 2022 at 04:59:35PM +0200, Arnd Bergmann wrote:quoted
On Thu, May 5, 2022 at 4:39 PM Mark Brown [off-list ref] wrote:quoted
On Thu, May 05, 2022 at 04:33:06PM +0200, Linus Walleij wrote:quoted
On Thu, May 5, 2022 at 8:04 AM Arnd Bergmann [off-list ref] wrote:quoted
quoted
quoted
quoted
static struct snd_soc_jack_pin hs_jack_pin[] = { { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE, }, { .pin = "Speaker", /* disable speaker when hp jack is inserted */ .mask = SND_JACK_HEADPHONE, .invert = 1, },quoted
quoted
quoted
Hm some ASoC thingie. No idea what that is, but I suppose another place where a subsystem for legacy reasons try to do the gpiolib inversion on it's own accord. That one isn't flagged as active low in the descriptor so it's fine I guess.quoted
quoted
It's saying that when the headphone is inserted the headphone output should be enabled and the speaker output should be disabled, and vice versa.quoted
Ok, that sounds like I should remove the flag here if I declare the GPIO line as GPIO_ACTIVE_LOW instead of GPIO_ACTIVE_HIGH, right?If you change the sense of the GPIO you'll need to flip the invert to the headphone instead of the speaker - whichever way round the GPIO sense is each of the pins should be taking the opposite sense from the GPIO state to the other.
Ok, I hope I got it this time:
- The hs_jack_gpio/"earphone-det" is declared as GPIO_ACTIVE_LOW,
with the ".invert" dropped in the snd_soc_jack_gpio definition to match
- "spk-sd" is declared as GPIO_ACTIVE_LOW, so both
this and "hp-driver" are enabled by setting the gpio to active, rather than
the two being opposites
- snd_soc_jack_pin flips the 'invert' flag from speaker to headphone, since
the "earphone-det" is now reversed
- hx4700_spk_power() flips polarity when setting the output to match the
GPIO_ACTIVE_LOW setting, but hx4700_hp_power() does not change.
Arnd
commit 20a9b05eff0488b78aa02c07f58654daa294069a
Author: Arnd Bergmann [off-list ref]
Date: Wed Sep 11 14:27:13 2019 +0200
ARM: pxa: hx4700: use gpio descriptors for audio
The audio driver should not use a hardwired gpio number
from the header. Change it to use a lookup table.
Cc: Philipp Zabel [off-list ref]
Cc: Paul Parsons [off-list ref]
Acked-by: Mark Brown [off-list ref]
Acked-by: Robert Jarzmik [off-list ref]
Cc: alsa-devel@alsa-project.org
Signed-off-by: Arnd Bergmann [off-list ref]
diff --git a/arch/arm/mach-pxa/hx4700-pcmcia.cb/arch/arm/mach-pxa/hx4700-pcmcia.c index e8acbfc9ef6c..e2331dfe427d 100644
--- a/arch/arm/mach-pxa/hx4700-pcmcia.c
+++ b/arch/arm/mach-pxa/hx4700-pcmcia.c@@ -10,7 +10,7 @@ #include <linux/irq.h> #include <asm/mach-types.h> -#include <mach/hx4700.h> +#include "hx4700.h" #include <pcmcia/soc_common.h>
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 140a44cb2989..2ae06edf413c 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c@@ -41,7 +41,7 @@ #include "pxa27x.h" #include "addr-map.h" -#include <mach/hx4700.h> +#include "hx4700.h" #include <linux/platform_data/irda-pxaficp.h> #include <sound/ak4641.h>
@@ -834,6 +834,19 @@ static struct i2c_board_info i2c_board_info[]__initdata = {
},
};
+static struct gpiod_lookup_table hx4700_audio_gpio_table = {
+ .dev_id = "hx4700-audio",
+ .table = {
+ GPIO_LOOKUP("gpio-pxa", GPIO75_HX4700_EARPHONE_nDET,
+ "earphone-det", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("gpio-pxa", GPIO92_HX4700_HP_DRIVER,
+ "hp-driver", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("gpio-pxa", GPIO107_HX4700_SPK_nSD,
+ "spk-sd", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct platform_device audio = {
.name = "hx4700-audio",
.id = -1,@@ -895,6 +908,7 @@ static void __init hx4700_init(void) gpiod_add_lookup_table(&bq24022_gpiod_table); gpiod_add_lookup_table(&gpio_vbus_gpiod_table); + gpiod_add_lookup_table(&hx4700_audio_gpio_table); platform_add_devices(devices, ARRAY_SIZE(devices)); pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
diff --git a/arch/arm/mach-pxa/include/mach/hx4700.hb/arch/arm/mach-pxa/hx4700.h similarity index 99% rename from arch/arm/mach-pxa/include/mach/hx4700.h rename to arch/arm/mach-pxa/hx4700.h index 0c30e6d9c660..ce2db33989e1 100644
--- a/arch/arm/mach-pxa/include/mach/hx4700.h
+++ b/arch/arm/mach-pxa/hx4700.h@@ -10,7 +10,7 @@ #include <linux/gpio.h> #include <linux/mfd/asic3.h> -#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ +#include <mach/irqs.h> /* PXA_NR_BUILTIN_GPIO */ #define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO #define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 7334fac758de..e6473c50e512 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c@@ -10,7 +10,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <sound/core.h> #include <sound/jack.h>
@@ -18,10 +18,10 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <mach/hx4700.h> #include <asm/mach-types.h> #include "pxa2xx-i2s.h" +static struct gpio_desc *gpiod_hp_driver, *gpiod_spk_sd; static struct snd_soc_jack hs_jack; /* Headphones jack detection DAPM pin */
@@ -29,20 +29,18 @@ static struct snd_soc_jack_pin hs_jack_pin[] = { { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE, + .invert = 1, }, { .pin = "Speaker", /* disable speaker when hp jack is inserted */ .mask = SND_JACK_HEADPHONE, - .invert = 1, }, }; /* Headphones jack detection GPIO */ static struct snd_soc_jack_gpio hs_jack_gpio = { - .gpio = GPIO75_HX4700_EARPHONE_nDET, - .invert = true, - .name = "hp-gpio", + .name = "earphone-det", .report = SND_JACK_HEADPHONE, .debounce_time = 200, };
@@ -81,14 +79,14 @@ static const struct snd_soc_ops hx4700_ops = { static int hx4700_spk_power(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value(gpiod_spk_sd, !SND_SOC_DAPM_EVENT_ON(event)); return 0; } static int hx4700_hp_power(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value(gpiod_hp_driver, !!SND_SOC_DAPM_EVENT_ON(event)); return 0; }
@@ -162,11 +160,6 @@ static struct snd_soc_card snd_soc_card_hx4700 = { .fully_routed = true, }; -static struct gpio hx4700_audio_gpios[] = { - { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" }, - { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" }, -}; - static int hx4700_audio_probe(struct platform_device *pdev) { int ret;
@@ -174,26 +167,26 @@ static int hx4700_audio_probe(structplatform_device *pdev)
if (!machine_is_h4700())
return -ENODEV;
- ret = gpio_request_array(hx4700_audio_gpios,
- ARRAY_SIZE(hx4700_audio_gpios));
+ gpiod_hp_driver = devm_gpiod_get(&pdev->dev, "hp-driver", GPIOD_ASIS);
+ ret = PTR_ERR_OR_ZERO(gpiod_hp_driver);
+ if (ret)
+ return ret;
+ gpiod_spk_sd = devm_gpiod_get(&pdev->dev, "spk-sd", GPIOD_ASIS);
+ ret = PTR_ERR_OR_ZERO(gpiod_spk_sd);
if (ret)
return ret;
+ hs_jack_gpio.gpiod_dev = &pdev->dev;
snd_soc_card_hx4700.dev = &pdev->dev;
ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700);
- if (ret)
- gpio_free_array(hx4700_audio_gpios,
- ARRAY_SIZE(hx4700_audio_gpios));
return ret;
}
static int hx4700_audio_remove(struct platform_device *pdev)
{
- gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
- gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
-
- gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
+ gpiod_set_value(gpiod_hp_driver, 0);
+ gpiod_set_value(gpiod_spk_sd, 0);
return 0;
}