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....@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....@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....@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot