Exemplo n.º 1
0
static int pic32_spi_probe(struct udevice *bus)
{
    struct pic32_spi_priv *priv = dev_get_priv(bus);
    struct dm_spi_bus *dm_spi = dev_get_uclass_priv(bus);
    struct udevice *clkdev;
    fdt_addr_t addr;
    fdt_size_t size;
    int ret;

    debug("%s: %d, bus: %i\n", __func__, __LINE__, bus->seq);
    addr = fdtdec_get_addr_size(gd->fdt_blob, bus->of_offset, "reg", &size);
    if (addr == FDT_ADDR_T_NONE)
        return -EINVAL;

    priv->regs = ioremap(addr, size);
    if (!priv->regs)
        return -EINVAL;

    dm_spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
                                    "spi-max-frequency", 250000000);
    /* get clock rate */
    ret = clk_get_by_index(bus, 0, &clkdev);
    if (ret < 0) {
        printf("pic32-spi: error, clk not found\n");
        return ret;
    }
    priv->clk_rate = clk_get_periph_rate(clkdev, ret);

    /* initialize HW */
    pic32_spi_hw_init(priv);

    /* set word len */
    pic32_spi_set_word_size(priv, SPI_DEFAULT_WORDLEN);

    /* PIC32 SPI controller can automatically drive /CS during transfer
     * depending on fifo fill-level. /CS will stay asserted as long as
     * TX fifo is non-empty, else will be deasserted confirming completion
     * of the ongoing transfer. To avoid this sort of error we will drive
     * /CS manually by toggling cs-gpio pins.
     */
    ret = gpio_request_by_name_nodev(gd->fdt_blob, bus->of_offset,
                                     "cs-gpios", 0,
                                     &priv->cs_gpio, GPIOD_IS_OUT);
    if (ret) {
        printf("pic32-spi: error, cs-gpios not found\n");
        return ret;
    }

    return 0;
}
Exemplo n.º 2
0
static int pic32_spi_prepare_message(struct spi_master *master,
				     struct spi_message *msg)
{
	struct pic32_spi *pic32s = spi_master_get_devdata(master);
	struct spi_device *spi = msg->spi;
	u32 val;

	/* set device specific bits_per_word */
	if (pic32s->bits_per_word != spi->bits_per_word) {
		pic32_spi_set_word_size(pic32s, spi->bits_per_word);
		pic32s->bits_per_word = spi->bits_per_word;
	}

	/* device specific speed change */
	if (pic32s->speed_hz != spi->max_speed_hz) {
		pic32_spi_set_clk_rate(pic32s, spi->max_speed_hz);
		pic32s->speed_hz = spi->max_speed_hz;
	}

	/* device specific mode change */
	if (pic32s->mode != spi->mode) {
		val = readl(&pic32s->regs->ctrl);
		/* active low */
		if (spi->mode & SPI_CPOL)
			val |= CTRL_CKP;
		else
			val &= ~CTRL_CKP;
		/* tx on rising edge */
		if (spi->mode & SPI_CPHA)
			val &= ~CTRL_CKE;
		else
			val |= CTRL_CKE;

		/* rx at end of tx */
		val |= CTRL_SMP;
		writel(val, &pic32s->regs->ctrl);
		pic32s->mode = spi->mode;
	}

	return 0;
}
Exemplo n.º 3
0
static int pic32_spi_one_transfer(struct spi_master *master,
				  struct spi_device *spi,
				  struct spi_transfer *transfer)
{
	struct pic32_spi *pic32s;
	bool dma_issued = false;
	unsigned long timeout;
	int ret;

	pic32s = spi_master_get_devdata(master);

	/* handle transfer specific word size change */
	if (transfer->bits_per_word &&
	    (transfer->bits_per_word != pic32s->bits_per_word)) {
		ret = pic32_spi_set_word_size(pic32s, transfer->bits_per_word);
		if (ret)
			return ret;
		pic32s->bits_per_word = transfer->bits_per_word;
	}

	/* handle transfer specific speed change */
	if (transfer->speed_hz && (transfer->speed_hz != pic32s->speed_hz)) {
		pic32_spi_set_clk_rate(pic32s, transfer->speed_hz);
		pic32s->speed_hz = transfer->speed_hz;
	}

	reinit_completion(&pic32s->xfer_done);

	/* transact by DMA mode */
	if (transfer->rx_sg.nents && transfer->tx_sg.nents) {
		ret = pic32_spi_dma_transfer(pic32s, transfer);
		if (ret) {
			dev_err(&spi->dev, "dma submit error\n");
			return ret;
		}

		/* DMA issued */
		dma_issued = true;
	} else {
		/* set current transfer information */
		pic32s->tx = (const void *)transfer->tx_buf;
		pic32s->rx = (const void *)transfer->rx_buf;
		pic32s->tx_end = pic32s->tx + transfer->len;
		pic32s->rx_end = pic32s->rx + transfer->len;
		pic32s->len = transfer->len;

		/* transact by interrupt driven PIO */
		enable_irq(pic32s->fault_irq);
		enable_irq(pic32s->rx_irq);
		enable_irq(pic32s->tx_irq);
	}

	/* wait for completion */
	timeout = wait_for_completion_timeout(&pic32s->xfer_done, 2 * HZ);
	if (timeout == 0) {
		dev_err(&spi->dev, "wait error/timedout\n");
		if (dma_issued) {
			dmaengine_terminate_all(master->dma_rx);
			dmaengine_terminate_all(master->dma_rx);
		}
		ret = -ETIMEDOUT;
	} else {
		ret = 0;
	}

	return ret;
}
Exemplo n.º 4
0
static int pic32_spi_set_wordlen(struct udevice *slave, unsigned int wordlen)
{
    struct pic32_spi_priv *priv = dev_get_priv(slave->parent);

    return pic32_spi_set_word_size(priv, wordlen);
}