Commit b75550e1bc6b3b2c80b628e68628fca015634071
Committed by
Linus Torvalds
1 parent
16b817579f
Exists in
master
and in
7 other branches
[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>
Showing 2 changed files with 53 additions and 19 deletions Side-by-side Diff
sound/ppc/pmac.c
... | ... | @@ -881,6 +881,7 @@ |
881 | 881 | { |
882 | 882 | struct device_node *sound; |
883 | 883 | unsigned int *prop, l; |
884 | + u32 layout_id = 0; | |
884 | 885 | |
885 | 886 | if (_machine != _MACH_Pmac) |
886 | 887 | return -ENODEV; |
... | ... | @@ -929,6 +930,9 @@ |
929 | 930 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); |
930 | 931 | if (prop && *prop < 16) |
931 | 932 | chip->subframe = *prop; |
933 | + prop = (unsigned int *) get_property(sound, "layout-id", NULL); | |
934 | + if (prop) | |
935 | + layout_id = *prop; | |
932 | 936 | /* This should be verified on older screamers */ |
933 | 937 | if (device_is_compatible(sound, "screamer")) { |
934 | 938 | chip->model = PMAC_SCREAMER; |
... | ... | @@ -961,12 +965,22 @@ |
961 | 965 | chip->freq_table = tumbler_freqs; |
962 | 966 | chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ |
963 | 967 | } |
964 | - if (device_is_compatible(sound, "AOAKeylargo")) { | |
965 | - /* Seems to support the stock AWACS frequencies, but has | |
966 | - a snapper mixer */ | |
967 | - chip->model = PMAC_SNAPPER; | |
968 | - // chip->can_byte_swap = 0; /* FIXME: check this */ | |
969 | - chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ | |
968 | + if (device_is_compatible(sound, "AOAKeylargo") || | |
969 | + device_is_compatible(sound, "AOAbase")) { | |
970 | + /* For now, only support very basic TAS3004 based machines with | |
971 | + * single frequency until proper i2s control is implemented | |
972 | + */ | |
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 | 985 | prop = (unsigned int *)get_property(sound, "device-id", NULL); |
972 | 986 | if (prop) |
sound/ppc/tumbler.c
... | ... | @@ -37,6 +37,8 @@ |
37 | 37 | #include <asm/irq.h> |
38 | 38 | #ifdef CONFIG_PPC_HAS_FEATURE_CALLS |
39 | 39 | #include <asm/pmac_feature.h> |
40 | +#else | |
41 | +#error old crap | |
40 | 42 | #endif |
41 | 43 | #include "pmac.h" |
42 | 44 | #include "tumbler_volume.h" |
43 | 45 | |
... | ... | @@ -950,10 +952,10 @@ |
950 | 952 | } |
951 | 953 | |
952 | 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 | 957 | struct device_node *node; |
956 | - u32 *base; | |
958 | + u32 *base, addr; | |
957 | 959 | |
958 | 960 | if (is_compatible) |
959 | 961 | node = find_compatible_audio_device(device); |
960 | 962 | |
961 | 963 | |
962 | 964 | |
963 | 965 | |
964 | 966 | |
... | ... | @@ -966,22 +968,32 @@ |
966 | 968 | |
967 | 969 | base = (u32 *)get_property(node, "AAPL,address", NULL); |
968 | 970 | if (! base) { |
969 | - snd_printd("cannot find address for device %s\n", device); | |
970 | - return -ENODEV; | |
971 | - } | |
971 | + base = (u32 *)get_property(node, "reg", NULL); | |
972 | + if (!base) { | |
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 | 985 | #ifdef CONFIG_PPC_HAS_FEATURE_CALLS |
974 | - gp->addr = (*base) & 0x0000ffff; | |
986 | + gp->addr = addr & 0x0000ffff; | |
975 | 987 | #else |
976 | - gp->addr = ioremap((unsigned long)(*base), 1); | |
988 | + gp->addr = ioremap((unsigned long)addr, 1); | |
977 | 989 | #endif |
990 | + /* Try to find the active state, default to 0 ! */ | |
978 | 991 | base = (u32 *)get_property(node, "audio-gpio-active-state", NULL); |
979 | 992 | if (base) |
980 | 993 | gp->active_state = *base; |
981 | 994 | else |
982 | - gp->active_state = 1; | |
995 | + gp->active_state = 0; | |
983 | 996 | |
984 | - | |
985 | 997 | return (node->n_intrs > 0) ? node->intrs[0].line : 0; |
986 | 998 | } |
987 | 999 | |
988 | 1000 | |
... | ... | @@ -1039,11 +1051,16 @@ |
1039 | 1051 | pmac_tumbler_t *mix = chip->mixer_data; |
1040 | 1052 | snd_assert(mix, return -EINVAL); |
1041 | 1053 | |
1042 | - tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0); | |
1043 | - tumbler_find_device("amp-mute", &mix->amp_mute, 0); | |
1044 | - tumbler_find_device("headphone-mute", &mix->hp_mute, 0); | |
1054 | + if (tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0) < 0) | |
1055 | + tumbler_find_device("hw-reset", &mix->audio_reset, 1); | |
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 | 1060 | irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 0); |
1046 | 1061 | if (irq < 0) |
1062 | + irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 1); | |
1063 | + if (irq < 0) | |
1047 | 1064 | irq = tumbler_find_device("keywest-gpio15", &mix->hp_detect, 1); |
1048 | 1065 | |
1049 | 1066 | tumbler_reset_audio(chip); |
1050 | 1067 | |
... | ... | @@ -1109,9 +1126,13 @@ |
1109 | 1126 | /* set up TAS */ |
1110 | 1127 | tas_node = find_devices("deq"); |
1111 | 1128 | if (tas_node == NULL) |
1129 | + tas_node = find_devices("codec"); | |
1130 | + if (tas_node == NULL) | |
1112 | 1131 | return -ENODEV; |
1113 | 1132 | |
1114 | 1133 | paddr = (u32 *)get_property(tas_node, "i2c-address", NULL); |
1134 | + if (paddr == NULL) | |
1135 | + paddr = (u32 *)get_property(tas_node, "reg", NULL); | |
1115 | 1136 | if (paddr) |
1116 | 1137 | mix->i2c.addr = (*paddr) >> 1; |
1117 | 1138 | else |
... | ... | @@ -1155,7 +1176,6 @@ |
1155 | 1176 | chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip); |
1156 | 1177 | if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0) |
1157 | 1178 | return err; |
1158 | - | |
1159 | 1179 | |
1160 | 1180 | #ifdef CONFIG_PMAC_PBOOK |
1161 | 1181 | chip->resume = tumbler_resume; |