/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of 16-bit SoundBlaster cards and clones
* Note: This is very ugly hardware which uses one 8-bit DMA channel and
* second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't
*
*/
-#include <sound/driver.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/init.h>
#include <sound/control.h>
#include <sound/info.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones");
MODULE_LICENSE("GPL");
#ifdef CONFIG_SND_SB16_CSP
-static void snd_sb16_csp_playback_prepare(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
{
if (chip->hardware == SB_HW_16CSP) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
/* manually loaded codec */
}
}
-static void snd_sb16_csp_capture_prepare(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
{
if (chip->hardware == SB_HW_16CSP) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
/* manually loaded codec */
}
}
-static void snd_sb16_csp_update(sb_t *chip)
+static void snd_sb16_csp_update(struct snd_sb *chip)
{
if (chip->hardware == SB_HW_16CSP) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->qpos_changed) {
spin_lock(&chip->reg_lock);
}
}
-static void snd_sb16_csp_playback_open(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
{
/* CSP decoders (QSound excluded) support only 16bit transfers */
if (chip->hardware == SB_HW_16CSP) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
/* manually loaded codec */
}
}
-static void snd_sb16_csp_playback_close(sb_t *chip)
+static void snd_sb16_csp_playback_close(struct snd_sb *chip)
{
if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->ops.csp_stop(csp) == 0) {
csp->ops.csp_unuse(csp);
}
}
-static void snd_sb16_csp_capture_open(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
{
/* CSP coders support only 16bit transfers */
if (chip->hardware == SB_HW_16CSP) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
/* manually loaded codec */
}
}
-static void snd_sb16_csp_capture_close(sb_t *chip)
+static void snd_sb16_csp_capture_close(struct snd_sb *chip)
{
if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) {
- snd_sb_csp_t *csp = chip->csp;
+ struct snd_sb_csp *csp = chip->csp;
if (csp->ops.csp_stop(csp) == 0) {
csp->ops.csp_unuse(csp);
#endif
-static void snd_sb16_setup_rate(sb_t *chip,
+static void snd_sb16_setup_rate(struct snd_sb *chip,
unsigned short rate,
int channel)
{
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
-static int snd_sb16_hw_params(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_sb16_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
}
-static int snd_sb16_hw_free(snd_pcm_substream_t * substream)
+static int snd_sb16_hw_free(struct snd_pcm_substream *substream)
{
snd_pcm_lib_free_pages(substream);
return 0;
}
-static int snd_sb16_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
{
unsigned long flags;
- sb_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
unsigned char format;
unsigned int size, count, dma;
return 0;
}
-static int snd_sb16_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
int cmd)
{
- sb_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
int result = 0;
spin_lock(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
chip->mode |= SB_RATE_LOCK_PLAYBACK;
snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
if (chip->mode & SB_RATE_LOCK_CAPTURE)
return result;
}
-static int snd_sb16_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
{
unsigned long flags;
- sb_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
unsigned char format;
unsigned int size, count, dma;
return 0;
}
-static int snd_sb16_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
int cmd)
{
- sb_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
int result = 0;
spin_lock(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
chip->mode |= SB_RATE_LOCK_CAPTURE;
snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
if (chip->mode & SB_RATE_LOCK_PLAYBACK)
return result;
}
-irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
{
- sb_t *chip = dev_id;
+ struct snd_sb *chip = dev_id;
unsigned char status;
int ok;
status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
spin_unlock(&chip->mixer_lock);
if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
- chip->rmidi_callback(irq, chip->rmidi->private_data, regs);
+ chip->rmidi_callback(irq, chip->rmidi->private_data);
if (status & SB_IRQTYPE_8BIT) {
ok = 0;
if (chip->mode & SB_MODE_PLAYBACK_8) {
*/
-static snd_pcm_uframes_t snd_sb16_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream)
{
- sb_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
unsigned int dma;
size_t ptr;
return bytes_to_frames(substream->runtime, ptr);
}
-static snd_pcm_uframes_t snd_sb16_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream)
{
- sb_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
unsigned int dma;
size_t ptr;
*/
-static snd_pcm_hardware_t snd_sb16_playback =
+static struct snd_pcm_hardware snd_sb16_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
.fifo_size = 0,
};
-static snd_pcm_hardware_t snd_sb16_capture =
+static struct snd_pcm_hardware snd_sb16_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
* open/close
*/
-static int snd_sb16_playback_open(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
{
unsigned long flags;
- sb_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
spin_lock_irqsave(&chip->open_lock, flags);
if (chip->mode & SB_MODE_PLAYBACK) {
__open_ok:
if (chip->hardware == SB_HW_ALS100)
runtime->hw.rate_max = 48000;
+ if (chip->hardware == SB_HW_CS5530) {
+ runtime->hw.buffer_bytes_max = 32 * 1024;
+ runtime->hw.periods_min = 2;
+ runtime->hw.rate_min = 44100;
+ }
if (chip->mode & SB_RATE_LOCK)
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
chip->playback_substream = substream;
return 0;
}
-static int snd_sb16_playback_close(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
{
unsigned long flags;
- sb_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
snd_sb16_csp_playback_close(chip);
spin_lock_irqsave(&chip->open_lock, flags);
return 0;
}
-static int snd_sb16_capture_open(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
{
unsigned long flags;
- sb_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
spin_lock_irqsave(&chip->open_lock, flags);
if (chip->mode & SB_MODE_CAPTURE) {
__open_ok:
if (chip->hardware == SB_HW_ALS100)
runtime->hw.rate_max = 48000;
+ if (chip->hardware == SB_HW_CS5530) {
+ runtime->hw.buffer_bytes_max = 32 * 1024;
+ runtime->hw.periods_min = 2;
+ runtime->hw.rate_min = 44100;
+ }
if (chip->mode & SB_RATE_LOCK)
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
chip->capture_substream = substream;
return 0;
}
-static int snd_sb16_capture_close(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
{
unsigned long flags;
- sb_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_sb *chip = snd_pcm_substream_chip(substream);
snd_sb16_csp_capture_close(chip);
spin_lock_irqsave(&chip->open_lock, flags);
* DMA control interface
*/
-static int snd_sb16_set_dma_mode(sb_t *chip, int what)
+static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what)
{
if (chip->dma8 < 0 || chip->dma16 < 0) {
snd_assert(what == 0, return -EINVAL);
return 0;
}
-static int snd_sb16_get_dma_mode(sb_t *chip)
+static int snd_sb16_get_dma_mode(struct snd_sb *chip)
{
if (chip->dma8 < 0 || chip->dma16 < 0)
return 0;
}
}
-static int snd_sb16_dma_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
static char *texts[3] = {
"Auto", "Playback", "Capture"
return 0;
}
-static int snd_sb16_dma_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *chip = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
spin_lock_irqsave(&chip->reg_lock, flags);
return 0;
}
-static int snd_sb16_dma_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *chip = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
unsigned char nval, oval;
int change;
return change;
}
-static snd_kcontrol_new_t snd_sb16_dma_control = {
+static struct snd_kcontrol_new snd_sb16_dma_control = {
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.name = "16-bit DMA Allocation",
.info = snd_sb16_dma_control_info,
* Initialization part
*/
-int snd_sb16dsp_configure(sb_t * chip)
+int snd_sb16dsp_configure(struct snd_sb * chip)
{
unsigned long flags;
unsigned char irqreg = 0, dmareg = 0, mpureg;
return 0;
}
-static snd_pcm_ops_t snd_sb16_playback_ops = {
+static struct snd_pcm_ops snd_sb16_playback_ops = {
.open = snd_sb16_playback_open,
.close = snd_sb16_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.pointer = snd_sb16_playback_pointer,
};
-static snd_pcm_ops_t snd_sb16_capture_ops = {
+static struct snd_pcm_ops snd_sb16_capture_ops = {
.open = snd_sb16_capture_open,
.close = snd_sb16_capture_close,
.ioctl = snd_pcm_lib_ioctl,
.pointer = snd_sb16_capture_pointer,
};
-int snd_sb16dsp_pcm(sb_t * chip, int device, snd_pcm_t ** rpcm)
+int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm)
{
- snd_card_t *card = chip->card;
- snd_pcm_t *pcm;
+ struct snd_card *card = chip->card;
+ struct snd_pcm *pcm;
int err;
if (rpcm)
return 0;
}
-const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction)
+const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction)
{
return direction == SNDRV_PCM_STREAM_PLAYBACK ?
&snd_sb16_playback_ops : &snd_sb16_capture_ops;