Exemplo n.º 1
0
static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream,
				    unsigned int offset,
				    unsigned int addr,
				    unsigned int count)
{
	struct snd_gf1_dma_block block;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct gus_pcm_private *pcmp = runtime->private_data;

	count += offset & 31;
	offset &= ~31;
	/*
	snd_printk(KERN_DEBUG "block change - offset = 0x%x, count = 0x%x\n",
		   offset, count);
	*/
	memset(&block, 0, sizeof(block));
	block.cmd = SNDRV_GF1_DMA_IRQ;
	if (snd_pcm_format_unsigned(runtime->format))
		block.cmd |= SNDRV_GF1_DMA_UNSIGNED;
	if (snd_pcm_format_width(runtime->format) == 16)
		block.cmd |= SNDRV_GF1_DMA_16BIT;
	block.addr = addr & ~31;
	block.buffer = runtime->dma_area + offset;
	block.buf_addr = runtime->dma_addr + offset;
	block.count = count;
	block.private_data = pcmp;
	block.ack = snd_gf1_pcm_block_change_ack;
	if (!snd_gf1_dma_transfer_block(pcmp->gus, &block, 0, 0))
		atomic_inc(&pcmp->dma_count);
	return 0;
}
Exemplo n.º 2
0
static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
{
	unsigned int CTRL;
	struct snd_pcm_runtime *runtime = substream->runtime;

	/* set ctrl mode
	   CTRL default: 8-bit (unsigned) mono, loop mode enabled
	 */
	CTRL = 0x00000001;
	if (snd_pcm_format_width(runtime->format) == 16)
		CTRL |= 0x00000008;	/* 16-bit data */
	if (!snd_pcm_format_unsigned(runtime->format))
		CTRL |= 0x00000002;	/* signed data */
	if (runtime->channels > 1)
		CTRL |= 0x00000004;	/* stereo data */
	return CTRL;
}
Exemplo n.º 3
0
/*
 * pdacf_pcm_prepare - prepare callback for playback and capture
 */
static int pdacf_pcm_prepare(struct snd_pcm_substream *subs)
{
    struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
    struct snd_pcm_runtime *runtime = subs->runtime;
    u16 val, nval, aval;

    if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
        return -EBUSY;

    chip->pcm_channels = runtime->channels;

    chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0;
#ifdef SNDRV_LITTLE_ENDIAN
    chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0;
#else
    chip->pcm_swab = chip->pcm_little;
#endif

    if (snd_pcm_format_unsigned(runtime->format))
        chip->pcm_xor = 0x80008000;

    if (pdacf_pcm_clear_sram(chip) < 0)
        return -EIO;
    
    val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
    nval &= ~(PDAUDIOCF_DATAFMT0|PDAUDIOCF_DATAFMT1);
    switch (runtime->format) {
    case SNDRV_PCM_FORMAT_S16_LE:
    case SNDRV_PCM_FORMAT_S16_BE:
        break;
    default: /* 24-bit */
        nval |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1;
        break;
    }
    aval = 0;
    chip->pcm_sample = 4;
    switch (runtime->format) {
    case SNDRV_PCM_FORMAT_S16_LE:
    case SNDRV_PCM_FORMAT_S16_BE:
        aval = AK4117_DIF_16R;
        chip->pcm_frame = 2;
        chip->pcm_sample = 2;
        break;
    case SNDRV_PCM_FORMAT_S24_3LE:
    case SNDRV_PCM_FORMAT_S24_3BE:
        chip->pcm_sample = 3;
        /* fall through */
    default: /* 24-bit */
        aval = AK4117_DIF_24R;
        chip->pcm_frame = 3;
        chip->pcm_xor &= 0xffff0000;
        break;
    }

    if (val != nval) {
        snd_ak4117_reg_write(chip->ak4117, AK4117_REG_IO, AK4117_DIF2|AK4117_DIF1|AK4117_DIF0, aval);
        pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval);
    }

    val = pdacf_reg_read(chip,  PDAUDIOCF_REG_IER);
    val &= ~(PDAUDIOCF_IRQLVLEN1);
    val |= PDAUDIOCF_IRQLVLEN0;
    pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val);

    chip->pcm_size = runtime->buffer_size;
    chip->pcm_period = runtime->period_size;
    chip->pcm_area = runtime->dma_area;

    return 0;
}
Exemplo n.º 4
0
static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const snd_pcm_format_mask_t *format_mask)
{
	int w, w1, u, e;
	snd_pcm_format_t f;
	snd_pcm_format_mask_t lin = { SND_PCM_FMTBIT_LINEAR };
	snd_pcm_format_mask_t fl = {
#ifdef BUILD_PCM_PLUGIN_LFLOAT
		SND_PCM_FMTBIT_FLOAT
#else
		{ 0 }
#endif
	};
	if (snd_pcm_format_mask_test(format_mask, format))
		return format;
	if (!snd_pcm_format_mask_test(&lin, format) &&
	    !snd_pcm_format_mask_test(&fl, format)) {
		unsigned int i;
		switch (format) {
#ifdef BUILD_PCM_PLUGIN_MULAW
		case SND_PCM_FORMAT_MU_LAW:
#endif
#ifdef BUILD_PCM_PLUGIN_ALAW
		case SND_PCM_FORMAT_A_LAW:
#endif
#ifdef BUILD_PCM_PLUGIN_ADPCM
		case SND_PCM_FORMAT_IMA_ADPCM:
#endif
			for (i = 0; i < sizeof(linear_preferred_formats) / sizeof(linear_preferred_formats[0]); ++i) {
				snd_pcm_format_t f = linear_preferred_formats[i];
				if (snd_pcm_format_mask_test(format_mask, f))
					return f;
			}
			/* Fall through */
		default:
			return SND_PCM_FORMAT_UNKNOWN;
		}

	}
	snd_mask_intersect(&lin, format_mask);
	snd_mask_intersect(&fl, format_mask);
	if (snd_mask_empty(&lin) && snd_mask_empty(&fl)) {
#ifdef BUILD_PCM_NONLINEAR
		unsigned int i;
		for (i = 0; i < sizeof(nonlinear_preferred_formats) / sizeof(nonlinear_preferred_formats[0]); ++i) {
			snd_pcm_format_t f = nonlinear_preferred_formats[i];
			if (snd_pcm_format_mask_test(format_mask, f))
				return f;
		}
#endif
		return SND_PCM_FORMAT_UNKNOWN;
	}
#ifdef BUILD_PCM_PLUGIN_LFLOAT
	if (snd_pcm_format_float(format)) {
		if (snd_pcm_format_mask_test(&fl, format)) {
			unsigned int i;
			for (i = 0; i < sizeof(float_preferred_formats) / sizeof(float_preferred_formats[0]); ++i) {
				snd_pcm_format_t f = float_preferred_formats[i];
				if (snd_pcm_format_mask_test(format_mask, f))
					return f;
			}
		}
		w = 32;
		u = 0;
		e = snd_pcm_format_big_endian(format);
	} else
#endif
	if (snd_mask_empty(&lin)) {
#ifdef BUILD_PCM_PLUGIN_LFLOAT
		unsigned int i;
		for (i = 0; i < sizeof(float_preferred_formats) / sizeof(float_preferred_formats[0]); ++i) {
			snd_pcm_format_t f = float_preferred_formats[i];
			if (snd_pcm_format_mask_test(format_mask, f))
				return f;
		}
#endif
		return SND_PCM_FORMAT_UNKNOWN;
	} else {
		w = snd_pcm_format_width(format);
		u = snd_pcm_format_unsigned(format);
		e = snd_pcm_format_big_endian(format);
	}
	for (w1 = w; w1 <= 32; w1++) {
		f = check_linear_format(format_mask, w1, u, e);
		if (f != SND_PCM_FORMAT_UNKNOWN)
			return f;
	}
	for (w1 = w - 1; w1 > 0; w1--) {
		f = check_linear_format(format_mask, w1, u, e);
		if (f != SND_PCM_FORMAT_UNKNOWN)
			return f;
	}
	return SND_PCM_FORMAT_UNKNOWN;
}