Ejemplo n.º 1
0
static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
{
    struct pcxhr_rmh rmh;
    unsigned int mask, reg;
    unsigned int codec;
    int err, use_src, changed;

    switch (chip->chip_idx) {
    case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
    case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
    case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
    case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
    default: return -EINVAL;
    }
    reg = 0;    /* audio source from analog plug */
    use_src = 0;    /* do not activate codec SRC */

    if (chip->audio_capture_source != 0) {
        reg = mask;    /* audio source from digital plug */
        if (chip->audio_capture_source == 2)
            use_src = 1;
    }
    /* set the input source */
    pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
    /* resync them (otherwise channel inversion possible) */
    if (changed) {
        pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
        rmh.cmd[0] |= (1 << chip->chip_idx);
        err = pcxhr_send_msg(chip->mgr, &rmh);
        if (err)
            return err;
    }
    pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);    /* set codec SRC on off */
    rmh.cmd_len = 3;
    rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
    rmh.cmd[1] = codec;
    rmh.cmd[2] = (CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x54);
    err = pcxhr_send_msg(chip->mgr, &rmh);
    if(err)
        return err;
    rmh.cmd[2] = (CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x49);
    err = pcxhr_send_msg(chip->mgr, &rmh);
    return err;
}
void pcxhr_reset_board(struct pcxhr_mgr *mgr)
{
	struct pcxhr_rmh rmh;

	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
		/* mute outputs */
		/* a read to IO_NUM_REG_MUTE_OUT register unmutes! */
		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
		rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
		pcxhr_send_msg(mgr, &rmh);
		/* mute inputs */
		pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 0, NULL);
	}
	/* reset pcxhr dsp */
	if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
		pcxhr_reset_dsp(mgr);
	/* reset second xilinx */
	if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_XLX_COM_INDEX))
		pcxhr_reset_xilinx_com(mgr);
	return;
}
static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
{
	struct pcxhr_rmh rmh;
	unsigned int mask, reg;
	unsigned int codec;
	int err, changed;

	switch (chip->chip_idx) {
	case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
	case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
	case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
	case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
	default: return -EINVAL;
	}
	if (chip->audio_capture_source != 0) {
		reg = mask;	
	} else {
		reg = 0;	
	}
	
	pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
	
	if (changed) {
		pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
		rmh.cmd[0] |= (1 << chip->chip_idx);
		err = pcxhr_send_msg(chip->mgr, &rmh);
		if (err)
			return err;
	}
	if (chip->mgr->board_aes_in_192k) {
		int i;
		unsigned int src_config = 0xC0;
		
		for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
			if (chip->mgr->chip[i]->audio_capture_source == 2)
				src_config |= (1 << (3 - i));
		}
		
		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
		rmh.cmd_len = 2;
		rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
		rmh.cmd[1] = src_config;
		err = pcxhr_send_msg(chip->mgr, &rmh);
	} else {
		int use_src = 0;
		if (chip->audio_capture_source == 2)
			use_src = 1;
		
		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
		rmh.cmd_len = 3;
		rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
		rmh.cmd[1] = codec;
		rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
			      (use_src ? 0x41 : 0x54));
		err = pcxhr_send_msg(chip->mgr, &rmh);
		if (err)
			return err;
		rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
			      (use_src ? 0x41 : 0x49));
		err = pcxhr_send_msg(chip->mgr, &rmh);
	}
	return err;
}
static int pcxhr_init_board(struct pcxhr_mgr *mgr)
{
	int err;
	struct pcxhr_rmh rmh;
	int card_streams;

	/* calc the number of all streams used */
	if (mgr->mono_capture)
		card_streams = mgr->capture_chips * 2;
	else
		card_streams = mgr->capture_chips;
	card_streams += mgr->playback_chips * PCXHR_PLAYBACK_STREAMS;

	/* enable interrupts */
	pcxhr_enable_dsp(mgr);

	pcxhr_init_rmh(&rmh, CMD_SUPPORTED);
	err = pcxhr_send_msg(mgr, &rmh);
	if (err)
		return err;
	/* test 8 or 12 phys out */
	snd_assert((rmh.stat[0] & MASK_FIRST_FIELD) == mgr->playback_chips*2,
		   return -EINVAL);
	/* test 8 or 2 phys in */
	snd_assert(((rmh.stat[0] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD) ==
		   mgr->capture_chips * 2, return -EINVAL);
	/* test max nb substream per board */
	snd_assert((rmh.stat[1] & 0x5F) >= card_streams, return -EINVAL);
	/* test max nb substream per pipe */
	snd_assert(((rmh.stat[1]>>7)&0x5F) >= PCXHR_PLAYBACK_STREAMS, return -EINVAL);

	pcxhr_init_rmh(&rmh, CMD_VERSION);
	/* firmware num for DSP */
	rmh.cmd[0] |= mgr->firmware_num;
	/* transfer granularity in samples (should be multiple of 48) */
	rmh.cmd[1] = (1<<23) + PCXHR_GRANULARITY;
	rmh.cmd_len = 2;
	err = pcxhr_send_msg(mgr, &rmh);
	if (err)
		return err;
	snd_printdd("PCXHR DSP version is %d.%d.%d\n",
		    (rmh.stat[0]>>16)&0xff, (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
	mgr->dsp_version = rmh.stat[0];

	/* get options */
	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
	rmh.cmd[0] |= IO_NUM_REG_STATUS;
	rmh.cmd[1]  = REG_STATUS_OPTIONS;
	rmh.cmd_len = 2;
	err = pcxhr_send_msg(mgr, &rmh);
	if (err)
		return err;

	if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == REG_STATUS_OPT_ANALOG_BOARD)
		mgr->board_has_analog = 1;	/* analog addon board available */
	else
		/* analog addon board not available -> no support for instance */
		return -EINVAL;	

	/* unmute inputs */
	err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
					  REG_CONT_UNMUTE_INPUTS, NULL);
	if (err)
		return err;
	/* unmute outputs */
	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* a write to IO_NUM_REG_MUTE_OUT mutes! */
	rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
	err = pcxhr_send_msg(mgr, &rmh);
	return err;
}