patch-2.2.14 linux/drivers/sound/dmasound.c
Next file: linux/drivers/sound/es1370.c
Previous file: linux/drivers/sound/adlib_card.c
Back to the patch index
Back to the overall index
- Lines: 167
- Date:
Tue Jan 4 10:12:21 2000
- Orig file:
v2.2.13/linux/drivers/sound/dmasound.c
- Orig date:
Tue Oct 19 17:10:38 1999
diff -u --recursive --new-file v2.2.13/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c
@@ -89,6 +89,7 @@
#include <linux/malloc.h>
#include <linux/sound.h>
#include <linux/init.h>
+#include <linux/delay.h>
#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/setup.h>
@@ -233,7 +234,7 @@
-269, -245, -218, -187, -153, -117, -79, -40,
};
-#define BEEP_SPEED 2 /* 22050 Hz sample rate */
+#define BEEP_SRATE 22050 /* 22050 Hz sample rate */
#define BEEP_BUFLEN 512
#define BEEP_VOLUME 15 /* 0 - 100 */
@@ -3003,8 +3004,9 @@
static int __init PMacIrqInit(void)
{
- if (request_irq(awacs_irq, pmac_awacs_intr, 0, "AWACS", 0)
- || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "AWACS out", 0))
+ if (request_irq(awacs_irq, pmac_awacs_intr, 0, "AWACS", (void *) awacs)
+ || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0,
+ "AWACS out", (void *) awacs))
return 0;
return 1;
}
@@ -3016,8 +3018,8 @@
out_le32(&awacs_txdma->control, RUN<<16);
/* disable interrupts from awacs interface */
out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
- free_irq(awacs_irq, pmac_awacs_intr);
- free_irq(awacs_tx_irq, pmac_awacs_tx_intr);
+ free_irq(awacs_irq, (void *) awacs);
+ free_irq(awacs_tx_irq, (void *) awacs);
kfree(awacs_tx_cmd_space);
if (beep_buf)
kfree(beep_buf);
@@ -3037,6 +3039,7 @@
static int awacs_freqs[8] = {
44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
};
+static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
static void PMacInit(void)
{
@@ -3060,10 +3063,13 @@
* Otherwise choose the next higher rate.
* N.B.: burgundy awacs (iMac and later) only works at 44100 Hz.
*/
- i = (awacs_revision >= AWACS_BURGUNDY)? 1: 8;
+ i = 8;
do {
tolerance = catchRadius * awacs_freqs[--i] / 100;
- } while (sound.soft.speed > awacs_freqs[i] + tolerance && i > 0);
+ if (awacs_freqs_ok[i]
+ && sound.soft.speed <= awacs_freqs[i] + tolerance)
+ break;
+ } while (i > 0);
if (sound.soft.speed >= awacs_freqs[i] - tolerance)
sound.trans = &transAwacsNormal;
else
@@ -3171,7 +3177,7 @@
out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
out_le32(&awacs->control,
(in_le32(&awacs->control) & ~0x1f00)
- || (awacs_rate_index << 8));
+ | (awacs_rate_index << 8));
out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
beep_playing = 0;
}
@@ -3259,6 +3265,11 @@
save_flags(flags); cli();
if (beep_playing) {
st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
+ out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
+ out_le32(&awacs->control,
+ (in_le32(&awacs->control) & ~0x1f00)
+ | (awacs_rate_index << 8));
+ out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
beep_playing = 0;
}
restore_flags(flags);
@@ -3271,8 +3282,8 @@
static void awacs_mksound(unsigned int hz, unsigned int ticks)
{
unsigned long flags;
- int beep_speed = (awacs_revision < AWACS_BURGUNDY)? BEEP_SPEED: 0;
- int srate = awacs_freqs[beep_speed];
+ int beep_speed = 0;
+ int srate;
int period, ncycles, nsamples;
int i, j, f;
short *p;
@@ -3280,6 +3291,11 @@
static int beep_nsamples_cache;
static int beep_volume_cache;
+ for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
+ if (awacs_freqs_ok[i])
+ beep_speed = i;
+ srate = awacs_freqs[beep_speed];
+
if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
#if 1
/* this is a hack for broken X server code */
@@ -3366,6 +3382,12 @@
out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
enable_irq(awacs_irq);
enable_irq(awacs_tx_irq);
+ if (awacs_revision == 3) {
+ mdelay(100);
+ awacs_write(0x6000);
+ mdelay(2);
+ awacs_write(awacs_reg[1] | MASK_ADDR1);
+ }
}
return PBOOK_SLEEP_OK;
}
@@ -4944,12 +4966,41 @@
np = find_devices("davbus");
sound = find_devices("sound");
if (sound != 0 && sound->parent == np) {
- int *sfprop;
- sfprop = (int *) get_property(sound, "sub-frame", 0);
- if (sfprop != 0 && *sfprop >= 0 && *sfprop < 16)
- awacs_subframe = *sfprop;
+ unsigned int *prop, l, i;
+ prop = (unsigned int *)
+ get_property(sound, "sub-frame", 0);
+ if (prop != 0 && *prop >= 0 && *prop < 16)
+ awacs_subframe = *prop;
if (device_is_compatible(sound, "burgundy"))
awacs_revision = AWACS_BURGUNDY;
+
+ /* look for a property saying what sample rates
+ are available */
+ for (i = 0; i < 8; ++i)
+ awacs_freqs_ok[i] = 0;
+ prop = (unsigned int *) get_property
+ (sound, "sample-rates", &l);
+ if (prop == 0)
+ prop = (unsigned int *) get_property
+ (sound, "output-frame-rates", &l);
+ if (prop != 0) {
+ for (l /= sizeof(int); l > 0; --l) {
+ /* sometimes the rate is in the
+ high-order 16 bits (?) */
+ unsigned int r = *prop++;
+ if (r >= 0x10000)
+ r >>= 16;
+ for (i = 0; i < 8; ++i) {
+ if (r == awacs_freqs[i]) {
+ awacs_freqs_ok[i] = 1;
+ break;
+ }
+ }
+ }
+ } else {
+ /* assume just 44.1k is OK */
+ awacs_freqs_ok[0] = 1;
+ }
}
}
if (np != NULL && np->n_addrs >= 3 && np->n_intrs >= 3) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)