Commit 79918bec authored by Dave Jones's avatar Dave Jones Committed by Linus Torvalds

[PATCH] dmasound update.

The largest part of the OSS update from 2.4
Various changelog entries scattered throughout the patch.
parent 8412c915
/*
* linux/drivers/sound/dmasound/dmasound_atari.c
*
* Atari TT and Falcon DMA Sound Driver
*
* See linux/drivers/sound/dmasound/dmasound_core.c for copyright and credits
* prior to 28/01/2001
*
* 28/01/2001 [0.1] Iain Sandoe
* - added versioning
* - put in and populated the hardware_afmts field.
* [0.2] - put in SNDCTL_DSP_GETCAPS value.
* 01/02/2001 [0.3] - put in default hard/soft settings.
*/
......@@ -21,10 +27,11 @@
#include "dmasound.h"
#define DMASOUND_ATARI_REVISION 0
#define DMASOUND_ATARI_EDITION 3
extern void atari_microwire_cmd(int cmd);
static int is_falcon;
static int write_sq_ignore_int = 0; /* ++TeSche: used for Falcon */
......@@ -136,10 +143,10 @@ static void FalconMixerInit(void);
static int AtaMixerIoctl(u_int cmd, u_long arg);
static int TTMixerIoctl(u_int cmd, u_long arg);
static int FalconMixerIoctl(u_int cmd, u_long arg);
static void AtaWriteSqSetup(void);
static void AtaSqOpen(void);
static int TTStateInfo(char *buffer);
static int FalconStateInfo(char *buffer);
static int AtaWriteSqSetup(void);
static int AtaSqOpen(mode_t mode);
static int TTStateInfo(char *buffer, size_t space);
static int FalconStateInfo(char *buffer, size_t space);
/*** Translations ************************************************************/
......@@ -1438,43 +1445,73 @@ static int FalconMixerIoctl(u_int cmd, u_long arg)
return AtaMixerIoctl(cmd, arg);
}
static void AtaWriteSqSetup(void)
static int AtaWriteSqSetup(void)
{
write_sq_ignore_int = 0;
return 0 ;
}
static void AtaSqOpen(void)
static int AtaSqOpen(mode_t mode)
{
write_sq_ignore_int = 1;
return 0 ;
}
static int TTStateInfo(char *buffer)
static int TTStateInfo(char *buffer, size_t space)
{
int len = 0;
len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-40...0]\n",
len += sprintf(buffer+len, "\tvol left %ddB [-40... 0]\n",
dmasound.volume_left);
len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-40...0]\n",
len += sprintf(buffer+len, "\tvol right %ddB [-40... 0]\n",
dmasound.volume_right);
len += sprintf(buffer+len, "\tsound.bass = %ddB [-12...+12]\n",
len += sprintf(buffer+len, "\tbass %ddB [-12...+12]\n",
dmasound.bass);
len += sprintf(buffer+len, "\tsound.treble = %ddB [-12...+12]\n",
len += sprintf(buffer+len, "\ttreble %ddB [-12...+12]\n",
dmasound.treble);
if (len >= space) {
printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
len = space ;
}
return len;
}
static int FalconStateInfo(char *buffer)
static int FalconStateInfo(char *buffer, size_t space)
{
int len = 0;
len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-22.5...0]\n",
len += sprintf(buffer+len, "\tvol left %ddB [-22.5 ... 0]\n",
dmasound.volume_left);
len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-22.5...0]\n",
len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
dmasound.volume_right);
if (len >= space) {
printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
len = space ;
}
return len;
}
/*** Machine definitions *****************************************************/
static SETTINGS def_hard_falcon = {
format: AFMT_S8,
stereo: 0,
size: 8,
speed: 8195
} ;
static SETTINGS def_hard_tt = {
format: AFMT_S8,
stereo: 0,
size: 8,
speed: 12517
} ;
static SETTINGS def_soft = {
format: AFMT_U8,
stereo: 0,
size: 8,
speed: 8000
} ;
static MACHINE machTT = {
name: "Atari",
......@@ -1501,6 +1538,9 @@ static MACHINE machTT = {
sq_open: AtaSqOpen,
state_info: TTStateInfo,
min_dsp_speed: 6258,
version: ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
hardware_afmts: AFMT_S8, /* h'ware-supported formats *only* here */
capabilities: DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
};
static MACHINE machFalcon = {
......@@ -1525,6 +1565,9 @@ static MACHINE machFalcon = {
sq_open: AtaSqOpen,
state_info: FalconStateInfo,
min_dsp_speed: 8195,
version: ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
hardware_afmts: (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
capabilities: DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
};
......@@ -1536,9 +1579,13 @@ static int __init dmasound_atari_init(void)
if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
if (ATARIHW_PRESENT(CODEC)) {
dmasound.mach = machFalcon;
dmasound.mach.default_soft = def_soft ;
dmasound.mach.default_hard = def_hard_falcon ;
is_falcon = 1;
} else if (ATARIHW_PRESENT(MICROWIRE)) {
dmasound.mach = machTT;
dmasound.mach.default_soft = def_soft ;
dmasound.mach.default_hard = def_hard_tt ;
is_falcon = 0;
} else
return -ENODEV;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/*
* linux/drivers/sound/dmasound/dmasound_paula.c
*
* Amiga `Paula' DMA Sound Driver
*
* See linux/drivers/sound/dmasound/dmasound_core.c for copyright and credits
*/
* prior to 28/01/2001
*
* 28/01/2001 [0.1] Iain Sandoe
* - added versioning
* - put in and populated the hardware_afmts field.
* [0.2] - put in SNDCTL_DSP_GETCAPS value.
* [0.3] - put in constraint on state buffer usage.
* [0.4] - put in default hard/soft settings
*/
#include <linux/module.h>
......@@ -23,6 +30,8 @@
#include "dmasound.h"
#define DMASOUND_PAULA_REVISION 0
#define DMASOUND_PAULA_EDITION 4
/*
* The minimum period for audio depends on htotal (for OCS/ECS/AGA)
......@@ -113,8 +122,8 @@ static inline void enable_heartbeat(void)
static void AmiMixerInit(void);
static int AmiMixerIoctl(u_int cmd, u_long arg);
static void AmiWriteSqSetup(void);
static int AmiStateInfo(char *buffer);
static int AmiWriteSqSetup(void);
static int AmiStateInfo(char *buffer, size_t space);
/*** Translations ************************************************************/
......@@ -646,26 +655,44 @@ static int AmiMixerIoctl(u_int cmd, u_long arg)
}
static void AmiWriteSqSetup(void)
static int AmiWriteSqSetup(void)
{
write_sq_block_size_half = write_sq.block_size>>1;
write_sq_block_size_quarter = write_sq_block_size_half>>1;
return 0;
}
static int AmiStateInfo(char *buffer)
static int AmiStateInfo(char *buffer, size_t space)
{
int len = 0;
len += sprintf(buffer+len, "\tsound.volume_left = %d [0...64]\n",
dmasound.volume_left);
len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
dmasound.volume_right);
if (len >= space) {
printk(KERN_ERR "dmasound_paula: overlowed state buffer alloc.\n") ;
len = space ;
}
return len;
}
/*** Machine definitions *****************************************************/
static SETTINGS def_hard = {
format: AFMT_S8,
stereo: 0,
size: 8,
speed: 8000
} ;
static SETTINGS def_soft = {
format: AFMT_U8,
stereo: 0,
size: 8,
speed: 8000
} ;
static MACHINE machAmiga = {
name: "Amiga",
......@@ -688,7 +715,10 @@ static MACHINE machAmiga = {
mixer_ioctl: AmiMixerIoctl,
write_sq_setup: AmiWriteSqSetup,
state_info: AmiStateInfo,
min_dsp_speed: 8000
min_dsp_speed: 8000,
version: ((DMASOUND_PAULA_REVISION<<8) | DMASOUND_PAULA_EDITION),
hardware_afmts: (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
capabilities: DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
};
......@@ -704,6 +734,8 @@ int __init dmasound_paula_init(void)
"dmasound [Paula]"))
return -EBUSY;
dmasound.mach = machAmiga;
dmasound.mach.default_hard = def_hard ;
dmasound.mach.default_soft = def_soft ;
err = dmasound_init();
if (err)
release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
......
/*
* linux/drivers/sound/dmasound/dmasound_q40.c
*
* Q40 DMA Sound Driver
*
* See linux/drivers/sound/dmasound/dmasound_core.c for copyright and credits
* prior to 28/01/2001
*
* 28/01/2001 [0.1] Iain Sandoe
* - added versioning
* - put in and populated the hardware_afmts field.
* [0.2] - put in SNDCTL_DSP_GETCAPS value.
* [0.3] - put in default hard/soft settings.
*/
......@@ -14,10 +20,13 @@
#include <linux/soundcard.h>
#include <asm/uaccess.h>
#include <asm/q40ints.h>
#include <asm/q40_master.h>
#include "dmasound.h"
#define DMASOUND_Q40_REVISION 0
#define DMASOUND_Q40_EDITION 3
static int expand_bal; /* Balance factor for expanding (not volume!) */
static int expand_data; /* Data for expanding */
......@@ -48,7 +57,7 @@ static void Q40Interrupt(void);
/*** 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,
......@@ -69,42 +78,8 @@ static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount,
*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)
......@@ -123,40 +98,7 @@ static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount,
*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)
......@@ -170,40 +112,8 @@ static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount,
*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,
......@@ -314,6 +224,125 @@ static ssize_t q40_ctx_u8(const u_char *userPtr, size_t userCount,
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
......@@ -323,6 +352,10 @@ static TRANS transQ40Expanding = {
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 *********************************************************/
......@@ -370,7 +403,7 @@ static void Q40IrqCleanUp(void)
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;
......@@ -465,7 +498,7 @@ static void Q40Interrupt(void)
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);
......@@ -498,10 +531,10 @@ static void Q40Init(void)
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 {
......@@ -546,6 +579,19 @@ static int Q40SetVolume(int volume)
/*** Machine definitions *****************************************************/
static SETTINGS def_hard = {
format: AFMT_U8,
stereo: 0,
size: 8,
speed: 10000
} ;
static SETTINGS def_soft = {
format: AFMT_U8,
stereo: 0,
size: 8,
speed: 8000
} ;
static MACHINE machQ40 = {
name: "Q40",
......@@ -562,7 +608,11 @@ static MACHINE machQ40 = {
silence: Q40Silence,
setFormat: Q40SetFormat,
setVolume: Q40SetVolume,
play: Q40Play
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 */
};
......@@ -573,6 +623,8 @@ int __init dmasound_q40_init(void)
{
if (MACH_IS_Q40) {
dmasound.mach = machQ40;
dmasound.mach.default_hard = def_hard ;
dmasound.mach.default_soft = def_soft ;
return dmasound_init();
} else
return -ENODEV;
......@@ -585,4 +637,6 @@ static void __exit dmasound_q40_cleanup(void)
module_init(dmasound_q40_init);
module_exit(dmasound_q40_cleanup);
MODULE_DESCRIPTION("Q40/Q60 sound driver");
MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment