Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7dfb2d40 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: emu10k1 - delay the PCM interrupts (add pcm_irq_delay parameter)
  ALSA: hda - Fix ALC680 base model capture
  ASoC: Remove DSP mode support for WM8776
  ALSA: hda - Add quirk for Dell Vostro 1220
  ALSA: riptide - Fix detection / load of firmware files
parents 6c8bfb7f 2ea1ef57
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1707,6 +1707,7 @@ struct snd_emu10k1 {
	unsigned int card_type;			/* EMU10K1_CARD_* */
	unsigned int card_type;			/* EMU10K1_CARD_* */
	unsigned int ecard_ctrl;		/* ecard control bits */
	unsigned int ecard_ctrl;		/* ecard control bits */
	unsigned long dma_mask;			/* PCI DMA mask */
	unsigned long dma_mask;			/* PCI DMA mask */
	unsigned int delay_pcm_irq;		/* in samples */
	int max_cache_pages;			/* max memory size / PAGE_SIZE */
	int max_cache_pages;			/* max memory size / PAGE_SIZE */
	struct snd_dma_buffer silent_page;	/* silent page */
	struct snd_dma_buffer silent_page;	/* silent page */
	struct snd_dma_buffer ptb_pages;	/* page table pages */
	struct snd_dma_buffer ptb_pages;	/* page table pages */
+4 −0
Original line number Original line Diff line number Diff line
@@ -978,6 +978,10 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
{
{
	if (substream->runtime->trigger_master != substream)
	if (substream->runtime->trigger_master != substream)
		return 0;
		return 0;
	/* some drivers might use hw_ptr to recover from the pause -
	   update the hw_ptr now */
	if (push)
		snd_pcm_update_hw_ptr(substream);
	/* The jiffies check in snd_pcm_update_hw_ptr*() is done by
	/* The jiffies check in snd_pcm_update_hw_ptr*() is done by
	 * a delta betwen the current jiffies, this gives a large enough
	 * a delta betwen the current jiffies, this gives a large enough
	 * delta, effectively to skip the check once.
	 * delta, effectively to skip the check once.
+4 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
static int enable_ir[SNDRV_CARDS];
static int enable_ir[SNDRV_CARDS];
static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};


module_param_array(index, int, NULL, 0444);
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
@@ -73,6 +74,8 @@ module_param_array(enable_ir, bool, NULL, 0444);
MODULE_PARM_DESC(enable_ir, "Enable IR.");
MODULE_PARM_DESC(enable_ir, "Enable IR.");
module_param_array(subsystem, uint, NULL, 0444);
module_param_array(subsystem, uint, NULL, 0444);
MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
module_param_array(delay_pcm_irq, uint, NULL, 0444);
MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0).");
/*
/*
 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value  Model:SB0400
 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value  Model:SB0400
 */
 */
@@ -127,6 +130,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
				      &emu)) < 0)
				      &emu)) < 0)
		goto error;
		goto error;
	card->private_data = emu;
	card->private_data = emu;
	emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
	if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
	if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
		goto error;
		goto error;
	if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
	if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
+26 −4
Original line number Original line Diff line number Diff line
@@ -332,7 +332,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
		evoice->epcm->ccca_start_addr = start_addr + ccis;
		evoice->epcm->ccca_start_addr = start_addr + ccis;
		if (extra) {
		if (extra) {
			start_addr += ccis;
			start_addr += ccis;
			end_addr += ccis;
			end_addr += ccis + emu->delay_pcm_irq;
		}
		}
		if (stereo && !extra) {
		if (stereo && !extra) {
			snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
			snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
@@ -360,7 +360,9 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
	/* Assumption that PT is already 0 so no harm overwriting */
	/* Assumption that PT is already 0 so no harm overwriting */
	snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
	snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
	snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
	snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
	snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
	snd_emu10k1_ptr_write(emu, PSST, voice,
			(start_addr + (extra ? emu->delay_pcm_irq : 0)) |
			(send_amount[2] << 24));
	if (emu->card_capabilities->emu_model)
	if (emu->card_capabilities->emu_model)
		pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
		pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
	else 
	else 
@@ -732,6 +734,23 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
	snd_emu10k1_ptr_write(emu, IP, voice, 0);
	snd_emu10k1_ptr_write(emu, IP, voice, 0);
}
}


static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
		struct snd_emu10k1_pcm *epcm,
		struct snd_pcm_substream *substream,
		struct snd_pcm_runtime *runtime)
{
	unsigned int ptr, period_pos;

	/* try to sychronize the current position for the interrupt
	   source voice */
	period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt;
	period_pos %= runtime->period_size;
	ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number);
	ptr &= ~0x00ffffff;
	ptr |= epcm->ccca_start_addr + period_pos;
	snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr);
}

static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
				        int cmd)
				        int cmd)
{
{
@@ -753,6 +772,8 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
		/* follow thru */
		/* follow thru */
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_RESUME:
		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
			snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
		mix = &emu->pcm_mixer[substream->number];
		mix = &emu->pcm_mixer[substream->number];
		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
@@ -869,8 +890,9 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
#endif
#endif
	/*
	/*
	printk(KERN_DEBUG
	printk(KERN_DEBUG
	       "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n",
	       "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n",
	       ptr, runtime->buffer_size, runtime->period_size);
	       (long)ptr, (long)runtime->buffer_size,
	       (long)runtime->period_size);
	*/
	*/
	return ptr;
	return ptr;
}
}
+3 −1
Original line number Original line Diff line number Diff line
@@ -310,8 +310,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
	if (snd_BUG_ON(!hdr))
	if (snd_BUG_ON(!hdr))
		return NULL;
		return NULL;


	idx = runtime->period_size >= runtime->buffer_size ?
					(emu->delay_pcm_irq * 2) : 0;
	mutex_lock(&hdr->block_mutex);
	mutex_lock(&hdr->block_mutex);
	blk = search_empty(emu, runtime->dma_bytes);
	blk = search_empty(emu, runtime->dma_bytes + idx);
	if (blk == NULL) {
	if (blk == NULL) {
		mutex_unlock(&hdr->block_mutex);
		mutex_unlock(&hdr->block_mutex);
		return NULL;
		return NULL;
Loading