コード例 #1
0
ファイル: atiixp.c プロジェクト: idtek/linux-2.6.11
/* set up slots and formats for SPDIF OUT */
static int snd_atiixp_spdif_prepare(snd_pcm_substream_t *substream)
{
    atiixp_t *chip = snd_pcm_substream_chip(substream);

    spin_lock_irq(&chip->reg_lock);
    if (chip->spdif_over_aclink) {
        unsigned int data;
        /* enable slots 10/11 */
        atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK,
                      ATI_REG_CMD_SPDF_CONFIG_01);
        data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
        data |= ATI_REG_OUT_DMA_SLOT_BIT(10) |
                ATI_REG_OUT_DMA_SLOT_BIT(11);
        data |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
        atiixp_write(chip, OUT_DMA_SLOT, data);
        atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_OUT,
                      substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
                      ATI_REG_CMD_INTERLEAVE_OUT : 0);
    } else {
        atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK, 0);
        atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_SPDF, 0);
    }
    spin_unlock_irq(&chip->reg_lock);
    return 0;
}
コード例 #2
0
ファイル: atiixp.c プロジェクト: varialus/DragonFlyX
static int
atiixp_chan_setformat(kobj_t obj, void *data, uint32_t format)
{
	struct atiixp_chinfo *ch = data;
	struct atiixp_info *sc = ch->parent;
	uint32_t value;

	atiixp_lock(sc);
	if (ch->dir == PCMDIR_REC) {
		value = atiixp_rd(sc, ATI_REG_CMD);
		value &= ~ATI_REG_CMD_INTERLEAVE_IN;
		if ((format & AFMT_32BIT) == 0)
			value |= ATI_REG_CMD_INTERLEAVE_IN;
		atiixp_wr(sc, ATI_REG_CMD, value);
	} else {
		value = atiixp_rd(sc, ATI_REG_OUT_DMA_SLOT);
		value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
		/* We do not have support for more than 2 channels, _yet_. */
		value |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
				ATI_REG_OUT_DMA_SLOT_BIT(4);
		value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
		atiixp_wr(sc, ATI_REG_OUT_DMA_SLOT, value);
		value = atiixp_rd(sc, ATI_REG_CMD);
		value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
		if ((format & AFMT_32BIT) == 0)
			value |= ATI_REG_CMD_INTERLEAVE_OUT;
		atiixp_wr(sc, ATI_REG_CMD, value);
		value = atiixp_rd(sc, ATI_REG_6CH_REORDER);
		value &= ~ATI_REG_6CH_REORDER_EN;
		atiixp_wr(sc, ATI_REG_6CH_REORDER, value);
	}
	ch->fmt = format;
	atiixp_unlock(sc);

	return 0;
}
コード例 #3
0
ファイル: atiixp.c プロジェクト: idtek/linux-2.6.11
/* set up slots and formats for analog OUT */
static int snd_atiixp_playback_prepare(snd_pcm_substream_t *substream)
{
    atiixp_t *chip = snd_pcm_substream_chip(substream);
    unsigned int data;

    spin_lock_irq(&chip->reg_lock);
    data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
    switch (substream->runtime->channels) {
    case 8:
        data |= ATI_REG_OUT_DMA_SLOT_BIT(10) |
                ATI_REG_OUT_DMA_SLOT_BIT(11);
    /* fallthru */
    case 6:
        data |= ATI_REG_OUT_DMA_SLOT_BIT(7) |
                ATI_REG_OUT_DMA_SLOT_BIT(8);
    /* fallthru */
    case 4:
        data |= ATI_REG_OUT_DMA_SLOT_BIT(6) |
                ATI_REG_OUT_DMA_SLOT_BIT(9);
    /* fallthru */
    default:
        data |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
                ATI_REG_OUT_DMA_SLOT_BIT(4);
        break;
    }

    /* set output threshold */
    data |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
    atiixp_write(chip, OUT_DMA_SLOT, data);

    atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_OUT,
                  substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
                  ATI_REG_CMD_INTERLEAVE_OUT : 0);

    /*
     * enable 6 channel re-ordering bit if needed
     */
    atiixp_update(chip, 6CH_REORDER, ATI_REG_6CH_REORDER_EN,
                  substream->runtime->channels >= 6 ? ATI_REG_6CH_REORDER_EN: 0);

    spin_unlock_irq(&chip->reg_lock);
    return 0;
}