diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-04-16 18:24:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:24:31 -0400 |
commit | b75550e1bc6b3b2c80b628e68628fca015634071 (patch) | |
tree | c5de5583d713c4cd682cb253fd74bd031d810f9c /sound | |
parent | 16b817579fb61050f1abcc0e81089974328a9c27 (diff) |
[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>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/ppc/pmac.c | 26 | ||||
-rw-r--r-- | sound/ppc/tumbler.c | 46 |
2 files changed, 53 insertions, 19 deletions
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 6c4ed90f490e..f9a9601769aa 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -881,6 +881,7 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
881 | { | 881 | { |
882 | struct device_node *sound; | 882 | struct device_node *sound; |
883 | unsigned int *prop, l; | 883 | unsigned int *prop, l; |
884 | u32 layout_id = 0; | ||
884 | 885 | ||
885 | if (_machine != _MACH_Pmac) | 886 | if (_machine != _MACH_Pmac) |
886 | return -ENODEV; | 887 | return -ENODEV; |
@@ -929,6 +930,9 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
929 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); | 930 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); |
930 | if (prop && *prop < 16) | 931 | if (prop && *prop < 16) |
931 | chip->subframe = *prop; | 932 | chip->subframe = *prop; |
933 | prop = (unsigned int *) get_property(sound, "layout-id", NULL); | ||
934 | if (prop) | ||
935 | layout_id = *prop; | ||
932 | /* This should be verified on older screamers */ | 936 | /* This should be verified on older screamers */ |
933 | if (device_is_compatible(sound, "screamer")) { | 937 | if (device_is_compatible(sound, "screamer")) { |
934 | chip->model = PMAC_SCREAMER; | 938 | chip->model = PMAC_SCREAMER; |
@@ -961,12 +965,22 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
961 | chip->freq_table = tumbler_freqs; | 965 | chip->freq_table = tumbler_freqs; |
962 | chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ | 966 | chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ |
963 | } | 967 | } |
964 | if (device_is_compatible(sound, "AOAKeylargo")) { | 968 | if (device_is_compatible(sound, "AOAKeylargo") || |
965 | /* Seems to support the stock AWACS frequencies, but has | 969 | device_is_compatible(sound, "AOAbase")) { |
966 | a snapper mixer */ | 970 | /* For now, only support very basic TAS3004 based machines with |
967 | chip->model = PMAC_SNAPPER; | 971 | * single frequency until proper i2s control is implemented |
968 | // chip->can_byte_swap = 0; /* FIXME: check this */ | 972 | */ |
969 | chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ | 973 | switch(layout_id) { |
974 | case 0x48: | ||
975 | case 0x46: | ||
976 | case 0x33: | ||
977 | case 0x29: | ||
978 | chip->num_freqs = ARRAY_SIZE(tumbler_freqs); | ||
979 | chip->model = PMAC_SNAPPER; | ||
980 | chip->can_byte_swap = 0; /* FIXME: check this */ | ||
981 | chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ | ||
982 | break; | ||
983 | } | ||
970 | } | 984 | } |
971 | prop = (unsigned int *)get_property(sound, "device-id", NULL); | 985 | prop = (unsigned int *)get_property(sound, "device-id", NULL); |
972 | if (prop) | 986 | if (prop) |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 7d10385f0a76..72a2219f56b5 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | #ifdef CONFIG_PPC_HAS_FEATURE_CALLS | 38 | #ifdef CONFIG_PPC_HAS_FEATURE_CALLS |
39 | #include <asm/pmac_feature.h> | 39 | #include <asm/pmac_feature.h> |
40 | #else | ||
41 | #error old crap | ||
40 | #endif | 42 | #endif |
41 | #include "pmac.h" | 43 | #include "pmac.h" |
42 | #include "tumbler_volume.h" | 44 | #include "tumbler_volume.h" |
@@ -950,10 +952,10 @@ static struct device_node *find_compatible_audio_device(const char *name) | |||
950 | } | 952 | } |
951 | 953 | ||
952 | /* find an audio device and get its address */ | 954 | /* find an audio device and get its address */ |
953 | static unsigned long tumbler_find_device(const char *device, pmac_gpio_t *gp, int is_compatible) | 955 | static long tumbler_find_device(const char *device, pmac_gpio_t *gp, int is_compatible) |
954 | { | 956 | { |
955 | struct device_node *node; | 957 | struct device_node *node; |
956 | u32 *base; | 958 | u32 *base, addr; |
957 | 959 | ||
958 | if (is_compatible) | 960 | if (is_compatible) |
959 | node = find_compatible_audio_device(device); | 961 | node = find_compatible_audio_device(device); |
@@ -966,21 +968,31 @@ static unsigned long tumbler_find_device(const char *device, pmac_gpio_t *gp, in | |||
966 | 968 | ||
967 | base = (u32 *)get_property(node, "AAPL,address", NULL); | 969 | base = (u32 *)get_property(node, "AAPL,address", NULL); |
968 | if (! base) { | 970 | if (! base) { |
969 | snd_printd("cannot find address for device %s\n", device); | 971 | base = (u32 *)get_property(node, "reg", NULL); |
970 | return -ENODEV; | 972 | if (!base) { |
971 | } | 973 | snd_printd("cannot find address for device %s\n", device); |
974 | return -ENODEV; | ||
975 | } | ||
976 | /* this only work if PPC_HAS_FEATURE_CALLS is set as we | ||
977 | * are only getting the low part of the address | ||
978 | */ | ||
979 | addr = *base; | ||
980 | if (addr < 0x50) | ||
981 | addr += 0x50; | ||
982 | } else | ||
983 | addr = *base; | ||
972 | 984 | ||
973 | #ifdef CONFIG_PPC_HAS_FEATURE_CALLS | 985 | #ifdef CONFIG_PPC_HAS_FEATURE_CALLS |
974 | gp->addr = (*base) & 0x0000ffff; | 986 | gp->addr = addr & 0x0000ffff; |
975 | #else | 987 | #else |
976 | gp->addr = ioremap((unsigned long)(*base), 1); | 988 | gp->addr = ioremap((unsigned long)addr, 1); |
977 | #endif | 989 | #endif |
990 | /* Try to find the active state, default to 0 ! */ | ||
978 | base = (u32 *)get_property(node, "audio-gpio-active-state", NULL); | 991 | base = (u32 *)get_property(node, "audio-gpio-active-state", NULL); |
979 | if (base) | 992 | if (base) |
980 | gp->active_state = *base; | 993 | gp->active_state = *base; |
981 | else | 994 | else |
982 | gp->active_state = 1; | 995 | gp->active_state = 0; |
983 | |||
984 | 996 | ||
985 | return (node->n_intrs > 0) ? node->intrs[0].line : 0; | 997 | return (node->n_intrs > 0) ? node->intrs[0].line : 0; |
986 | } | 998 | } |
@@ -1039,11 +1051,16 @@ static int __init tumbler_init(pmac_t *chip) | |||
1039 | pmac_tumbler_t *mix = chip->mixer_data; | 1051 | pmac_tumbler_t *mix = chip->mixer_data; |
1040 | snd_assert(mix, return -EINVAL); | 1052 | snd_assert(mix, return -EINVAL); |
1041 | 1053 | ||
1042 | tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0); | 1054 | if (tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0) < 0) |
1043 | tumbler_find_device("amp-mute", &mix->amp_mute, 0); | 1055 | tumbler_find_device("hw-reset", &mix->audio_reset, 1); |
1044 | tumbler_find_device("headphone-mute", &mix->hp_mute, 0); | 1056 | if (tumbler_find_device("amp-mute", &mix->amp_mute, 0) < 0) |
1057 | tumbler_find_device("amp-mute", &mix->amp_mute, 1); | ||
1058 | if (tumbler_find_device("headphone-mute", &mix->hp_mute, 0) < 0) | ||
1059 | tumbler_find_device("headphone-mute", &mix->hp_mute, 1); | ||
1045 | irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 0); | 1060 | irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 0); |
1046 | if (irq < 0) | 1061 | if (irq < 0) |
1062 | irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 1); | ||
1063 | if (irq < 0) | ||
1047 | irq = tumbler_find_device("keywest-gpio15", &mix->hp_detect, 1); | 1064 | irq = tumbler_find_device("keywest-gpio15", &mix->hp_detect, 1); |
1048 | 1065 | ||
1049 | tumbler_reset_audio(chip); | 1066 | tumbler_reset_audio(chip); |
@@ -1109,9 +1126,13 @@ int __init snd_pmac_tumbler_init(pmac_t *chip) | |||
1109 | /* set up TAS */ | 1126 | /* set up TAS */ |
1110 | tas_node = find_devices("deq"); | 1127 | tas_node = find_devices("deq"); |
1111 | if (tas_node == NULL) | 1128 | if (tas_node == NULL) |
1129 | tas_node = find_devices("codec"); | ||
1130 | if (tas_node == NULL) | ||
1112 | return -ENODEV; | 1131 | return -ENODEV; |
1113 | 1132 | ||
1114 | paddr = (u32 *)get_property(tas_node, "i2c-address", NULL); | 1133 | paddr = (u32 *)get_property(tas_node, "i2c-address", NULL); |
1134 | if (paddr == NULL) | ||
1135 | paddr = (u32 *)get_property(tas_node, "reg", NULL); | ||
1115 | if (paddr) | 1136 | if (paddr) |
1116 | mix->i2c.addr = (*paddr) >> 1; | 1137 | mix->i2c.addr = (*paddr) >> 1; |
1117 | else | 1138 | else |
@@ -1156,7 +1177,6 @@ int __init snd_pmac_tumbler_init(pmac_t *chip) | |||
1156 | if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0) | 1177 | if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0) |
1157 | return err; | 1178 | return err; |
1158 | 1179 | ||
1159 | |||
1160 | #ifdef CONFIG_PMAC_PBOOK | 1180 | #ifdef CONFIG_PMAC_PBOOK |
1161 | chip->resume = tumbler_resume; | 1181 | chip->resume = tumbler_resume; |
1162 | #endif | 1182 | #endif |