[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: