]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: i2c: ak4xxx-adda: implement AK4529 reset handling
authorCássio Gabriel <cassiogabrielcontato@gmail.com>
Tue, 7 Apr 2026 21:13:06 +0000 (18:13 -0300)
committerTakashi Iwai <tiwai@suse.de>
Wed, 8 Apr 2026 08:17:53 +0000 (10:17 +0200)
Delta 410 uses snd_akm4xxx_reset() both around DFS changes and from
its PM callbacks, but the AK4529 case in this helper is still left
unimplemented and never drives the codec reset path.

The AK4529 datasheet documents register 09h.RSTN as an internal
timing reset. Clearing RSTN powers down the ADC and DAC blocks, but
does not reinitialize the register map. That matches the existing
ak4xxx helper model, which already keeps the desired codec state in
the software register cache.

Implement AK4529 reset handling by clearing 09h.RSTN on state == 1,
then replaying the cached register image and setting RSTN back to 1
on state == 0.

This restores cached Delta 410 mixer state after resume and gives
the AK4529 DFS-change path a real codec reset sequence.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
Link: https://patch.msgid.link/20260407-ak4529-reset-handling-v1-1-b971c18b1a32@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/i2c/other/ak4xxx-adda.c

index b24c80410d45e3e2d91c6741eb17cb3297a9c628..bdeb3cef3640e17c617739b7b339835ee74cc6d9 100644 (file)
@@ -53,6 +53,31 @@ static void ak4524_reset(struct snd_akm4xxx *ak, int state)
        }
 }
 
+/* reset procedure for AK4529 */
+static void ak4529_reset(struct snd_akm4xxx *ak, int state)
+{
+       static const unsigned char regs[] = {
+               0x0a, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+               0x06, 0x07, 0x0b, 0x0c, 0x08,
+       };
+       unsigned int i;
+       unsigned char reg;
+
+       if (state) {
+               snd_akm4xxx_write(ak, 0, 0x09,
+                                 snd_akm4xxx_get(ak, 0, 0x09) & ~0x01);
+               return;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(regs); i++) {
+               reg = regs[i];
+               snd_akm4xxx_write(ak, 0, reg,
+                                 snd_akm4xxx_get(ak, 0, reg));
+       }
+       snd_akm4xxx_write(ak, 0, 0x09,
+                         snd_akm4xxx_get(ak, 0, 0x09) | 0x01);
+}
+
 /* reset procedure for AK4355 and AK4358 */
 static void ak435X_reset(struct snd_akm4xxx *ak, int state)
 {
@@ -99,7 +124,7 @@ void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
                ak4524_reset(ak, state);
                break;
        case SND_AK4529:
-               /* FIXME: needed for ak4529? */
+               ak4529_reset(ak, state);
                break;
        case SND_AK4355:
                ak435X_reset(ak, state);