Пример #1
0
/*
 * vx_release_pseudo_dma - disable the pseudo-DMA mode
 */
static void vx_release_pseudo_dma(vx_core_t *_chip)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;

	/* Disable DMA and 16-bit accesses */
	chip->regDIALOG &= ~(VXP_DLG_DMAWRITE_SEL_MASK|
			     VXP_DLG_DMAREAD_SEL_MASK|
			     VXP_DLG_DMA16_SEL_MASK);
	vx_outb(chip, DIALOG, chip->regDIALOG);
	/* HREQ pin disabled. */
	vx_outb(chip, ICR, 0);
}
Пример #2
0
/*
 * reset codec bit
 */
static void vxp_reset_codec(vx_core_t *_chip)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;

	/* Set the reset CODEC bit to 1. */
	vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK);
	vx_inb(chip, CDSP);
	snd_vx_delay(_chip, 10);
	/* Set the reset CODEC bit to 0. */
	chip->regCDSP &= ~VXP_CDSP_CODEC_RESET_MASK;
	vx_outb(chip, CDSP, chip->regCDSP);
	vx_inb(chip, CDSP);
	snd_vx_delay(_chip, 1);
}
Пример #3
0
static void vxp_reset_dsp(vx_core_t *_chip)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;

	/* set the reset dsp bit to 1 */
	vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_DSP_RESET_MASK);
	vx_inb(chip, CDSP);
	mdelay(XX_DSP_RESET_WAIT_TIME);
	/* reset the bit */
	chip->regCDSP &= ~VXP_CDSP_DSP_RESET_MASK;
	vx_outb(chip, CDSP, chip->regCDSP);
	vx_inb(chip, CDSP);
	mdelay(XX_DSP_RESET_WAIT_TIME);
}
Пример #4
0
/*
 * reset codec bit
 */
static void vxp_reset_codec(struct vx_core *_chip)
{
	struct snd_vxpocket *chip = to_vxpocket(_chip);

	/* Set the reset CODEC bit to 1. */
	vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK);
	vx_inb(chip, CDSP);
	msleep(10);
	/* Set the reset CODEC bit to 0. */
	chip->regCDSP &= ~VXP_CDSP_CODEC_RESET_MASK;
	vx_outb(chip, CDSP, chip->regCDSP);
	vx_inb(chip, CDSP);
	msleep(1);
}
Пример #5
0
/*
 * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
 * @do_write: 0 = read, 1 = set up for DMA write
 */
static void vx_setup_pseudo_dma(vx_core_t *_chip, int do_write)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;

	/* Interrupt mode and HREQ pin enabled for host transmit / receive data transfers */
	vx_outb(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
	/* Reset the pseudo-dma register */
	vx_inb(chip, ISR);
	vx_outb(chip, ISR, 0);

	/* Select DMA in read/write transfer mode and in 16-bit accesses */
	chip->regDIALOG |= VXP_DLG_DMA16_SEL_MASK;
	chip->regDIALOG |= do_write ? VXP_DLG_DMAWRITE_SEL_MASK : VXP_DLG_DMAREAD_SEL_MASK;
	vx_outb(chip, DIALOG, chip->regDIALOG);

}
Пример #6
0
/*
 * vx_validate_irq - enable/disable IRQ
 */
static void vxp_validate_irq(vx_core_t *_chip, int enable)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;

	/* Set the interrupt enable bit to 1 in CDSP register */
	if (enable)
		chip->regCDSP |= VXP_CDSP_VALID_IRQ_MASK;
	else
		chip->regCDSP &= ~VXP_CDSP_VALID_IRQ_MASK;
	vx_outb(chip, CDSP, chip->regCDSP);
}
Пример #7
0
/*
 * vx_test_and_ack - test and acknowledge interrupt
 *
 * called from irq hander, too
 *
 * spinlock held!
 */
static int vxp_test_and_ack(vx_core_t *_chip)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;

	/* not booted yet? */
	if (! (_chip->chip_status & VX_STAT_XILINX_LOADED))
		return -ENXIO;

	if (! (vx_inb(chip, DIALOG) & VXP_DLG_MEMIRQ_MASK))
		return -EIO;
	
	/* ok, interrupts generated, now ack it */
	/* set ACQUIT bit up and down */
	vx_outb(chip, DIALOG, chip->regDIALOG | VXP_DLG_ACK_MEMIRQ_MASK);
	/* useless read just to spend some time and maintain
	 * the ACQUIT signal up for a while ( a bus cycle )
	 */
	vx_inb(chip, DIALOG);
	vx_outb(chip, DIALOG, chip->regDIALOG & ~VXP_DLG_ACK_MEMIRQ_MASK);

	return 0;
}
/**
 * snd_vx_boot_xilinx - boot up the xilinx interface
 * @boot: the boot record to load
 */
int snd_vx_load_boot_image(vx_core_t *chip, const snd_hwdep_dsp_image_t *boot)
{
	unsigned int i;
	int no_fillup = vx_has_new_dsp(chip);

	/* check the length of boot image */
	snd_assert(boot->length > 0, return -EINVAL);
	snd_assert(boot->length % 3 == 0, return -EINVAL);
	snd_assert(boot->image, return -EINVAL);
#if 0
	{
		/* more strict check */
		unsigned int c = ((u32)boot->image[0] << 16) | ((u32)boot->image[1] << 8) | boot->image[2];
		snd_assert(boot->length == (c + 2) * 3, return -EINVAL);
	}
#endif

	/* reset dsp */
	vx_reset_dsp(chip);
	
	udelay(END_OF_RESET_WAIT_TIME); /* another wait? */

	/* download boot strap */
	for (i = 0; i < 0x600; i += 3) {
		if (i >= boot->length) {
			if (no_fillup)
				break;
			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
				snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
				return -EIO;
			}
			vx_outb(chip, TXH, 0);
			vx_outb(chip, TXM, 0);
			vx_outb(chip, TXL, 0);
		} else {
			unsigned char image[3];
			if (copy_from_user(image, boot->image + i, 3))
				return -EFAULT;
			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
				snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
				return -EIO;
			}
			vx_outb(chip, TXH, image[0]);
			vx_outb(chip, TXM, image[1]);
			vx_outb(chip, TXL, image[2]);
		}
	}
	return 0;
}
Пример #9
0
/**
 * snd_vx_boot_xilinx - boot up the xilinx interface
 * @boot: the boot record to load
 */
int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
{
	unsigned int i;
	int no_fillup = vx_has_new_dsp(chip);

	/* check the length of boot image */
	snd_assert(boot->size > 0, return -EINVAL);
	snd_assert(boot->size % 3 == 0, return -EINVAL);
#if 0
	{
		/* more strict check */
		unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];
		snd_assert(boot->size == (c + 2) * 3, return -EINVAL);
	}
#endif

	/* reset dsp */
	vx_reset_dsp(chip);
	
	udelay(END_OF_RESET_WAIT_TIME); /* another wait? */

	/* download boot strap */
	for (i = 0; i < 0x600; i += 3) {
		if (i >= boot->size) {
			if (no_fillup)
				break;
			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
				snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
				return -EIO;
			}
			vx_outb(chip, TXH, 0);
			vx_outb(chip, TXM, 0);
			vx_outb(chip, TXL, 0);
		} else {
			unsigned char *image = boot->data + i;
			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
				snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
				return -EIO;
			}
			vx_outb(chip, TXH, image[0]);
			vx_outb(chip, TXM, image[1]);
			vx_outb(chip, TXL, image[2]);
		}
	}
	return 0;
}
Пример #10
0
/*
 * vx_load_xilinx_binary - load the xilinx binary image
 * the binary image is the binary array converted from the bitstream file.
 */
static int vxp_load_xilinx_binary(vx_core_t *_chip, const struct firmware *fw)
{
	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
	unsigned int i;
	int c;
	int regCSUER, regRUER;
	unsigned char *image;
	unsigned char data;

	/* Switch to programmation mode */
	chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
	vx_outb(chip, DIALOG, chip->regDIALOG);

	/* Save register CSUER and RUER */
	regCSUER = vx_inb(chip, CSUER);
	regRUER = vx_inb(chip, RUER);

	/* reset HF0 and HF1 */
	vx_outb(chip, ICR, 0);

	/* Wait for answer HF2 equal to 1 */
	snd_printdd(KERN_DEBUG "check ISR_HF2\n");
	if (vx_check_isr(_chip, ISR_HF2, ISR_HF2, 20) < 0)
		goto _error;

	/* set HF1 for loading xilinx binary */
	vx_outb(chip, ICR, ICR_HF1);
	image = fw->data;
	for (i = 0; i < fw->size; i++, image++) {
		data = *image;
		if (vx_wait_isr_bit(_chip, ISR_TX_EMPTY) < 0)
			goto _error;
		vx_outb(chip, TXL, data);
		/* wait for reading */
		if (vx_wait_for_rx_full(_chip) < 0)
			goto _error;
		c = vx_inb(chip, RXL);
		if (c != (int)data)
			snd_printk(KERN_ERR "vxpocket: load xilinx mismatch at %d: 0x%x != 0x%x\n", i, c, (int)data);
        }

	/* reset HF1 */
	vx_outb(chip, ICR, 0);

	/* wait for HF3 */
	if (vx_check_isr(_chip, ISR_HF3, ISR_HF3, 20) < 0)
		goto _error;

	/* read the number of bytes received */
	if (vx_wait_for_rx_full(_chip) < 0)
		goto _error;

	c = (int)vx_inb(chip, RXH) << 16;
	c |= (int)vx_inb(chip, RXM) << 8;
	c |= vx_inb(chip, RXL);

	snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%x\n", c, fw->size);

	vx_outb(chip, ICR, ICR_HF0);

	/* TEMPO 250ms : wait until Xilinx is downloaded */
	snd_vx_delay(_chip, 300);

	/* test magical word */
	if (vx_check_magic(_chip) < 0)
		goto _error;

	/* Restore register 0x0E and 0x0F (thus replacing COR and FCSR) */
	vx_outb(chip, CSUER, regCSUER);
	vx_outb(chip, RUER, regRUER);

	/* Reset the Xilinx's signal enabling IO access */
	chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
	vx_outb(chip, DIALOG, chip->regDIALOG);
	vx_inb(chip, DIALOG);
	snd_vx_delay(_chip, 10);
	chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
	vx_outb(chip, DIALOG, chip->regDIALOG);
	vx_inb(chip, DIALOG);

	/* Reset of the Codec */
	vxp_reset_codec(_chip);
	vx_reset_dsp(_chip);

	return 0;

 _error:
	vx_outb(chip, CSUER, regCSUER);
	vx_outb(chip, RUER, regRUER);
	chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
	vx_outb(chip, DIALOG, chip->regDIALOG);
	return -EIO;
}
Пример #11
0
/*
 * vx_send_msg_nolock - send a DSP message and read back the status
 * @rmh: the rmh record to send and receive
 *
 * returns 0 if successful, or a negative error code.
 * the error code can be VX-specific, retrieved via vx_get_error().
 * 
 * this function doesn't call spinlock at all.
 */
int vx_send_msg_nolock(vx_core_t *chip, struct vx_rmh *rmh)
{
	int i, err;
	
	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;

	if ((err = vx_reset_chk(chip)) < 0) {
		snd_printd(KERN_DEBUG "vx_send_msg: vx_reset_chk error\n");
		return err;
	}

#if 0
	printk(KERN_DEBUG "rmh: cmd = 0x%06x, length = %d, stype = %d\n",
	       rmh->Cmd[0], rmh->LgCmd, rmh->DspStat);
	if (rmh->LgCmd > 1) {
		printk(KERN_DEBUG "  ");
		for (i = 1; i < rmh->LgCmd; i++)
			printk("0x%06x ", rmh->Cmd[i]);
		printk("\n");
	}
#endif
	/* Check bit M is set according to length of the command */
	if (rmh->LgCmd > 1)
		rmh->Cmd[0] |= MASK_MORE_THAN_1_WORD_COMMAND;
	else
		rmh->Cmd[0] &= MASK_1_WORD_COMMAND;

	/* Wait for TX empty */
	if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
		snd_printd(KERN_DEBUG "vx_send_msg: wait tx empty error\n");
		return err;
	}

	/* Write Cmd[0] */
	vx_outb(chip, TXH, (rmh->Cmd[0] >> 16) & 0xff);
	vx_outb(chip, TXM, (rmh->Cmd[0] >> 8) & 0xff);
	vx_outb(chip, TXL, rmh->Cmd[0] & 0xff);

	/* Trigger irq MESSAGE */
	if ((err = vx_send_irq_dsp(chip, IRQ_MESSAGE)) < 0) {
		snd_printd(KERN_DEBUG "vx_send_msg: send IRQ_MESSAGE error\n");
		return err;
	}

	/* Wait for CHK = 1 */
	if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
		return err;

	/* If error, get error value from RX */
	if (vx_inb(chip, ISR) & ISR_ERR) {
		if ((err = vx_wait_for_rx_full(chip)) < 0) {
			snd_printd(KERN_DEBUG "vx_send_msg: rx_full read error\n");
			return err;
		}
		err = vx_inb(chip, RXH) << 16;
		err |= vx_inb(chip, RXM) << 8;
		err |= vx_inb(chip, RXL);
		snd_printd(KERN_DEBUG "msg got error = 0x%x at cmd[0]\n", err);
		err = -(VX_ERR_MASK | err);
		return err;
	}

	/* Send the other words */
	if (rmh->LgCmd > 1) {
		for (i = 1; i < rmh->LgCmd; i++) {
			/* Wait for TX ready */
			if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
				snd_printd(KERN_DEBUG "vx_send_msg: tx_ready error\n");
				return err;
			}

			/* Write Cmd[i] */
			vx_outb(chip, TXH, (rmh->Cmd[i] >> 16) & 0xff);
			vx_outb(chip, TXM, (rmh->Cmd[i] >> 8) & 0xff);
			vx_outb(chip, TXL, rmh->Cmd[i] & 0xff);

			/* Trigger irq MESS_READ_NEXT */
			if ((err = vx_send_irq_dsp(chip, IRQ_MESS_READ_NEXT)) < 0) {
				snd_printd(KERN_DEBUG "vx_send_msg: IRQ_READ_NEXT error\n");
				return err;
			}
		}
		/* Wait for TX empty */
		if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
			snd_printd(KERN_DEBUG "vx_send_msg: TX_READY error\n");
			return err;
		}
		/* End of transfer */
		err = vx_transfer_end(chip, IRQ_MESS_READ_END);
		if (err < 0)
			return err;
	}

	return vx_read_status(chip, rmh);
}