[U-Boot] [PATCH] S5P: new spi gpio bitbang driver

Donghwa Lee dh09.lee at samsung.com
Tue Sep 14 09:38:11 CEST 2010


This patch adds basic support for spi mode 0~3 by control gpio bitbang in S5P.
Original name of this patch was "support spi gpio driver by control gpio bitbang".
But, it had arch-specific features, S5P, so changed to this name.

It uses several gpio pin and emulates spi chipselect signal, clock signal
and sda signal as if spi controller generate spi signal.

I think it is going to use LCD Panel driver that using spi interface.

Signed-off-by: Donghwa Lee <dh09.lee at samsung.com>

---
 arch/arm/include/asm/arch-s5pc1xx/spi.h |   53 +++++++++++
 drivers/spi/Makefile                    |    1 +
 drivers/spi/s5p-spi.c                   |  154 +++++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-s5pc1xx/spi.h
 create mode 100644 drivers/spi/s5p-spi.c

diff --git a/arch/arm/include/asm/arch-s5pc1xx/spi.h b/arch/arm/include/asm/arch-s5pc1xx/spi.h
new file mode 100644
index 0000000..c7ae4dc
--- /dev/null
+++ b/arch/arm/include/asm/arch-s5pc1xx/spi.h
@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright 2010 SAMSUNG Electronics
+ * Donghwa Lee <dh09.lee at samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ASM_ARCH_SPI_H_
+#define __ASM_ARCH_SPI_H_
+
+#ifndef __ASSEMBLY__
+
+
+#define COMMAND_ONLY		0xFE
+#define DATA_ONLY		0xFF
+#define ACTIVE_LOW		0
+#define ACTIVE_HIGH		1
+
+
+struct s5p_spi_platdata {
+	struct s5p_gpio_bank *cs_bank;
+	struct s5p_gpio_bank *clk_bank;
+	struct s5p_gpio_bank *si_bank;
+	struct s5p_gpio_bank *so_bank;
+
+	unsigned int cs_num;
+	unsigned int clk_num;
+	unsigned int si_num;
+	unsigned int so_num;
+
+	unsigned int mode;
+	unsigned int cs_active;
+	unsigned int word_len;
+};
+
+void s5p_spi_write(struct s5p_spi_platdata *spi,
+				unsigned int address, unsigned int command);
+
+#endif	/* __ASSEMBLY__ */
+#endif
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index dfcbb8b..e3c38e8 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -36,6 +36,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
+COBJS-$(CONFIG_S5P) += s5p-spi.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/spi/s5p-spi.c b/drivers/spi/s5p-spi.c
new file mode 100644
index 0000000..6fa8634
--- /dev/null
+++ b/drivers/spi/s5p-spi.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ * Donghwa Lee <dh09.lee at samsung.com>
+ * s5p_spi_gpio.c - SPI master driver using generic bitbanged GPIO
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/spi.h>
+#include <spi.h>
+
+static void s5p_spi_gpio_set_sck(struct s5p_spi_platdata *spi, int is_on)
+{
+	gpio_set_value(spi->clk_bank, spi->clk_num, is_on);
+}
+
+static void s5p_spi_gpio_set_mosi(struct s5p_spi_platdata *spi, int is_on)
+{
+	gpio_set_value(spi->si_bank, spi->si_num, is_on);
+}
+
+static void s5p_spi_gpio_chipselect(struct s5p_spi_platdata *spi,
+	int cpol)
+{
+	gpio_set_value(spi->cs_bank, spi->cs_num,
+		!spi->cs_active);
+
+	/* set initial clock polarity */
+	if (cpol)
+		s5p_spi_gpio_set_sck(spi, spi->mode & SPI_CPOL);
+
+	/* SPI is normally active-low */
+	gpio_set_value(spi->cs_bank, spi->cs_num,
+		spi->cs_active);
+}
+
+static void
+s5p_spi_gpio_tx_cpha0(struct s5p_spi_platdata *spi,
+		unsigned int nsecs, unsigned int cpol,
+		unsigned int word, unsigned int bits)
+{
+	int i;
+	unsigned int data;
+
+	data = (word << spi->word_len) + bits;
+
+	s5p_spi_gpio_chipselect(spi, cpol);
+
+	/* clock starts at inactive polarity */
+	for (i = spi->word_len; i >= 0; i--) {
+
+		/* data high or low */
+		if ((data >> i) & 0x1)
+			s5p_spi_gpio_set_mosi(spi, 1);
+		else
+			s5p_spi_gpio_set_mosi(spi, 0);
+
+		udelay(nsecs);
+
+		s5p_spi_gpio_set_sck(spi, !cpol);
+		udelay(nsecs);
+
+		s5p_spi_gpio_set_sck(spi, cpol);
+	}
+}
+
+static void
+s5p_spi_gpio_tx_cpha1(struct s5p_spi_platdata *spi,
+		unsigned int nsecs, unsigned int cpol,
+		unsigned int word, unsigned int bits)
+{
+	int i;
+	unsigned int data;
+
+	data = (word << spi->word_len) + bits;
+
+	s5p_spi_gpio_chipselect(spi, cpol);
+
+	/* clock starts at inactive polarity */
+	for (i = spi->word_len; i >= 0; i--) {
+
+		/* setup MSB (to slave) on leading edge */
+		s5p_spi_gpio_set_sck(spi, !cpol);
+
+		/* data high or low */
+		if ((data >> i) & 0x1)
+			s5p_spi_gpio_set_mosi(spi, 1);
+		else
+			s5p_spi_gpio_set_mosi(spi, 0);
+
+		udelay(nsecs);
+
+		s5p_spi_gpio_set_sck(spi, cpol);
+		udelay(nsecs);
+	}
+}
+
+static void s5p_spi_gpio_tx_word_mode0(struct s5p_spi_platdata *spi,
+		unsigned int nsecs, unsigned int word, unsigned int bits)
+{
+	return s5p_spi_gpio_tx_cpha0(spi, nsecs, 0, word, bits);
+}
+
+static void s5p_spi_gpio_tx_word_mode1(struct s5p_spi_platdata *spi,
+		unsigned int nsecs, unsigned int word, unsigned int bits)
+{
+	return s5p_spi_gpio_tx_cpha1(spi, nsecs, 0, word, bits);
+}
+
+static void s5p_spi_gpio_tx_word_mode2(struct s5p_spi_platdata *spi,
+		unsigned int nsecs, unsigned int word, unsigned int bits)
+{
+	return s5p_spi_gpio_tx_cpha0(spi, nsecs, 1, word, bits);
+}
+
+static void s5p_spi_gpio_tx_word_mode3(struct s5p_spi_platdata *spi,
+		unsigned int nsecs, unsigned int word, unsigned int bits)
+{
+	return s5p_spi_gpio_tx_cpha1(spi, nsecs, 1, word, bits);
+}
+
+void s5p_spi_gpio_write(struct s5p_spi_platdata *spi,
+	unsigned int address, unsigned int command)
+{
+	switch (spi->mode) {
+	case SPI_MODE_0:
+		s5p_spi_gpio_tx_word_mode0(spi,
+			1, address, command);
+	case SPI_MODE_1:
+		s5p_spi_gpio_tx_word_mode1(spi,
+			1, address, command);
+	case SPI_MODE_2:
+		s5p_spi_gpio_tx_word_mode2(spi,
+			1, address, command);
+	case SPI_MODE_3:
+		s5p_spi_gpio_tx_word_mode3(spi,
+			1, address, command);
+	}
+}
-- 
1.6.0.4



More information about the U-Boot mailing list