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; }