patch-2.4.19 linux-2.4.19/drivers/sound/dmasound/dmasound_q40.c
Next file: linux-2.4.19/drivers/sound/emu10k1/audio.c
Previous file: linux-2.4.19/drivers/sound/dmasound/dmasound_paula.c
Back to the patch index
Back to the overall index
- Lines: 326
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/sound/dmasound/dmasound_q40.c
- Orig date:
Mon Feb 25 11:38:05 2002
diff -urN linux-2.4.18/drivers/sound/dmasound/dmasound_q40.c linux-2.4.19/drivers/sound/dmasound/dmasound_q40.c
@@ -20,6 +20,7 @@
#include <linux/soundcard.h>
#include <asm/uaccess.h>
+#include <asm/q40ints.h>
#include <asm/q40_master.h>
#include "dmasound.h"
@@ -56,7 +57,7 @@
/*** Mid level stuff *********************************************************/
-#if 1
+
/* userCount, frameUsed, frameLeft == byte counts */
static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
@@ -77,42 +78,8 @@
*frameUsed += used ;
return used;
}
-#else
-static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8;
- ssize_t count, used;
- u_char *p = (u_char *) &frame[*frameUsed];
- u_char val;
- int stereo = sound.soft.stereo;
-
- frameLeft >>= 1;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(size_t, userCount, frameLeft);
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = table[data]+128;
- *p++ = val;
- if (stereo) {
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = table[data]+128;
- }
- *p++ = val;
- count--;
- }
- *frameUsed += used * 2;
- return stereo? used * 2: used;
-}
-#endif
-#if 1
static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
@@ -131,40 +98,7 @@
*frameUsed += used;
return used;
}
-#else
-static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- u_char *p = (u_char *) &frame[*frameUsed];
- u_char val;
- int stereo = dmasound.soft.stereo;
- frameLeft >>= 1;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(size_t, userCount, frameLeft);
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = data + 128;
- *p++ = val;
- if (stereo) {
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = data + 128;
- }
- *p++ = val;
- count--;
- }
- *frameUsed += used * 2;
- return stereo? used * 2: used;
-}
-#endif
-
-#if 1
static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
@@ -178,40 +112,8 @@
*frameUsed += used;
return used;
}
-#else
-static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- u_char *p = (u_char *) &frame[*frameUsed];
- u_char val;
- int stereo = dmasound.soft.stereo;
- frameLeft >>= 1;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(size_t, userCount, frameLeft);
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = data;
- *p++ = val;
- if (stereo) {
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = data;
- }
- *p++ = val;
- count--;
- }
- *frameUsed += used * 2;
- return stereo? used * 2: used;
-}
-#endif
-
/* a bit too complicated to optimise right now ..*/
static ssize_t q40_ctx_law(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
@@ -322,6 +224,125 @@
return utotal;
}
+/* compressing versions */
+static ssize_t q40_ctc_law(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ unsigned char *table = (unsigned char *)
+ (dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8);
+ unsigned int data = expand_data;
+ u_char *p = (u_char *) &frame[*frameUsed];
+ int bal = expand_bal;
+ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+ int utotal, ftotal;
+
+ ftotal = frameLeft;
+ utotal = userCount;
+ while (frameLeft) {
+ u_char c;
+ while(bal<0) {
+ if (userCount == 0)
+ goto lout;
+ if (!(bal<(-hSpeed))) {
+ if (get_user(c, userPtr))
+ return -EFAULT;
+ data = 0x80 + table[c];
+ }
+ userPtr++;
+ userCount--;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ lout:
+ expand_bal = bal;
+ expand_data = data;
+ *frameUsed += (ftotal - frameLeft);
+ utotal -= userCount;
+ return utotal;
+}
+
+
+static ssize_t q40_ctc_s8(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ u_char *p = (u_char *) &frame[*frameUsed];
+ unsigned int data = expand_data;
+ int bal = expand_bal;
+ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+ int utotal, ftotal;
+
+ ftotal = frameLeft;
+ utotal = userCount;
+ while (frameLeft) {
+ u_char c;
+ while (bal < 0) {
+ if (userCount == 0)
+ goto lout;
+ if (!(bal<(-hSpeed))) {
+ if (get_user(c, userPtr))
+ return -EFAULT;
+ data = c + 0x80;
+ }
+ userPtr++;
+ userCount--;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ lout:
+ expand_bal = bal;
+ expand_data = data;
+ *frameUsed += (ftotal - frameLeft);
+ utotal -= userCount;
+ return utotal;
+}
+
+
+static ssize_t q40_ctc_u8(const u_char *userPtr, size_t userCount,
+ u_char frame[], ssize_t *frameUsed,
+ ssize_t frameLeft)
+{
+ u_char *p = (u_char *) &frame[*frameUsed];
+ unsigned int data = expand_data;
+ int bal = expand_bal;
+ int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+ int utotal, ftotal;
+
+ ftotal = frameLeft;
+ utotal = userCount;
+ while (frameLeft) {
+ u_char c;
+ while (bal < 0) {
+ if (userCount == 0)
+ goto lout;
+ if (!(bal<(-hSpeed))) {
+ if (get_user(c, userPtr))
+ return -EFAULT;
+ data = c ;
+ }
+ userPtr++;
+ userCount--;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ lout:
+ expand_bal = bal;
+ expand_data = data;
+ *frameUsed += (ftotal - frameLeft) ;
+ utotal -= userCount;
+ return utotal;
+}
+
static TRANS transQ40Normal = {
q40_ct_law, q40_ct_law, q40_ct_s8, q40_ct_u8, NULL, NULL, NULL, NULL
@@ -331,6 +352,10 @@
q40_ctx_law, q40_ctx_law, q40_ctx_s8, q40_ctx_u8, NULL, NULL, NULL, NULL
};
+static TRANS transQ40Compressing = {
+ q40_ctc_law, q40_ctc_law, q40_ctc_s8, q40_ctc_u8, NULL, NULL, NULL, NULL
+};
+
/*** Low level stuff *********************************************************/
@@ -378,7 +403,7 @@
static void Q40Silence(void)
{
master_outb(0,SAMPLE_ENABLE_REG);
- *DAC_LEFT=*DAC_RIGHT=0;
+ *DAC_LEFT=*DAC_RIGHT=127;
}
static char *q40_pp=NULL;
@@ -473,7 +498,7 @@
if (q40_sc<2)
{ /* there was nothing to play, disable irq */
master_outb(0,SAMPLE_ENABLE_REG);
- *DAC_LEFT=*DAC_RIGHT=0;
+ *DAC_LEFT=*DAC_RIGHT=127;
}
WAKE_UP(write_sq.action_queue);
@@ -506,10 +531,10 @@
Q40Silence();
- if (dmasound.hard.speed > 20000) {
- /* we would need to squeeze the sound, but we won't do that */
+ if (dmasound.hard.speed > 20200) {
+ /* squeeze the sound, we do that */
dmasound.hard.speed = 20000;
- dmasound.trans_write = &transQ40Normal;
+ dmasound.trans_write = &transQ40Compressing;
} else if (dmasound.hard.speed > 10000) {
dmasound.hard.speed = 20000;
} else {
@@ -584,6 +609,7 @@
setFormat: Q40SetFormat,
setVolume: Q40SetVolume,
play: Q40Play,
+ min_dsp_speed: 10000,
version: ((DMASOUND_Q40_REVISION<<8) | DMASOUND_Q40_EDITION),
hardware_afmts: AFMT_U8, /* h'ware-supported formats *only* here */
capabilities: DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
@@ -611,4 +637,6 @@
module_init(dmasound_q40_init);
module_exit(dmasound_q40_cleanup);
+
+MODULE_DESCRIPTION("Q40/Q60 sound driver");
MODULE_LICENSE("GPL");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)