From: Linus Walleij <linusw@kernel.org>
To: Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
Jaya Kumar <jayakumar.alsa@gmail.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
Bartosz Golaszewski <brgl@kernel.org>
Cc: linux-sound@vger.kernel.org, linux-gpio@vger.kernel.org,
Linus Walleij <linusw@kernel.org>
Subject: [PATCH] RFT: x86_32: Move OLPC XO-1 audio GPIO to software nodes
Date: Wed, 25 Mar 2026 22:46:36 +0100 [thread overview]
Message-ID: <20260325-asoc-olpc-v1-1-ebe6de05c7e2@kernel.org> (raw)
This needs real hardware to continue.
At the TODO spot, we need the name of the actual
PCI device providing the cs5535 device.
If we can get this working, we can move over the rest
of the hogs etc to software nodes and get rid of all
the custom cs5535_gpio_set(), cs5535_gpio_clear()
etc.
If it turns out that no-one is willing to actually
test OLPC XO-1 patches, I will follow up with a patch
to just delete the XO-1 support altogether.
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
arch/x86/platform/olpc/olpc.c | 33 ++++++++++++++++++++++++++++++++
sound/pci/cs5535audio/cs5535audio.c | 3 +--
sound/pci/cs5535audio/cs5535audio.h | 26 +++++++++++++------------
sound/pci/cs5535audio/cs5535audio_olpc.c | 32 +++++++++++++++----------------
sound/pci/cs5535audio/cs5535audio_pcm.c | 4 ++--
5 files changed, 66 insertions(+), 32 deletions(-)
diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c
index 1d4a00e767ec..95df7f691825 100644
--- a/arch/x86/platform/olpc/olpc.c
+++ b/arch/x86/platform/olpc/olpc.c
@@ -10,6 +10,8 @@
#include <linux/init.h>
#include <linux/export.h>
#include <linux/delay.h>
+#include <linux/gpio/machine.h>
+#include <linux/gpio/property.h>
#include <linux/io.h>
#include <linux/string.h>
#include <linux/platform_device.h>
@@ -17,6 +19,7 @@
#include <linux/syscore_ops.h>
#include <linux/mutex.h>
#include <linux/olpc-ec.h>
+#include <linux/property.h>
#include <asm/geode.h>
#include <asm/setup.h>
@@ -283,6 +286,32 @@ static struct olpc_ec_driver ec_xo1_5_driver = {
#endif
};
+/*
+ * Create software nodes for GPIO look-ups so we can keep the
+ * CS5535 GPIO driver abstract without peeking under the hood.
+ */
+static const struct software_node cs5535_gpiochip_node = {
+ .name = "cs5535-gpio",
+};
+
+static const struct property_entry olpc_snd_props[] = {
+ PROPERTY_ENTRY_GPIO("mic-ac-gpios", &cs5535_gpiochip_node,
+ OLPC_GPIO_MIC_AC, GPIO_ACTIVE_HIGH),
+ {}
+};
+
+static const struct software_node olpc_snd_node = {
+ /* TODO: dev_name(&pci->dev) for the OLPC CS5535 PCI device */
+ .name = "",
+ .properties = olpc_snd_props,
+};
+
+static const struct software_node *olpc_sw_nodes[] = {
+ &cs5535_gpiochip_node,
+ &olpc_snd_node,
+ NULL
+};
+
static int __init olpc_init(void)
{
int r = 0;
@@ -315,6 +344,10 @@ static int __init olpc_init(void)
return r;
}
+ r = software_node_register_node_group(olpc_sw_nodes);
+ if (r)
+ return r;
+
return 0;
}
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 0ebf6c02b1ef..676c540d03eb 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -164,7 +164,7 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
- err = olpc_quirks(card, cs5535au->ac97);
+ err = olpc_quirks(card, cs5535au);
if (err < 0) {
dev_err(card->dev, "olpc quirks failed\n");
return err;
@@ -241,7 +241,6 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
static void snd_cs5535audio_free(struct snd_card *card)
{
- olpc_quirks_cleanup();
}
static int snd_cs5535audio_create(struct snd_card *card,
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index d84620a0c26c..f917fc21533a 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -2,6 +2,8 @@
#ifndef __SOUND_CS5535AUDIO_H
#define __SOUND_CS5535AUDIO_H
+#include <linux/gpio/consumer.h>
+
#define cs_writel(cs5535au, reg, val) outl(val, (cs5535au)->port + reg)
#define cs_writeb(cs5535au, reg, val) outb(val, (cs5535au)->port + reg)
#define cs_readl(cs5535au, reg) inl((cs5535au)->port + reg)
@@ -93,6 +95,7 @@ struct cs5535audio {
struct snd_pcm_substream *playback_substream;
struct snd_pcm_substream *capture_substream;
struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
+ struct gpio_desc *mic_ac;
};
extern const struct dev_pm_ops snd_cs5535audio_pm;
@@ -100,25 +103,24 @@ extern const struct dev_pm_ops snd_cs5535audio_pm;
#ifdef CONFIG_OLPC
void olpc_prequirks(struct snd_card *card,
struct snd_ac97_template *ac97);
-int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
-void olpc_quirks_cleanup(void);
-void olpc_analog_input(struct snd_ac97 *ac97, int on);
+int olpc_quirks(struct snd_card *card, struct cs5535audio *cs5535au);
+void olpc_analog_input(struct cs5535audio *cs5535au, int on);
void olpc_mic_bias(struct snd_ac97 *ac97, int on);
-static inline void olpc_capture_open(struct snd_ac97 *ac97)
+static inline void olpc_capture_open(struct cs5535audio *cs5535au)
{
/* default to Analog Input off */
- olpc_analog_input(ac97, 0);
+ olpc_analog_input(cs5535au, 0);
/* enable MIC Bias for recording */
- olpc_mic_bias(ac97, 1);
+ olpc_mic_bias(cs5535au->ac97, 1);
}
-static inline void olpc_capture_close(struct snd_ac97 *ac97)
+static inline void olpc_capture_close(struct cs5535audio *cs5535au)
{
/* disable Analog Input */
- olpc_analog_input(ac97, 0);
+ olpc_analog_input(cs5535au, 0);
/* disable the MIC Bias (so the recording LED turns off) */
- olpc_mic_bias(ac97, 0);
+ olpc_mic_bias(cs5535au->ac97, 0);
}
#else
static inline void olpc_prequirks(struct snd_card *card,
@@ -128,10 +130,10 @@ static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
return 0;
}
static inline void olpc_quirks_cleanup(void) { }
-static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
+static inline void olpc_analog_input(struct cs5535audio *cs5535au, int on) { }
static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
-static inline void olpc_capture_open(struct snd_ac97 *ac97) { }
-static inline void olpc_capture_close(struct snd_ac97 *ac97) { }
+static inline void olpc_capture_open(struct cs5535audio *cs5535au) { }
+static inline void olpc_capture_close(struct cs5535audio *cs5535au) { }
#endif
int snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
index 122170a410d9..19eed3c9c48b 100644
--- a/sound/pci/cs5535audio/cs5535audio_olpc.c
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -9,7 +9,7 @@
#include <sound/info.h>
#include <sound/control.h>
#include <sound/ac97_codec.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <asm/olpc.h>
#include "cs5535audio.h"
@@ -21,8 +21,9 @@
* It has an Analog Input mode that is switched into (after disabling the
* High Pass Filter) via GPIO. It is supported on B2 and later models.
*/
-void olpc_analog_input(struct snd_ac97 *ac97, int on)
+void olpc_analog_input(struct cs5535audio *cs5535au, int on)
{
+ struct snd_ac97 *ac97 = cs5535au->ac97;
int err;
if (!machine_is_olpc())
@@ -38,7 +39,7 @@ void olpc_analog_input(struct snd_ac97 *ac97, int on)
}
/* set Analog Input through GPIO */
- gpio_set_value(OLPC_GPIO_MIC_AC, on);
+ gpiod_set_value(cs5535au->mic_ac, on);
}
/*
@@ -70,7 +71,9 @@ static int olpc_dc_info(struct snd_kcontrol *kctl,
static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
{
- v->value.integer.value[0] = gpio_get_value(OLPC_GPIO_MIC_AC);
+ struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
+
+ v->value.integer.value[0] = gpiod_get_value(cs5535au->mic_ac);
return 0;
}
@@ -78,7 +81,7 @@ static int olpc_dc_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
{
struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
- olpc_analog_input(cs5535au->ac97, v->value.integer.value[0]);
+ olpc_analog_input(cs5535au, v->value.integer.value[0]);
return 1;
}
@@ -141,19 +144,22 @@ void olpc_prequirks(struct snd_card *card,
ac97->scaps |= AC97_SCAP_INV_EAPD;
}
-int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
+int olpc_quirks(struct snd_card *card, struct cs5535audio *cs5535au)
{
+ struct snd_ac97 *ac97 = cs5535au->ac97;
struct snd_ctl_elem_id elem;
int i, err;
if (!machine_is_olpc())
return 0;
- if (gpio_request(OLPC_GPIO_MIC_AC, DRV_NAME)) {
- dev_err(card->dev, "unable to allocate MIC GPIO\n");
- return -EIO;
+ cs5535au->mic_ac = devm_gpiod_get_optional(card->dev, "mic-ac",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(cs5535au->mic_ac)) {
+ dev_err(card->dev, "unable to allocate MIC AC GPIO\n");
+ return PTR_ERR(cs5535au->mic_ac);
}
- gpio_direction_output(OLPC_GPIO_MIC_AC, 0);
+ gpiod_set_consumer_name(cs5535au->mic_ac, DRV_NAME);
/* drop the original AD1888 HPF control */
memset(&elem, 0, sizeof(elem));
@@ -179,9 +185,3 @@ int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
olpc_mic_bias(ac97, 0);
return 0;
}
-
-void olpc_quirks_cleanup(void)
-{
- if (machine_is_olpc())
- gpio_free(OLPC_GPIO_MIC_AC);
-}
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 48b99a07e3bc..49b1efb93dd9 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -341,14 +341,14 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_PERIODS);
if (err < 0)
return err;
- olpc_capture_open(cs5535au->ac97);
+ olpc_capture_open(cs5535au);
return 0;
}
static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
{
struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- olpc_capture_close(cs5535au->ac97);
+ olpc_capture_close(cs5535au);
return 0;
}
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260319-asoc-olpc-ff15cf19420b
Best regards,
--
Linus Walleij <linusw@kernel.org>
next reply other threads:[~2026-03-25 21:46 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-25 21:46 Linus Walleij [this message]
2026-03-26 9:08 ` [PATCH] RFT: x86_32: Move OLPC XO-1 audio GPIO to software nodes Bartosz Golaszewski
2026-03-26 10:20 ` Linus Walleij
2026-03-26 9:25 ` kernel test robot
2026-03-26 10:08 ` kernel test robot
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=20260325-asoc-olpc-v1-1-ebe6de05c7e2@kernel.org \
--to=linusw@kernel.org \
--cc=bp@alien8.de \
--cc=brgl@kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jayakumar.alsa@gmail.com \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=perex@perex.cz \
--cc=tglx@kernel.org \
--cc=tiwai@suse.com \
--cc=x86@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox