[PATCH] pmac: sound support for latest laptops

This patch hacks the current Alsa snd-powermac driver to add support for
recent machine models with the tas3004 chip, that is basically new laptop
models.  The Mac Mini is _NOT_ yet supported by this patch (soon soon ...).
 The G5s (iMac or Desktop) will need the rewritten sound driver on which
I'm working on (I _might_ get a hack for analog only on some G5s on the
current driver, but no promise).

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 7d10385..72a2219 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -37,6 +37,8 @@
 #include <asm/irq.h>
 #ifdef CONFIG_PPC_HAS_FEATURE_CALLS
 #include <asm/pmac_feature.h>
+#else
+#error old crap
 #endif
 #include "pmac.h"
 #include "tumbler_volume.h"
@@ -950,10 +952,10 @@
 }
 
 /* find an audio device and get its address */
-static unsigned long tumbler_find_device(const char *device, pmac_gpio_t *gp, int is_compatible)
+static long tumbler_find_device(const char *device, pmac_gpio_t *gp, int is_compatible)
 {
 	struct device_node *node;
-	u32 *base;
+	u32 *base, addr;
 
 	if (is_compatible)
 		node = find_compatible_audio_device(device);
@@ -966,21 +968,31 @@
 
 	base = (u32 *)get_property(node, "AAPL,address", NULL);
 	if (! base) {
-		snd_printd("cannot find address for device %s\n", device);
-		return -ENODEV;
-	}
+		base = (u32 *)get_property(node, "reg", NULL);
+		if (!base) {
+			snd_printd("cannot find address for device %s\n", device);
+			return -ENODEV;
+		}
+		/* this only work if PPC_HAS_FEATURE_CALLS is set as we
+		 * are only getting the low part of the address
+		 */
+		addr = *base;
+		if (addr < 0x50)
+			addr += 0x50;
+	} else
+		addr = *base;
 
 #ifdef CONFIG_PPC_HAS_FEATURE_CALLS
-	gp->addr = (*base) & 0x0000ffff;
+	gp->addr = addr & 0x0000ffff;
 #else
-	gp->addr = ioremap((unsigned long)(*base), 1);
+	gp->addr = ioremap((unsigned long)addr, 1);
 #endif
+	/* Try to find the active state, default to 0 ! */
 	base = (u32 *)get_property(node, "audio-gpio-active-state", NULL);
 	if (base)
 		gp->active_state = *base;
 	else
-		gp->active_state = 1;
-
+		gp->active_state = 0;
 
 	return (node->n_intrs > 0) ? node->intrs[0].line : 0;
 }
@@ -1039,11 +1051,16 @@
 	pmac_tumbler_t *mix = chip->mixer_data;
 	snd_assert(mix, return -EINVAL);
 
-	tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0);
-	tumbler_find_device("amp-mute", &mix->amp_mute, 0);
-	tumbler_find_device("headphone-mute", &mix->hp_mute, 0);
+	if (tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0) < 0)
+		tumbler_find_device("hw-reset", &mix->audio_reset, 1);
+	if (tumbler_find_device("amp-mute", &mix->amp_mute, 0) < 0)
+		tumbler_find_device("amp-mute", &mix->amp_mute, 1);
+	if (tumbler_find_device("headphone-mute", &mix->hp_mute, 0) < 0)
+		tumbler_find_device("headphone-mute", &mix->hp_mute, 1);
 	irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 0);
 	if (irq < 0)
+		irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 1);
+	if (irq < 0)
 		irq = tumbler_find_device("keywest-gpio15", &mix->hp_detect, 1);
 
 	tumbler_reset_audio(chip);
@@ -1109,9 +1126,13 @@
 	/* set up TAS */
 	tas_node = find_devices("deq");
 	if (tas_node == NULL)
+		tas_node = find_devices("codec");
+	if (tas_node == NULL)
 		return -ENODEV;
 
 	paddr = (u32 *)get_property(tas_node, "i2c-address", NULL);
+	if (paddr == NULL)
+		paddr = (u32 *)get_property(tas_node, "reg", NULL);
 	if (paddr)
 		mix->i2c.addr = (*paddr) >> 1;
 	else
@@ -1156,7 +1177,6 @@
 	if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
 		return err;
 
-
 #ifdef CONFIG_PMAC_PBOOK
 	chip->resume = tumbler_resume;
 #endif