mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			74 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
Optionally omit the CS signal, if there's only one device on the bus.
 | 
						|
 | 
						|
--mb
 | 
						|
 | 
						|
 | 
						|
 | 
						|
--- a/drivers/spi/spi_gpio.c
 | 
						|
+++ b/drivers/spi/spi_gpio.c
 | 
						|
@@ -178,8 +178,10 @@ static void spi_gpio_chipselect(struct s
 | 
						|
 	if (is_active)
 | 
						|
 		setsck(spi, spi->mode & SPI_CPOL);
 | 
						|
 
 | 
						|
-	/* SPI is normally active-low */
 | 
						|
-	gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
 | 
						|
+	if (cs != SPI_GPIO_NO_CHIPSELECT) {
 | 
						|
+		/* SPI is normally active-low */
 | 
						|
+		gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
 | 
						|
+	}
 | 
						|
 }
 | 
						|
 
 | 
						|
 static int spi_gpio_setup(struct spi_device *spi)
 | 
						|
@@ -191,15 +193,17 @@ static int spi_gpio_setup(struct spi_dev
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
 	if (!spi->controller_state) {
 | 
						|
-		status = gpio_request(cs, spi->dev.bus_id);
 | 
						|
-		if (status)
 | 
						|
-			return status;
 | 
						|
-		status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
 | 
						|
+		if (cs != SPI_GPIO_NO_CHIPSELECT) {
 | 
						|
+			status = gpio_request(cs, spi->dev.bus_id);
 | 
						|
+			if (status)
 | 
						|
+				return status;
 | 
						|
+			status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
 | 
						|
+		}
 | 
						|
 	}
 | 
						|
 	if (!status)
 | 
						|
 		status = spi_bitbang_setup(spi);
 | 
						|
 	if (status) {
 | 
						|
-		if (!spi->controller_state)
 | 
						|
+		if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT)
 | 
						|
 			gpio_free(cs);
 | 
						|
 	}
 | 
						|
 	return status;
 | 
						|
@@ -209,7 +213,8 @@ static void spi_gpio_cleanup(struct spi_
 | 
						|
 {
 | 
						|
 	unsigned long	cs = (unsigned long) spi->controller_data;
 | 
						|
 
 | 
						|
-	gpio_free(cs);
 | 
						|
+	if (cs != SPI_GPIO_NO_CHIPSELECT)
 | 
						|
+		gpio_free(cs);
 | 
						|
 	spi_bitbang_cleanup(spi);
 | 
						|
 }
 | 
						|
 
 | 
						|
--- a/include/linux/spi/spi_gpio.h
 | 
						|
+++ b/include/linux/spi/spi_gpio.h
 | 
						|
@@ -25,10 +25,16 @@
 | 
						|
  *	...
 | 
						|
  *	};
 | 
						|
  *
 | 
						|
+ * If chipselect is not used (there's only one device on the bus), assign
 | 
						|
+ * SPI_GPIO_NO_CHIPSELECT to the controller_data:
 | 
						|
+ *		.controller_data = (void *) SPI_GPIO_NO_CHIPSELECT;
 | 
						|
+ *
 | 
						|
  * If the bitbanged bus is later switched to a "native" controller,
 | 
						|
  * that platform_device and controller_data should be removed.
 | 
						|
  */
 | 
						|
 
 | 
						|
+#define SPI_GPIO_NO_CHIPSELECT		((unsigned long)-1l)
 | 
						|
+
 | 
						|
 /**
 | 
						|
  * struct spi_gpio_platform_data - parameter for bitbanged SPI master
 | 
						|
  * @sck: number of the GPIO used for clock output
 |