ODROID-C5: spi: Add support cs-gpios using gpiod

Signed-off-by: YoungSoo Shin <shinys000114@gmail.com>
Change-Id: Id2729ed05a0ebc696aef413a0517150846cbdff5
diff --git a/drivers/spi/spi-meson-spicc-v2.c b/drivers/spi/spi-meson-spicc-v2.c
index 4391057..781c86d 100644
--- a/drivers/spi/spi-meson-spicc-v2.c
+++ b/drivers/spi/spi-meson-spicc-v2.c
@@ -626,6 +626,59 @@
 	return IRQ_HANDLED;
 }
 
+static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
+{
+	bool activate = enable;
+
+	/*
+	 * Avoid calling into the driver (or doing delays) if the chip select
+	 * isn't actually changing from the last time this was called.
+	 */
+	if (!force && (spi->controller->last_cs_enable == enable) &&
+	    (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
+		return;
+
+	spi->controller->last_cs_enable = enable;
+	spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
+
+	if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
+	    !spi->controller->set_cs_timing) && !activate) {
+		spi_delay_exec(&spi->cs_hold, NULL);
+	}
+
+	if (spi->mode & SPI_CS_HIGH)
+		enable = !enable;
+
+	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) {
+		if (!(spi->mode & SPI_NO_CS)) {
+			if (spi->cs_gpiod) {
+				/* Polarity handled by GPIO library */
+				gpiod_set_value_cansleep(spi->cs_gpiod, activate);
+			} else {
+				/*
+				 * invert the enable line, as active low is
+				 * default for SPI.
+				 */
+				gpio_set_value_cansleep(spi->cs_gpio, !enable);
+			}
+		}
+		/* Some SPI masters need both GPIO CS & slave_select */
+		if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
+		    spi->controller->set_cs)
+			spi->controller->set_cs(spi, !enable);
+	} else if (spi->controller->set_cs) {
+		spi->controller->set_cs(spi, !enable);
+	}
+
+	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
+	    !spi->controller->set_cs_timing) {
+		if (activate)
+			spi_delay_exec(&spi->cs_setup, NULL);
+		else
+			spi_delay_exec(&spi->cs_inactive, NULL);
+	}
+}
+
 /*
  * spi_transfer_one_message - Default implementation of transfer_one_message()
  *
@@ -647,6 +700,7 @@
 	int desc_num = 0, descs_len;
 	int ret = -EIO;
 
+	spi_set_cs(msg->spi, true, false);
 	if (!spicc_sem_down_read(spicc)) {
 		spi_finalize_current_message(ctlr);
 		dev_err(dev, "controller busy\n");
@@ -703,6 +757,7 @@
 
 	dma_unmap_single(dev, descs_paddr, descs_len, DMA_TO_DEVICE);
 end:
+	spi_set_cs(msg->spi, false, false);
 	desc = descs;
 	exdesc = exdescs;
 	list_for_each_entry(xfer, &msg->transfers, transfer_list)
@@ -1245,6 +1300,7 @@
 	ctlr->slave_abort = meson_spicc_slave_abort;
 	ctlr->can_dma = meson_spicc_can_dma;
 	ctlr->max_dma_len = SPICC_BLOCK_MAX;
+	ctlr->use_gpio_descriptors = true;
 	dma_set_max_seg_size(&pdev->dev, SPICC_BLOCK_MAX);
 	ret = devm_spi_register_master(&pdev->dev, ctlr);
 	if (ret) {