/** * mixart_wait_nice_for_register_value - wait for a value on a peudo register, * exit with a timeout * * @mgr: pointer to miXart manager structure * @offset: unsigned pseudo_register base + offset of value * @is_egal: wait for the equal value * @value: value * @timeout: timeout in centisenconds
*/ staticint mixart_wait_nice_for_register_value(struct mixart_mgr *mgr,
u32 offset, int is_egal,
u32 value, unsignedlong timeout)
{ unsignedlong end_time = jiffies + (timeout * HZ / 100);
u32 read;
do { /* we may take too long time in this loop. * so give controls back to kernel if needed.
*/
cond_resched();
read = readl_be( MIXART_MEM( mgr, offset )); if(is_egal) { if(read == value) return 0;
} else { /* wait for different value */ if(read != value) return 0;
}
} while ( time_after_eq(end_time, jiffies) );
err = mixart_enum_connectors(mgr); if (err < 0) return err;
err = mixart_enum_physio(mgr); if (err < 0) return err;
/* send a synchro command to card (necessary to do this before first MSG_STREAM_START_STREAM_GRP_PACKET) */ /* though why not here */
request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
request.uid = (struct mixart_uid){0,0};
request.data = NULL;
request.size = 0; /* this command has no data. response is a 32 bit status */
err = snd_mixart_send_msg(mgr, &request, sizeof(k), &k); if( (err < 0) || (k != 0) ) {
dev_err(&mgr->pci->dev, "error MSG_SYSTEM_SEND_SYNCHRO_CMD\n"); return err == 0 ? -EINVAL : err;
}
return 0;
}
/* firmware base addresses (when hard coded) */ #define MIXART_MOTHERBOARD_XLX_BASE_ADDRESS 0x00600000
staticint mixart_dsp_load(struct mixart_mgr* mgr, int index, conststruct firmware *dsp)
{ int err, card_index;
u32 status_xilinx, status_elf, status_daught;
u32 val;
/* motherboard xilinx status 5 will say that the board is performing a reset */ if (status_xilinx == 5) {
dev_err(&mgr->pci->dev, "miXart is resetting !\n"); return -EAGAIN; /* try again later */
}
switch (index) { case MIXART_MOTHERBOARD_XLX_INDEX:
/* xilinx already loaded ? */ if (status_xilinx == 4) {
dev_dbg(&mgr->pci->dev, "xilinx is already loaded !\n"); return 0;
} /* the status should be 0 == "idle" */ if (status_xilinx != 0) {
dev_err(&mgr->pci->dev, "xilinx load error ! status = %d\n",
status_xilinx); return -EIO; /* modprob -r may help ? */
}
/* check xilinx validity */ if (((u32*)(dsp->data))[0] == 0xffffffff) return -EINVAL; if (dsp->size % 4) return -EINVAL;
/* set xilinx status to copying */
writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
/* the status should be 0 == "idle" */ if (status_elf != 0) {
dev_err(&mgr->pci->dev, "elf load error ! status = %d\n",
status_elf); return -EIO; /* modprob -r may help ? */
}
/* wait for xilinx status == 4 */
err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET, 1, 4, 500); /* 5sec */ if (err < 0) {
dev_err(&mgr->pci->dev, "xilinx was not loaded or " "could not be started\n"); return err;
}
/* init some data on the card */
writel_be( 0, MIXART_MEM( mgr, MIXART_PSEUDOREG_BOARDNUMBER ) ); /* set miXart boardnumber to 0 */
writel_be( 0, MIXART_MEM( mgr, MIXART_FLOWTABLE_PTR ) ); /* reset pointer to flow table on miXart */
/* set elf status to copying */
writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
/* process the copying of the elf packets */
err = mixart_load_elf( mgr, dsp ); if (err < 0) return err;
/* set elf status to copy finished */
writel_be( 2, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
/* wait for elf status == 4 */
err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET, 1, 4, 300); /* 3sec */ if (err < 0) {
dev_err(&mgr->pci->dev, "elf could not be started\n"); return err;
}
/* miXart waits at this point on the pointer to the flow table */
writel_be( (u32)mgr->flowinfo.addr, MIXART_MEM( mgr, MIXART_FLOWTABLE_PTR ) ); /* give pointer of flow table to miXart */
return 0; /* return, another xilinx file has to be loaded before */
case MIXART_AESEBUBOARD_XLX_INDEX: default:
/* elf and xilinx should be loaded */ if (status_elf != 4 || status_xilinx != 4) {
dev_err(&mgr->pci->dev, "xilinx or elf not " "successfully loaded\n"); return -EIO; /* modprob -r may help ? */
}
/* the board type can now be retrieved */
mgr->board_type = (DAUGHTER_TYPE_MASK & readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DBRD_TYPE_OFFSET)));
if (mgr->board_type == MIXART_DAUGHTER_TYPE_NONE) break; /* no daughter board; the file does not have to be loaded, continue after the switch */
/* only if aesebu daughter board presence (elf code must run) */ if (mgr->board_type != MIXART_DAUGHTER_TYPE_AES ) return -EINVAL;
/* daughter should be idle */ if (status_daught != 0) {
dev_err(&mgr->pci->dev, "daughter load error ! status = %d\n",
status_daught); return -EIO; /* modprob -r may help ? */
}
/* check daughterboard xilinx validity */ if (((u32*)(dsp->data))[0] == 0xffffffff) return -EINVAL; if (dsp->size % 4) return -EINVAL;
/* inform mixart about the size of the file */
writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
/* set daughterboard status to 1 */
writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
/* set daughterboard status to 4 */
writel_be( 4, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
/* continue with init */ break;
} /* end of switch file index*/
/* wait for daughter status == 3 */
err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 3, 300); /* 3sec */ if (err < 0) {
dev_err(&mgr->pci->dev, "daughter board could not be initialised\n"); return err;
}
/* init mailbox (communication with embedded) */
snd_mixart_init_mailbox(mgr);
/* first communication with embedded */
err = mixart_first_init(mgr); if (err < 0) {
dev_err(&mgr->pci->dev, "miXart could not be set up\n"); return err;
}
/* create devices and mixer in accordance with HW options*/ for (card_index = 0; card_index < mgr->num_cards; card_index++) { struct snd_mixart *chip = mgr->chip[card_index];
err = snd_mixart_create_pcm(chip); if (err < 0) return err;
if (card_index == 0) {
err = snd_mixart_create_mixer(chip->mgr); if (err < 0) return err;
}
err = snd_card_register(chip->card); if (err < 0) return err;
}
dev_dbg(&mgr->pci->dev, "miXart firmware downloaded and successfully set up\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.