forked from mirrors/linux
		
	spi: spi-fsl-dspi: Remove spi-bitbang
DSPI module need cs change information in a spi transfer. According to cs change, DSPI will give last data the right flag. Bitbang provide cs change behind the last data in a transfer. So DSPI can not deal the last data in every transfer properly, so remove the bitbang in the driver. Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
		
							parent
							
								
									973fbce69e
								
							
						
					
					
						commit
						9298bc7273
					
				
					 2 changed files with 66 additions and 69 deletions
				
			
		| 
						 | 
				
			
			@ -292,7 +292,6 @@ config SPI_FSL_SPI
 | 
			
		|||
 | 
			
		||||
config SPI_FSL_DSPI
 | 
			
		||||
	tristate "Freescale DSPI controller"
 | 
			
		||||
	select SPI_BITBANG
 | 
			
		||||
	select REGMAP_MMIO
 | 
			
		||||
	depends on SOC_VF610 || COMPILE_TEST
 | 
			
		||||
	help
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ struct chip_data {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
struct fsl_dspi {
 | 
			
		||||
	struct spi_bitbang	bitbang;
 | 
			
		||||
	struct spi_master	*master;
 | 
			
		||||
	struct platform_device	*pdev;
 | 
			
		||||
 | 
			
		||||
	struct regmap		*regmap;
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +114,7 @@ struct fsl_dspi {
 | 
			
		|||
	struct clk		*clk;
 | 
			
		||||
 | 
			
		||||
	struct spi_transfer	*cur_transfer;
 | 
			
		||||
	struct spi_message	*cur_msg;
 | 
			
		||||
	struct chip_data	*cur_chip;
 | 
			
		||||
	size_t			len;
 | 
			
		||||
	void			*tx;
 | 
			
		||||
| 
						 | 
				
			
			@ -123,6 +124,7 @@ struct fsl_dspi {
 | 
			
		|||
	char			dataflags;
 | 
			
		||||
	u8			cs;
 | 
			
		||||
	u16			void_write_data;
 | 
			
		||||
	u32			cs_change;
 | 
			
		||||
 | 
			
		||||
	wait_queue_head_t	waitq;
 | 
			
		||||
	u32			waitflags;
 | 
			
		||||
| 
						 | 
				
			
			@ -225,6 +227,8 @@ static int dspi_transfer_write(struct fsl_dspi *dspi)
 | 
			
		|||
		if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) {
 | 
			
		||||
			/* last transfer in the transfer */
 | 
			
		||||
			dspi_pushr |= SPI_PUSHR_EOQ;
 | 
			
		||||
			if ((dspi->cs_change) && (!dspi->len))
 | 
			
		||||
				dspi_pushr &= ~SPI_PUSHR_CONT;
 | 
			
		||||
		} else if (tx_word && (dspi->len == 1))
 | 
			
		||||
			dspi_pushr |= SPI_PUSHR_EOQ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -246,6 +250,7 @@ static int dspi_transfer_read(struct fsl_dspi *dspi)
 | 
			
		|||
	int rx_count = 0;
 | 
			
		||||
	int rx_word = is_double_byte_mode(dspi);
 | 
			
		||||
	u16 d;
 | 
			
		||||
 | 
			
		||||
	while ((dspi->rx < dspi->rx_end)
 | 
			
		||||
			&& (rx_count < DSPI_FIFO_SIZE)) {
 | 
			
		||||
		if (rx_word) {
 | 
			
		||||
| 
						 | 
				
			
			@ -276,20 +281,32 @@ static int dspi_transfer_read(struct fsl_dspi *dspi)
 | 
			
		|||
	return rx_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t)
 | 
			
		||||
static int dspi_transfer_one_message(struct spi_master *master,
 | 
			
		||||
		struct spi_message *message)
 | 
			
		||||
{
 | 
			
		||||
	struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
 | 
			
		||||
	dspi->cur_transfer = t;
 | 
			
		||||
	struct fsl_dspi *dspi = spi_master_get_devdata(master);
 | 
			
		||||
	struct spi_device *spi = message->spi;
 | 
			
		||||
	struct spi_transfer *transfer;
 | 
			
		||||
	int status = 0;
 | 
			
		||||
	message->actual_length = 0;
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(transfer, &message->transfers, transfer_list) {
 | 
			
		||||
		dspi->cur_transfer = transfer;
 | 
			
		||||
		dspi->cur_msg = message;
 | 
			
		||||
		dspi->cur_chip = spi_get_ctldata(spi);
 | 
			
		||||
		dspi->cs = spi->chip_select;
 | 
			
		||||
		if (dspi->cur_transfer->transfer_list.next
 | 
			
		||||
				== &dspi->cur_msg->transfers)
 | 
			
		||||
			transfer->cs_change = 1;
 | 
			
		||||
		dspi->cs_change = transfer->cs_change;
 | 
			
		||||
		dspi->void_write_data = dspi->cur_chip->void_write_data;
 | 
			
		||||
 | 
			
		||||
		dspi->dataflags = 0;
 | 
			
		||||
	dspi->tx = (void *)t->tx_buf;
 | 
			
		||||
	dspi->tx_end = dspi->tx + t->len;
 | 
			
		||||
	dspi->rx = t->rx_buf;
 | 
			
		||||
	dspi->rx_end = dspi->rx + t->len;
 | 
			
		||||
	dspi->len = t->len;
 | 
			
		||||
		dspi->tx = (void *)transfer->tx_buf;
 | 
			
		||||
		dspi->tx_end = dspi->tx + transfer->len;
 | 
			
		||||
		dspi->rx = transfer->rx_buf;
 | 
			
		||||
		dspi->rx_end = dspi->rx + transfer->len;
 | 
			
		||||
		dspi->len = transfer->len;
 | 
			
		||||
 | 
			
		||||
		if (!dspi->rx)
 | 
			
		||||
			dspi->dataflags |= TRAN_STATE_RX_VOID;
 | 
			
		||||
| 
						 | 
				
			
			@ -298,42 +315,33 @@ static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t)
 | 
			
		|||
			dspi->dataflags |= TRAN_STATE_TX_VOID;
 | 
			
		||||
 | 
			
		||||
		regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val);
 | 
			
		||||
	regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val);
 | 
			
		||||
	regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE);
 | 
			
		||||
 | 
			
		||||
	if (t->speed_hz)
 | 
			
		||||
		regmap_update_bits(dspi->regmap, SPI_MCR,
 | 
			
		||||
				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
 | 
			
		||||
				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
 | 
			
		||||
		regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),
 | 
			
		||||
				dspi->cur_chip->ctar_val);
 | 
			
		||||
		if (transfer->speed_hz)
 | 
			
		||||
			regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),
 | 
			
		||||
					dspi->cur_chip->ctar_val);
 | 
			
		||||
 | 
			
		||||
	dspi_transfer_write(dspi);
 | 
			
		||||
		regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE);
 | 
			
		||||
		message->actual_length += dspi_transfer_write(dspi);
 | 
			
		||||
 | 
			
		||||
		if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
 | 
			
		||||
			dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n");
 | 
			
		||||
		dspi->waitflags = 0;
 | 
			
		||||
 | 
			
		||||
	return t->len - dspi->len;
 | 
			
		||||
		if (transfer->delay_usecs)
 | 
			
		||||
			udelay(transfer->delay_usecs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
static void dspi_chipselect(struct spi_device *spi, int value)
 | 
			
		||||
{
 | 
			
		||||
	struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
 | 
			
		||||
	unsigned int pushr;
 | 
			
		||||
	message->status = status;
 | 
			
		||||
	spi_finalize_current_message(master);
 | 
			
		||||
 | 
			
		||||
	regmap_read(dspi->regmap, SPI_PUSHR, &pushr);
 | 
			
		||||
 | 
			
		||||
	switch (value) {
 | 
			
		||||
	case BITBANG_CS_ACTIVE:
 | 
			
		||||
		pushr |= SPI_PUSHR_CONT;
 | 
			
		||||
		break;
 | 
			
		||||
	case BITBANG_CS_INACTIVE:
 | 
			
		||||
		pushr &= ~SPI_PUSHR_CONT;
 | 
			
		||||
		break;
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	regmap_write(dspi->regmap, SPI_PUSHR, pushr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 | 
			
		||||
static int dspi_setup(struct spi_device *spi)
 | 
			
		||||
{
 | 
			
		||||
	struct chip_data *chip;
 | 
			
		||||
	struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
 | 
			
		||||
| 
						 | 
				
			
			@ -373,14 +381,6 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dspi_setup(struct spi_device *spi)
 | 
			
		||||
{
 | 
			
		||||
	if (!spi->max_speed_hz)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return dspi_setup_transfer(spi, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dspi_cleanup(struct spi_device *spi)
 | 
			
		||||
{
 | 
			
		||||
	struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
 | 
			
		||||
| 
						 | 
				
			
			@ -395,8 +395,9 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 | 
			
		|||
{
 | 
			
		||||
	struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;
 | 
			
		||||
 | 
			
		||||
	regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF);
 | 
			
		||||
	struct spi_message *msg = dspi->cur_msg;
 | 
			
		||||
 | 
			
		||||
	regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF);
 | 
			
		||||
	dspi_transfer_read(dspi);
 | 
			
		||||
 | 
			
		||||
	if (!dspi->len) {
 | 
			
		||||
| 
						 | 
				
			
			@ -406,11 +407,8 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 | 
			
		|||
 | 
			
		||||
		dspi->waitflags = 1;
 | 
			
		||||
		wake_up_interruptible(&dspi->waitq);
 | 
			
		||||
	} else {
 | 
			
		||||
		dspi_transfer_write(dspi);
 | 
			
		||||
 | 
			
		||||
		return IRQ_HANDLED;
 | 
			
		||||
	}
 | 
			
		||||
	} else
 | 
			
		||||
		msg->actual_length += dspi_transfer_write(dspi);
 | 
			
		||||
 | 
			
		||||
	return IRQ_HANDLED;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -469,12 +467,12 @@ static int dspi_probe(struct platform_device *pdev)
 | 
			
		|||
 | 
			
		||||
	dspi = spi_master_get_devdata(master);
 | 
			
		||||
	dspi->pdev = pdev;
 | 
			
		||||
	dspi->bitbang.master = master;
 | 
			
		||||
	dspi->bitbang.chipselect = dspi_chipselect;
 | 
			
		||||
	dspi->bitbang.setup_transfer = dspi_setup_transfer;
 | 
			
		||||
	dspi->bitbang.txrx_bufs = dspi_txrx_transfer;
 | 
			
		||||
	dspi->bitbang.master->setup = dspi_setup;
 | 
			
		||||
	dspi->bitbang.master->dev.of_node = pdev->dev.of_node;
 | 
			
		||||
	dspi->master = master;
 | 
			
		||||
 | 
			
		||||
	master->transfer = NULL;
 | 
			
		||||
	master->setup = dspi_setup;
 | 
			
		||||
	master->transfer_one_message = dspi_transfer_one_message;
 | 
			
		||||
	master->dev.of_node = pdev->dev.of_node;
 | 
			
		||||
 | 
			
		||||
	master->cleanup = dspi_cleanup;
 | 
			
		||||
	master->mode_bits = SPI_CPOL | SPI_CPHA;
 | 
			
		||||
| 
						 | 
				
			
			@ -535,7 +533,7 @@ static int dspi_probe(struct platform_device *pdev)
 | 
			
		|||
	init_waitqueue_head(&dspi->waitq);
 | 
			
		||||
	platform_set_drvdata(pdev, master);
 | 
			
		||||
 | 
			
		||||
	ret = spi_bitbang_start(&dspi->bitbang);
 | 
			
		||||
	ret = spi_register_master(master);
 | 
			
		||||
	if (ret != 0) {
 | 
			
		||||
		dev_err(&pdev->dev, "Problem registering DSPI master\n");
 | 
			
		||||
		goto out_clk_put;
 | 
			
		||||
| 
						 | 
				
			
			@ -557,9 +555,9 @@ static int dspi_remove(struct platform_device *pdev)
 | 
			
		|||
	struct fsl_dspi *dspi = spi_master_get_devdata(master);
 | 
			
		||||
 | 
			
		||||
	/* Disconnect from the SPI framework */
 | 
			
		||||
	spi_bitbang_stop(&dspi->bitbang);
 | 
			
		||||
	clk_disable_unprepare(dspi->clk);
 | 
			
		||||
	spi_master_put(dspi->bitbang.master);
 | 
			
		||||
	spi_unregister_master(dspi->master);
 | 
			
		||||
	spi_master_put(dspi->master);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue