Re: [PATCH v2] spi: Add SuperH HSPI prototype driver
Hi Kuninori, On Fri, Jan 6, 2012 at 11:30 AM, Kuninori Morimoto kuninori.morimoto...@renesas.com wrote: This patch adds SuperH HSPI driver. It is still prototype driver, but has enough function at this point. Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com --- v1 - v2 - mdelay() - msleep() - typo fix - sizeof(struct hspi_priv) - sizeof(*hspi) - remove devname - use dev_err() instead of printk(KERN_ERR, ) - modiry spi_unregister_master() timing drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi-sh-hspi.c | 363 +++ include/linux/spi/sh_hspi.h | 34 4 files changed, 404 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi-sh-hspi.c create mode 100644 include/linux/spi/sh_hspi.h diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a1fd73d..33bb33e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -325,6 +325,12 @@ config SPI_SH_SCI help SPI driver for SuperH SCI blocks. +config SPI_SH_HSPI + tristate SuperH HSPI controller + depends on ARCH_SHMOBILE + help + SPI driver for SuperH HSPI blocks. + config SPI_STMP3XXX tristate Freescale STMP37xx/378x SPI/SSP controller depends on ARCH_STMP3XXX SPI_MASTER diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 61c3261..d65e059 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o obj-$(CONFIG_SPI_SH) += spi-sh.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o +obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_STMP3XXX) += spi-stmp.o obj-$(CONFIG_SPI_TEGRA) += spi-tegra.o obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp.o diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c new file mode 100644 index 000..f527d24 --- /dev/null +++ b/drivers/spi/spi-sh-hspi.c @@ -0,0 +1,363 @@ +/* + * SuperH HSPI bus driver + * + * Copyright (C) 2011 Kuninori Morimoto + * + * Based on spi-sh.c: + * Based on pxa2xx_spi.c: + * Copyright (C) 2011 Renesas Solutions Corp. + * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs + * + * 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; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include linux/module.h +#include linux/kernel.h +#include linux/timer.h +#include linux/delay.h +#include linux/list.h +#include linux/workqueue.h +#include linux/interrupt.h +#include linux/platform_device.h +#include linux/pm_runtime.h +#include linux/io.h +#include linux/spi/spi.h +#include linux/spi/sh_hspi.h + +#define SPCR 0x00 +#define SPSR 0x04 +#define SPSCR 0x08 +#define SPTBR 0x0C +#define SPRBR 0x10 +#define SPCR2 0x14 + +/* SPSR */ +#define RXFL (1 2) + +#define hspi2info(h) (h-dev-platform_data) + +struct hspi_priv { + void __iomem *addr; + struct spi_master *master; + struct list_head queue; + struct workqueue_struct *workqueue; + struct work_struct ws; + struct device *dev; + spinlock_t lock; +}; + +/* + * basic function + */ +static void hspi_write(struct hspi_priv *hspi, int reg, u32 val) +{ + iowrite32(val, hspi-addr + reg); +} + +static u8 hspi_read(struct hspi_priv *hspi, int reg) +{ + return (u8)ioread32(hspi-addr + reg); You do a ioread32 and then typecast to u8 Didnt undwerstand? +} + +/* + * transfer function + */ +static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val) +{ + int t = 256; + + while (t--) { + if ((mask hspi_read(hspi, SPSR)) == val) + return 0; + + msleep(10); + } + + dev_err(hspi-dev, timeout\n); + return -ETIMEDOUT; +} + +static int hspi_push(struct hspi_priv *hspi, struct spi_message *msg, + struct spi_transfer *t) +{ + int i, ret; + u8 *data = (u8 *)t-tx_buf; + + /* + * FIXME + * very simple, but polling transfer + */ + for (i = 0; i t-len; i++) { + /*
[PATCH v3] spi: Add SuperH HSPI prototype driver
This patch adds SuperH HSPI driver. It is still prototype driver, but has enough function at this point. Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com --- v2 - v3 - modify wrong hspi_read() return cast - use devm_xx() drivers/spi/Kconfig |6 + drivers/spi/Makefile|1 + drivers/spi/spi-sh-hspi.c | 364 +++ include/linux/spi/sh_hspi.h | 34 4 files changed, 405 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi-sh-hspi.c create mode 100644 include/linux/spi/sh_hspi.h diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8293658..6f544e6 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -324,6 +324,12 @@ config SPI_SH_SCI help SPI driver for SuperH SCI blocks. +config SPI_SH_HSPI + tristate SuperH HSPI controller + depends on ARCH_SHMOBILE + help + SPI driver for SuperH HSPI blocks. + config SPI_STMP3XXX tristate Freescale STMP37xx/378x SPI/SSP controller depends on ARCH_STMP3XXX SPI_MASTER diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 61c3261..d65e059 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o obj-$(CONFIG_SPI_SH) += spi-sh.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o +obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_STMP3XXX) += spi-stmp.o obj-$(CONFIG_SPI_TEGRA)+= spi-tegra.o obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp.o diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c new file mode 100644 index 000..8356ec8 --- /dev/null +++ b/drivers/spi/spi-sh-hspi.c @@ -0,0 +1,364 @@ +/* + * SuperH HSPI bus driver + * + * Copyright (C) 2011 Kuninori Morimoto + * + * Based on spi-sh.c: + * Based on pxa2xx_spi.c: + * Copyright (C) 2011 Renesas Solutions Corp. + * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs + * + * 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; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include linux/module.h +#include linux/kernel.h +#include linux/timer.h +#include linux/delay.h +#include linux/list.h +#include linux/workqueue.h +#include linux/interrupt.h +#include linux/platform_device.h +#include linux/pm_runtime.h +#include linux/io.h +#include linux/spi/spi.h +#include linux/spi/sh_hspi.h + +#define SPCR 0x00 +#define SPSR 0x04 +#define SPSCR 0x08 +#define SPTBR 0x0C +#define SPRBR 0x10 +#define SPCR2 0x14 + +/* SPSR */ +#define RXFL (1 2) + +#define hspi2info(h) (h-dev-platform_data) + +struct hspi_priv { + void __iomem *addr; + struct spi_master *master; + struct list_head queue; + struct workqueue_struct *workqueue; + struct work_struct ws; + struct device *dev; + spinlock_t lock; +}; + +/* + * basic function + */ +static void hspi_write(struct hspi_priv *hspi, int reg, u32 val) +{ + iowrite32(val, hspi-addr + reg); +} + +static u32 hspi_read(struct hspi_priv *hspi, int reg) +{ + return ioread32(hspi-addr + reg); +} + +/* + * transfer function + */ +static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val) +{ + int t = 256; + + while (t--) { + if ((mask hspi_read(hspi, SPSR)) == val) + return 0; + + msleep(20); + } + + dev_err(hspi-dev, timeout\n); + return -ETIMEDOUT; +} + +static int hspi_push(struct hspi_priv *hspi, struct spi_message *msg, +struct spi_transfer *t) +{ + int i, ret; + u8 *data = (u8 *)t-tx_buf; + + /* +* FIXME +* very simple, but polling transfer +*/ + for (i = 0; i t-len; i++) { + /* wait remains */ + ret = hspi_status_check_timeout(hspi, 0x1, 0x0); + if (ret 0) + return ret; + + hspi_write(hspi, SPTBR, (u32)data[i]); + + /* wait recive */ + ret = hspi_status_check_timeout(hspi, 0x4, 0x4); + if (ret 0) + return ret; + + /* dummy read */ + hspi_read(hspi, SPRBR); +