Beispiel #1
0
static void completed(struct device *dev, int error)
{
	const struct spi_dw_config *info = dev->config->config_info;
	struct spi_dw_data *spi = dev->driver_data;

	if (error) {
		goto out;
	}

	if (spi_context_tx_on(&spi->ctx) ||
	    spi_context_rx_on(&spi->ctx)) {
		return;
	}

out:
	/* need to give time for FIFOs to drain before issuing more commands */
	while (test_bit_sr_busy(info->regs)) {
	}

	/* Disabling interrupts */
	write_imr(DW_SPI_IMR_MASK, info->regs);
	/* Disabling the controller */
	clear_bit_ssienr(info->regs);

	spi_context_cs_control(&spi->ctx, false);

	LOG_DBG("SPI transaction completed %s error",
		    error ? "with" : "without");

	spi_context_complete(&spi->ctx, error);
}
Beispiel #2
0
static inline bool _spi_dw_is_controller_ready(struct device *dev)
{
	const struct spi_dw_config *info = dev->config->config_info;

	if (test_bit_ssienr(info->regs) || test_bit_sr_busy(info->regs)) {
		return false;
	}

	return true;
}
Beispiel #3
0
static void completed(struct device *dev, int error)
{
	const struct spi_dw_config *info = dev->config->config_info;
	struct spi_dw_data *spi = dev->driver_data;

	if (error) {
		goto out;
	}

	/*
	* There are several situations here.
	* 1. spi_write w rx_buf - need last_tx && rx_buf_len zero to be done.
	* 2. spi_write w/o rx_buf - only need to determine when write is done.
	* 3. spi_read - need rx_buf_len zero.
	*/
	if (spi->tx_buf && spi->rx_buf) {
		if (!spi->last_tx || spi->rx_buf_len) {
			return;
		}
	} else if (spi->tx_buf) {
		if (!spi->last_tx) {
			return;
		}
	} else { /* or, spi->rx_buf!=0 */
		if (spi->rx_buf_len) {
			return;
		}
	}

out:
	/* need to give time for FIFOs to drain before issuing more commands */
	while (test_bit_sr_busy(info->regs)) {
	}

	spi->error = error;

	/* Disabling interrupts */
	write_imr(DW_SPI_IMR_MASK, info->regs);
	/* Disabling the controller */
	clear_bit_ssienr(info->regs);

	_spi_control_cs(dev, 0);

	SYS_LOG_DBG("SPI transaction completed %s error",
		    error ? "with" : "without");

	k_sem_give(&spi->device_sync_sem);
}