static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh) { u32 reg = ED_DSP_TIMED_OUT; int dwloop; if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) { snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg); return -EBUSY; } /* write command */ lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len); /* MicoBlaze gogogo */ lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC); /* wait for device to answer */ for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) { if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) { if (rmh->dsp_stat == 0) reg = lx_dsp_reg_read(chip, eReg_CRM1); else reg = 0; goto polling_successful; } else udelay(1); } snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send_atomic! " "polling failed\n"); polling_successful: if ((reg & ERROR_VALUE) == 0) { /* read response */ if (rmh->stat_len) { snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1)); lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat, rmh->stat_len); } } else snd_printk(LXP "rmh error: %08x\n", reg); /* clear Reg_CSM_MR */ lx_dsp_reg_write(chip, eReg_CSM, 0); switch (reg) { case ED_DSP_TIMED_OUT: snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n"); return -ETIMEDOUT; case ED_DSP_CRASHED: snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n"); return -EAGAIN; } lx_message_dump(rmh); return reg; }
static int lx_init_xilinx_test(struct lx6464es *chip) { u32 reg; dev_dbg(chip->card->dev, "->lx_init_xilinx_test\n"); /* TEST if we have access to Xilinx/MicroBlaze */ lx_dsp_reg_write(chip, eReg_CSM, 0); reg = lx_dsp_reg_read(chip, eReg_CSM); if (reg) { dev_err(chip->card->dev, "Problem: Reg_CSM %x.\n", reg); /* PCI9056_SPACE0_REMAP */ lx_plx_reg_write(chip, ePLX_PCICR, 1); reg = lx_dsp_reg_read(chip, eReg_CSM); if (reg) { dev_err(chip->card->dev, "Error: Reg_CSM %x.\n", reg); return -EAGAIN; /* seems to be appropriate */ } } dev_dbg(chip->card->dev, "Xilinx/MicroBlaze access test successful\n"); return 0; }
static int __devinit lx_init_xilinx_test(struct lx6464es *chip) { u32 reg; snd_printdd("->lx_init_xilinx_test\n"); /* TEST if we have access to Xilinx/MicroBlaze */ lx_dsp_reg_write(chip, eReg_CSM, 0); reg = lx_dsp_reg_read(chip, eReg_CSM); if (reg) { snd_printk(KERN_ERR LXP "Problem: Reg_CSM %x.\n", reg); /* PCI9056_SPACE0_REMAP */ lx_plx_reg_write(chip, ePLX_PCICR, 1); reg = lx_dsp_reg_read(chip, eReg_CSM); if (reg) { snd_printk(KERN_ERR LXP "Error: Reg_CSM %x.\n", reg); return -EAGAIN; /* seems to be appropriate */ } } snd_printd(LXP "Xilinx/MicroBlaze access test successful\n"); return 0; }
/* reset the dsp during initialization */ static int lx_init_xilinx_reset(struct lx6464es *chip) { int i; u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC); dev_dbg(chip->card->dev, "->lx_init_xilinx_reset\n"); /* activate reset of xilinx */ plx_reg &= ~CHIPSC_RESET_XILINX; lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg); msleep(1); lx_plx_reg_write(chip, ePLX_MBOX3, 0); msleep(1); plx_reg |= CHIPSC_RESET_XILINX; lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg); /* deactivate reset of xilinx */ for (i = 0; i != 100; ++i) { u32 reg_mbox3; msleep(10); reg_mbox3 = lx_plx_reg_read(chip, ePLX_MBOX3); if (reg_mbox3) { dev_dbg(chip->card->dev, "xilinx reset done\n"); dev_dbg(chip->card->dev, "xilinx took %d loops\n", i); break; } } /* todo: add some error handling? */ /* clear mr */ lx_dsp_reg_write(chip, eReg_CSM, 0); /* le xilinx ES peut ne pas etre encore pret, on attend. */ msleep(600); return 0; }
/* initialize ethersound */ static int lx_init_ethersound_config(struct lx6464es *chip) { int i; u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES); /* configure 64 io channels */ u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) | (64 << IOCR_INPUTS_OFFSET) | (64 << IOCR_OUTPUTS_OFFSET) | (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET); dev_dbg(chip->card->dev, "->lx_init_ethersound\n"); chip->freq_ratio = FREQ_RATIO_SINGLE_MODE; /* * write it to the card ! * this actually kicks the ES xilinx, the first time since poweron. * the MAC address in the Reg_ADMACESMSB Reg_ADMACESLSB registers * is not ready before this is done, and the bit 2 in Reg_CSES is set. * */ lx_dsp_reg_write(chip, eReg_CONFES, conf_es); for (i = 0; i != 1000; ++i) { if (lx_dsp_reg_read(chip, eReg_CSES) & 4) { dev_dbg(chip->card->dev, "ethersound initialized after %dms\n", i); goto ethersound_initialized; } msleep(1); } dev_warn(chip->card->dev, "ethersound could not be initialized after %dms\n", i); return -ETIMEDOUT; ethersound_initialized: dev_dbg(chip->card->dev, "ethersound initialized\n"); return 0; }