Patch against 2.4.8-pre7-ben0 for Tumbler no little endian support
Patch is attached. This flags the FireWire iBook as also being an iBook,
and indicates that KeyLargo revisions later than 2 (since the FireWire
iBook has a rev. 3) cannot reorder little-endian samples on their own. I
also have added code in drivers/sound/dmasound/trans_16.c to do the
necessary byte reordering in little-endian samples, so that the audio
output will be correct.
Derrik Pates | Sysadmin, Douglas School | #linuxOS on EFnet
dpates@dsdk12.net | District (dsdk12.net) | #linuxOS on OPN
--- /home/linux-2.4-benh.dist/drivers/sound/dmasound/dmasound_awacs.c Thu Aug 9 07:12:02 2001
+++ drivers/sound/dmasound/dmasound_awacs.c Thu Aug 9 12:35:14 2001
@@ -2004,6 +2004,10 @@
is_ibook = 1 ;
return ;
}
+ if (machine_is_compatible("PowerBook2,2")) { /* ibook 2 (firewire) */
+ is_ibook = 1 ;
+ return ;
+ }
}
/* Get the OF node that tells us about the registers, interrupts etc. to use
@@ -2258,10 +2262,10 @@
break;
}
}
- if (rev == 2) {
+ if (rev >= 2) {
hw_can_byteswap = 0;
#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: found Keylargo rev 2 - H/W byte-swap disabled\n") ;
+printk("dmasound_pmac: found Keylargo rev 2 or later - H/W byte-swap disabled\n") ;
#endif
}
}
--- /home/linux-2.4-benh.dist/drivers/sound/dmasound/trans_16.c Thu Aug 9 07:12:01 2001
+++ drivers/sound/dmasound/trans_16.c Thu Aug 9 12:33:01 2001
@@ -12,6 +12,7 @@
#include <linux/soundcard.h>
#include <asm/uaccess.h>
+#include <asm/byteorder.h>
#include "dmasound.h"
static short dmasound_alaw2dma16[] ;
@@ -26,10 +27,16 @@
static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
-static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_s16le(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
-static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_s16be(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft);
+static ssize_t pmac_ct_u16le(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft);
+static ssize_t pmac_ct_u16be(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
@@ -42,17 +49,29 @@
static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
-static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ctx_s16le(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft);
+static ssize_t pmac_ctx_s16be(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft);
+static ssize_t pmac_ctx_u16le(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
-static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ctx_u16be(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
-static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_s16le_read(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft);
+static ssize_t pmac_ct_s16be_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
-static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_u16le_read(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft);
+static ssize_t pmac_ct_u16be_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft);
@@ -156,7 +175,37 @@
}
-static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_s16le(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ ssize_t count, used;
+ int stereo = dmasound.soft.stereo;
+ short *fp = (short *) &frame[*frameUsed];
+ short *up = (short *) userPtr;
+
+ frameLeft >>= 2;
+ userCount >>= (stereo? 2: 1);
+ used = count = min(userCount, frameLeft);
+ while (count > 0) {
+ short data;
+ if (get_user(data, up++))
+ return -EFAULT;
+ __arch__swab16s(&data);
+ *fp++ = data;
+ if (stereo) {
+ if (get_user(data, up++))
+ return -EFAULT;
+ __arch__swab16s(&data);
+ }
+ *fp++ = data;
+ count--;
+ }
+ *frameUsed += used * 4;
+ return stereo? used * 4: used * 2;
+}
+
+static ssize_t pmac_ct_s16be(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
@@ -185,7 +234,40 @@
return stereo? used * 4: used * 2;
}
-static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_u16le(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ ssize_t count, used;
+ int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
+ int stereo = dmasound.soft.stereo;
+ short *fp = (short *) &frame[*frameUsed];
+ short *up = (short *) userPtr;
+
+ frameLeft >>= 2;
+ userCount >>= (stereo? 2: 1);
+ used = count = min(userCount, frameLeft);
+ while (count > 0) {
+ short data;
+ if (get_user(data, up++))
+ return -EFAULT;
+ data ^= mask;
+ __arch__swab16s(&data);
+ *fp++ = data;
+ if (stereo) {
+ if (get_user(data, up++))
+ return -EFAULT;
+ data ^= mask;
+ __arch__swab16s(&data);
+ }
+ *fp++ = data;
+ count--;
+ }
+ *frameUsed += used * 4;
+ return stereo? used * 4: used * 2;
+}
+
+static ssize_t pmac_ct_u16be(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
@@ -354,7 +436,53 @@
}
-static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ctx_s16le(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ unsigned int *p = (unsigned int *) &frame[*frameUsed];
+ unsigned int data = expand_data;
+ unsigned short *up = (unsigned short *) userPtr;
+ int bal = expand_bal;
+ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+ int stereo = dmasound.soft.stereo;
+ int utotal, ftotal;
+
+ frameLeft >>= 2;
+ userCount >>= (stereo? 2: 1);
+ ftotal = frameLeft;
+ utotal = userCount;
+ while (frameLeft) {
+ unsigned short c;
+ if (bal < 0) {
+ if (userCount == 0)
+ break;
+ if (get_user(data, up++))
+ return -EFAULT;
+ if (stereo) {
+ if (get_user(c, up++))
+ return -EFAULT;
+ data = (data << 16) + c;
+ } else
+ data = (data << 16) + data;
+ userCount--;
+ bal += hSpeed;
+ }
+ __arch__swab16s((short *)&data);
+ __arch__swab16s(((short *)&data + 1));
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ expand_bal = bal;
+ expand_data = data;
+ *frameUsed += (ftotal - frameLeft) * 4;
+ utotal -= userCount;
+ return stereo? utotal * 4: utotal * 2;
+}
+
+
+static ssize_t pmac_ctx_s16be(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
@@ -398,7 +526,55 @@
}
-static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ctx_u16le(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
+ unsigned int *p = (unsigned int *) &frame[*frameUsed];
+ unsigned int data = expand_data;
+ unsigned short *up = (unsigned short *) userPtr;
+ int bal = expand_bal;
+ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+ int stereo = dmasound.soft.stereo;
+ int utotal, ftotal;
+
+ frameLeft >>= 2;
+ userCount >>= (stereo? 2: 1);
+ ftotal = frameLeft;
+ utotal = userCount;
+ while (frameLeft) {
+ unsigned short c;
+ if (bal < 0) {
+ if (userCount == 0)
+ break;
+ if (get_user(data, up++))
+ return -EFAULT;
+ data ^= mask;
+ if (stereo) {
+ if (get_user(c, up++))
+ return -EFAULT;
+ data = (data << 16) + (c ^ mask);
+ } else
+ data = (data << 16) + data;
+ userCount--;
+ bal += hSpeed;
+ }
+ __arch__swab16s((short *)&data);
+ __arch__swab16s(((short *)&data + 1));
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ expand_bal = bal;
+ expand_data = data;
+ *frameUsed += (ftotal - frameLeft) * 4;
+ utotal -= userCount;
+ return stereo? utotal * 4: utotal * 2;
+}
+
+
+static ssize_t pmac_ctx_u16be(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
@@ -510,7 +686,38 @@
return stereo? used * 2: used;
}
-static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_s16le_read(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ ssize_t count, used;
+ int stereo = dmasound.soft.stereo;
+ short *fp = (short *) &frame[*frameUsed];
+ short *up = (short *) userPtr;
+
+ frameLeft >>= 2;
+ userCount >>= (stereo? 2: 1);
+ used = count = min(userCount, frameLeft);
+ while (count > 0) {
+ short data;
+ data = *fp++;
+ __arch__swab16s(&data);
+ if (put_user(data, up++))
+ return -EFAULT;
+ if (stereo) {
+ data = *fp;
+ __arch__swab16s(&data);
+ if (put_user(data, up++))
+ return -EFAULT;
+ }
+ fp++;
+ count--;
+ }
+ *frameUsed += used * 4;
+ return stereo? used * 4: used * 2;
+}
+
+static ssize_t pmac_ct_s16be_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
@@ -539,12 +746,47 @@
return stereo? used * 4: used * 2;
}
-static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
+static ssize_t pmac_ct_u16le_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
ssize_t count, used;
- int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
+ int mask = 0x0080;
+ int stereo = dmasound.soft.stereo;
+ short *fp = (short *) &frame[*frameUsed];
+ short *up = (short *) userPtr;
+
+ frameLeft >>= 2;
+ userCount >>= (stereo? 2: 1);
+ used = count = min(userCount, frameLeft);
+ while (count > 0) {
+ short data;
+
+ data = *fp++;
+ data ^= mask;
+ __arch__swab16s(&data);
+ if (put_user(data, up++))
+ return -EFAULT;
+ if (stereo) {
+ data = *fp;
+ data ^= mask;
+ __arch__swab16s(&data);
+ if (put_user(data, up++))
+ return -EFAULT;
+ }
+ fp++;
+ count--;
+ }
+ *frameUsed += used * 4;
+ return stereo? used * 4: used * 2;
+}
+
+static ssize_t pmac_ct_u16be_read(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ ssize_t count, used;
+ int mask = 0x8000;
int stereo = dmasound.soft.stereo;
short *fp = (short *) &frame[*frameUsed];
short *up = (short *) userPtr;
@@ -553,7 +795,7 @@
userCount >>= (stereo? 2: 1);
used = count = min(userCount, frameLeft);
while (count > 0) {
- int data;
+ short data;
data = *fp++;
data ^= mask;
@@ -577,10 +819,10 @@
ct_alaw: pmac_ct_law,
ct_s8: pmac_ct_s8,
ct_u8: pmac_ct_u8,
- ct_s16be: pmac_ct_s16,
- ct_u16be: pmac_ct_u16,
- ct_s16le: pmac_ct_s16,
- ct_u16le: pmac_ct_u16,
+ ct_s16be: pmac_ct_s16be,
+ ct_u16be: pmac_ct_u16be,
+ ct_s16le: pmac_ct_s16le,
+ ct_u16le: pmac_ct_u16le,
};
TRANS transAwacsExpand = {
@@ -588,19 +830,19 @@
ct_alaw: pmac_ctx_law,
ct_s8: pmac_ctx_s8,
ct_u8: pmac_ctx_u8,
- ct_s16be: pmac_ctx_s16,
- ct_u16be: pmac_ctx_u16,
- ct_s16le: pmac_ctx_s16,
- ct_u16le: pmac_ctx_u16,
+ ct_s16be: pmac_ctx_s16be,
+ ct_u16be: pmac_ctx_u16be,
+ ct_s16le: pmac_ctx_s16le,
+ ct_u16le: pmac_ctx_u16le,
};
TRANS transAwacsNormalRead = {
ct_s8: pmac_ct_s8_read,
ct_u8: pmac_ct_u8_read,
- ct_s16be: pmac_ct_s16_read,
- ct_u16be: pmac_ct_u16_read,
- ct_s16le: pmac_ct_s16_read,
- ct_u16le: pmac_ct_u16_read,
+ ct_s16be: pmac_ct_s16be_read,
+ ct_u16be: pmac_ct_u16be_read,
+ ct_s16le: pmac_ct_s16le_read,
+ ct_u16le: pmac_ct_u16le_read,
};
/* translation tables */
Reply to: