コード例 #1
0
ファイル: spi-pxa2xx-dma.c プロジェクト: AshishNamdev/linux
int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
					   struct spi_device *spi,
					   u8 bits_per_word, u32 *burst_code,
					   u32 *threshold)
{
	struct pxa2xx_spi_chip *chip_info = spi->controller_data;

	/*
	 * If the DMA burst size is given in chip_info we use that,
	 * otherwise we use the default. Also we use the default FIFO
	 * thresholds for now.
	 */
	*burst_code = chip_info ? chip_info->dma_burst_size : 1;
	*threshold = SSCR1_RxTresh(RX_THRESH_DFLT)
		   | SSCR1_TxTresh(TX_THRESH_DFLT);

	return 0;
}
コード例 #2
0
/**
 * calculate_sscr1_psp - separate function that calculate sscr1 register
 * @ps_settings : pointer of the settings struct
 *
 * this function is to simplify/clarify set_ssp_i2s_hw function
 *
 * Output parameters
 *      u32 : calculated SSCR1 register
 */
u32 calculate_sscr1_psp(const struct intel_mid_i2s_settings *ps_settings)
{
	u32 sscr1;
	sscr1 = SSCR1_reg(SFRMDIR, ps_settings->sspsfrm_direction)
		|SSCR1_reg(SCLKDIR, ps_settings->sspslclk_direction)
		|SSCR1_reg(TTELP, ps_settings->tx_tristate_phase)
		|SSCR1_reg(TTE,	ps_settings->tx_tristate_enable)
		|SSCR1_reg(TRAIL, ps_settings->ssp_trailing_byte_mode)
		|SSCR1_reg(TINTE, ps_settings->ssp_rx_timeout_interrupt_status)
		|SSCR1_reg(PINTE,
			ps_settings->ssp_trailing_byte_interrupt_status)
		|SSCR1_reg(LBM,	ps_settings->ssp_loopback_mode_status)
		|SSCR1_reg(RWOT, ps_settings->ssp_duplex_mode)
		|SSCR1_reg(RFT,
			SSCR1_RxTresh(ps_settings->ssp_rx_fifo_threshold))
		|SSCR1_reg(TFT,
			SSCR1_TxTresh(ps_settings->ssp_tx_fifo_threshold));
	return sscr1;
}
コード例 #3
0
/*
 * Set up the SSP DAI format.
 * The SSP Port must be inactive before calling this function as the
 * physical interface format is changed.
 */
static int pxa3xx_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
		unsigned int fmt)
{
	struct ssp_device *ssp = cpu_dai->private_data;
	int dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
	u32 sscr0, sscr1, sspsp;

	sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
	if (sscr0 & SSCR0_SSE)
		return 0;

	ssp_clk[cpu_dai->id].dai_fmt = dai_fmt;

	/*
	 * reset port settings
	 * PXA3xx docs say to use RxThresh = 8 and TxThresh = 7 with
	 * DMA bursts of 32
	 */
	__raw_writel(0, ssp->mmio_base + SSCR0);
	sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
	__raw_writel(sscr1, ssp->mmio_base + SSCR1);
	__raw_writel(0, ssp->mmio_base + SSPSP);

	switch (dai_fmt) {
	case SND_SOC_DAIFMT_I2S:
		sscr0 = SSCR0_MOD | SSCR0_PSP;
		__raw_writel(sscr0, ssp->mmio_base + SSCR0);
		sscr1 = __raw_readl(ssp->mmio_base + SSCR1);
		sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
		__raw_writel(sscr1, ssp->mmio_base + SSCR1);

		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			sspsp = __raw_readl(ssp->mmio_base + SSPSP);
			sspsp |= SSPSP_FSRT;
			__raw_writel(sspsp, ssp->mmio_base + SSPSP);
			break;
		case SND_SOC_DAIFMT_NB_IF:
			sspsp = __raw_readl(ssp->mmio_base + SSPSP);
			sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
			__raw_writel(sspsp, ssp->mmio_base + SSPSP);
			break;
		case SND_SOC_DAIFMT_IB_IF:
			sspsp = __raw_readl(ssp->mmio_base + SSPSP);
			sspsp |= SSPSP_SFRMP;
			__raw_writel(sspsp, ssp->mmio_base + SSPSP);
			break;
		default:
			return -EINVAL;
		}
		break;
	case SND_SOC_DAIFMT_DSP_A:
	case SND_SOC_DAIFMT_DSP_B:
		sscr0 = SSCR0_MOD | SSCR0_PSP;
		__raw_writel(sscr0, ssp->mmio_base + SSCR0);
		sscr1 = __raw_readl(ssp->mmio_base + SSCR1);
		sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
		__raw_writel(sscr1, ssp->mmio_base + SSCR1);
		if (dai_fmt == SND_SOC_DAIFMT_DSP_A)
			__raw_writel(SSPSP_FSRT, ssp->mmio_base + SSPSP);

		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			sspsp = __raw_readl(ssp->mmio_base + SSPSP);
			sspsp |= SSPSP_SFRMP;
			__raw_writel(sspsp, ssp->mmio_base + SSPSP);
			break;
		case SND_SOC_DAIFMT_IB_IF:
			break;
		default:
			return -EINVAL;
		}

		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		sscr1 = __raw_readl(ssp->mmio_base + SSCR1);
		sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
		__raw_writel(sscr1, ssp->mmio_base + SSCR1);
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		sscr1 = __raw_readl(ssp->mmio_base + SSCR1);
		sscr1 |= SSCR1_SCLKDIR;
		__raw_writel(sscr1, ssp->mmio_base + SSCR1);
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
コード例 #4
0
int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
        struct spi_device *spi,
        u8 bits_per_word, u32 *burst_code,
        u32 *threshold)
{
    struct pxa2xx_spi_chip *chip_info =
        (struct pxa2xx_spi_chip *)spi->controller_data;
    int bytes_per_word;
    int burst_bytes;
    int thresh_words;
    int req_burst_size;
    int retval = 0;

    /* Set the threshold (in registers) to equal the same amount of data
     * as represented by burst size (in bytes).  The computation below
     * is (burst_size rounded up to nearest 8 byte, word or long word)
     * divided by (bytes/register); the tx threshold is the inverse of
     * the rx, so that there will always be enough data in the rx fifo
     * to satisfy a burst, and there will always be enough space in the
     * tx fifo to accept a burst (a tx burst will overwrite the fifo if
     * there is not enough space), there must always remain enough empty
     * space in the rx fifo for any data loaded to the tx fifo.
     * Whenever burst_size (in bytes) equals bits/word, the fifo threshold
     * will be 8, or half the fifo;
     * The threshold can only be set to 2, 4 or 8, but not 16, because
     * to burst 16 to the tx fifo, the fifo would have to be empty;
     * however, the minimum fifo trigger level is 1, and the tx will
     * request service when the fifo is at this level, with only 15 spaces.
     */

    /* find bytes/word */
    if (bits_per_word <= 8)
        bytes_per_word = 1;
    else if (bits_per_word <= 16)
        bytes_per_word = 2;
    else
        bytes_per_word = 4;

    /* use struct pxa2xx_spi_chip->dma_burst_size if available */
    if (chip_info)
        req_burst_size = chip_info->dma_burst_size;
    else {
        switch (chip->dma_burst_size) {
        default:
            /* if the default burst size is not set,
             * do it now */
            chip->dma_burst_size = DCMD_BURST8;
        case DCMD_BURST8:
            req_burst_size = 8;
            break;
        case DCMD_BURST16:
            req_burst_size = 16;
            break;
        case DCMD_BURST32:
            req_burst_size = 32;
            break;
        }
    }
    if (req_burst_size <= 8) {
        *burst_code = DCMD_BURST8;
        burst_bytes = 8;
    } else if (req_burst_size <= 16) {
        if (bytes_per_word == 1) {
            /* don't burst more than 1/2 the fifo */
            *burst_code = DCMD_BURST8;
            burst_bytes = 8;
            retval = 1;
        } else {
            *burst_code = DCMD_BURST16;
            burst_bytes = 16;
        }
    } else {
        if (bytes_per_word == 1) {
            /* don't burst more than 1/2 the fifo */
            *burst_code = DCMD_BURST8;
            burst_bytes = 8;
            retval = 1;
        } else if (bytes_per_word == 2) {
            /* don't burst more than 1/2 the fifo */
            *burst_code = DCMD_BURST16;
            burst_bytes = 16;
            retval = 1;
        } else {
            *burst_code = DCMD_BURST32;
            burst_bytes = 32;
        }
    }

    thresh_words = burst_bytes / bytes_per_word;

    /* thresh_words will be between 2 and 8 */
    *threshold = (SSCR1_RxTresh(thresh_words) & SSCR1_RFT)
                 | (SSCR1_TxTresh(16-thresh_words) & SSCR1_TFT);

    return retval;
}