patch-2.2.0-pre8 linux/drivers/sound/sb_audio.c
Next file: linux/drivers/sound/sb_common.c
Previous file: linux/drivers/sound/sb.h
Back to the patch index
Back to the overall index
- Lines: 336
- Date:
Thu Jan 14 22:59:47 1999
- Orig file:
v2.2.0-pre7/linux/drivers/sound/sb_audio.c
- Orig date:
Fri Jan 8 22:36:11 1999
diff -u --recursive --new-file v2.2.0-pre7/linux/drivers/sound/sb_audio.c linux/drivers/sound/sb_audio.c
@@ -29,7 +29,9 @@
#include "sb_mixer.h"
#include "sb.h"
-static int sb_audio_open(int dev, int mode)
+#include "sb_ess.h"
+
+int sb_audio_open(int dev, int mode)
{
sb_devc *devc = audio_devs[dev]->devc;
unsigned long flags;
@@ -93,7 +95,7 @@
return 0;
}
-static void sb_audio_close(int dev)
+void sb_audio_close(int dev)
{
sb_devc *devc = audio_devs[dev]->devc;
@@ -600,250 +602,21 @@
}
/*
- * ESS specific routines
- */
-
-static int ess_audio_set_speed(int dev, int speed)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- int divider;
-
- if (speed > 0)
- {
- if (speed < 5000)
- speed = 5000;
- if (speed > 48000)
- speed = 48000;
-
- if (speed > 22000)
- {
- divider = (795500 + speed / 2) / speed;
- speed = (795500 + divider / 2) / divider;
- }
- else
- {
- divider = (397700 + speed / 2) / speed;
- speed = (397700 + divider / 2) / divider;
- }
- devc->speed = speed;
- }
- return devc->speed;
-}
-
-static void ess_speed(sb_devc * devc)
-{
- int divider;
- unsigned char bits = 0;
- int speed = devc->speed;
-
- if (speed < 4000)
- speed = 4000;
- else if (speed > 48000)
- speed = 48000;
-
- if (speed > 22000)
- {
- bits = 0x80;
- divider = 256 - (795500 + speed / 2) / speed;
- }
- else
- {
- divider = 128 - (397700 + speed / 2) / speed;
- }
-
- bits |= (unsigned char) divider;
- ess_write(devc, 0xa1, bits);
-
- /*
- * Set filter divider register
- */
-
- speed = (speed * 9) / 20; /* Set filter roll-off to 90% of speed/2 */
- divider = 256 - 7160000 / (speed * 82);
- ess_write(devc, 0xa2, divider);
- return;
-}
-
-static void ess_change
- (sb_devc *devc, unsigned int reg, unsigned int mask, unsigned int val)
-{
- int value;
-
- value = ess_read(devc, reg);
- value = (value & ~mask) | (val & mask);
- ess_write(devc, reg, value);
-}
-
-struct ess_command {int cmd; int data;};
-
-static void ess_exec_commands
- (sb_devc *devc, struct ess_command *cmdtab[])
-{
- struct ess_command *cmd;
-
- cmd = cmdtab [ ((devc->channels != 1) << 1) + (devc->bits != AFMT_U8) ];
-
- while (cmd->cmd != -1) {
- ess_write (devc, cmd->cmd, cmd->data);
- cmd++;
- }
-}
-
-static struct ess_command ess_i08m[] = /* input 8 bit mono */
- { {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
-static struct ess_command ess_i16m[] = /* input 16 bit mono */
- { {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
-static struct ess_command ess_i08s[] = /* input 8 bit stereo */
- { {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
-static struct ess_command ess_i16s[] = /* input 16 bit stereo */
- { {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
-
-static struct ess_command *ess_inp_cmds[] =
- { ess_i08m, ess_i16m, ess_i08s, ess_i16s };
-
-static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- ess_speed(devc);
- sb_dsp_command(devc, DSP_CMD_SPKOFF);
-
- ess_write(devc, 0xb8, 0x0e); /* Auto init DMA mode */
- ess_change (devc, 0xa8, 0x03, 3 - devc->channels); /* Mono/stereo */
- ess_write(devc, 0xb9, 2); /* Demand mode (4 bytes/DMA request) */
-
- ess_exec_commands (devc, ess_inp_cmds);
-
- ess_change (devc, 0xb1, 0xf0, 0x50);
- ess_change (devc, 0xb2, 0xf0, 0x50);
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static struct ess_command ess_o08m[] = /* output 8 bit mono */
- { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
-static struct ess_command ess_o16m[] = /* output 16 bit mono */
- { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
-static struct ess_command ess_o08s[] = /* output 8 bit stereo */
- { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
-static struct ess_command ess_o16s[] = /* output 16 bit stereo */
- { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
-
-
-static struct ess_command *ess_out_cmds[] =
- { ess_o08m, ess_o16m, ess_o08s, ess_o16s };
-
-static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- sb_dsp_reset(devc);
- ess_speed(devc);
-
- ess_write(devc, 0xb8, 4); /* Auto init DMA mode */
- ess_change (devc, 0xa8, 0x03, 3 - devc->channels); /* Mono/stereo */
- ess_write(devc, 0xb9, 2); /* Demand mode (4 bytes/request) */
-
- ess_exec_commands (devc, ess_out_cmds);
-
- ess_change (devc, 0xb1, 0xf0, 0x50);
- ess_change (devc, 0xb2, 0xf0, 0x50);
-
- sb_dsp_command(devc, DSP_CMD_SPKON);
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static void ess_audio_output_block(int dev, unsigned long buf, int nr_bytes,
- int intrflag)
-{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_OUTPUT;
-
- ess_write(devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
- ess_write(devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
-
- ess_change (devc, 0xb8, 0x05, 0x05); /* Go */
- devc->intr_active = 1;
-}
-
-static void ess_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
-
- /*
- * Start a DMA input to the buffer pointed by dmaqtail
- */
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_INPUT;
-
- ess_write(devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
- ess_write(devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
-
- ess_change (devc, 0xb8, 0x0f, 0x0f); /* Go */
- devc->intr_active = 1;
-}
-
-static void ess_audio_trigger(int dev, int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- bits &= devc->irq_mode;
-
- if (!bits)
- sb_dsp_command(devc, 0xd0); /* Halt DMA */
- else
- {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- ess_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
-
- case IMODE_OUTPUT:
- ess_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
- }
- }
-
- devc->trigger_bits = bits;
-}
-
-/*
* SB16 specific routines
*/
static int sb16_audio_set_speed(int dev, int speed)
{
sb_devc *devc = audio_devs[dev]->devc;
+ int max_speed = devc->submodel == SUBMDL_ALS100 ? 48000 : 44100;
if (speed > 0)
{
- if (speed < 5000)
- speed = 4000;
+ if (speed < 5000) /* which of these */
+ speed = 4000; /* is correct ??? */
- if (speed > 44100)
- speed = 44100;
+ if (speed > max_speed)
+ speed = max_speed;
devc->speed = speed;
}
@@ -1276,26 +1049,6 @@
sb16_audio_mmap
};
-static struct audio_driver ess_audio_driver = /* ESS ES688/1688 */
-{
- sb_audio_open,
- sb_audio_close,
- sb_set_output_parms,
- sb_set_input_parms,
- NULL,
- ess_audio_prepare_for_input,
- ess_audio_prepare_for_output,
- sb1_audio_halt_xfer,
- NULL, /* local_qlen */
- NULL, /* copy_from_user */
- NULL,
- NULL,
- ess_audio_trigger,
- ess_audio_set_speed,
- sb16_audio_set_bits,
- sbpro_audio_set_channels
-};
-
void sb_audio_init(sb_devc * devc, char *name)
{
int audio_flags = 0;
@@ -1332,9 +1085,7 @@
case MDL_ESS:
DDB(printk("Will use ESS ES688/1688 driver\n"));
- audio_flags = DMA_AUTOMODE;
- format_mask |= AFMT_S16_LE;
- driver = &ess_audio_driver;
+ driver = ess_audio_init (devc, &audio_flags, &format_mask);
break;
case MDL_SB16:
@@ -1355,17 +1106,17 @@
driver = &sbpro_audio_driver;
}
- if ((devc->my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
+ if ((devc->dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
name,driver, sizeof(struct audio_driver),
audio_flags, format_mask, devc,
devc->dma8,
- devc->duplex ? devc->dma16 : devc->dma8) < 0))
+ devc->duplex ? devc->dma16 : devc->dma8)) < 0)
{
printk(KERN_ERR "Sound Blaster: unable to install audio.\n");
return;
}
- audio_devs[devc->my_dev]->mixer_dev = devc->my_mixerdev;
- audio_devs[devc->my_dev]->min_fragment = 5;
+ audio_devs[devc->dev]->mixer_dev = devc->my_mixerdev;
+ audio_devs[devc->dev]->min_fragment = 5;
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov