Re: [U-Boot] [PATCH v3] spi: add new driver for OpenCores tiny_spi

2011-04-11 Thread Wolfgang Denk
Dear Thomas Chou,

In message <1295323751-12085-1-git-send-email-tho...@wytron.com.tw> you wrote:
> This patch adds support for OpenCores tiny_spi.
> 
> http://opencores.org/project,tiny_spi
> 
> Signed-off-by: Thomas Chou 
> ---
> for u-boot
> v2, use const and clean up as Mike suggested.
> v3, use struct instead of base+offset as Wolfgang suggested.
> 
>  drivers/spi/Makefile  |1 +
>  drivers/spi/oc_tiny_spi.c |  248 
> +
>  2 files changed, 249 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/spi/oc_tiny_spi.c

Sorry, but I see only now trhat there is an issue left:

> +struct tiny_spi_regs {
> + volatile unsigned rxdata;   /* Rx data reg */
> + volatile unsigned txdata;   /* Tx data reg */
> + volatile unsigned status;   /* Status reg */
> + volatile unsigned control;  /* Control reg */
> + volatile unsigned baud; /* Baud reg */
> +};

Please drop all these volatiles; see
Documentation/volatile-considered-harmful.txt in the Linux source
tree.

Thanks.

Wolfgang Denk

-- 
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de
Accident: A condition in which presence of mind is good, but  absence
of body is better.
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH v3] spi: add new driver for OpenCores tiny_spi

2011-01-17 Thread Thomas Chou
This patch adds support for OpenCores tiny_spi.

http://opencores.org/project,tiny_spi

Signed-off-by: Thomas Chou 
---
for u-boot
v2, use const and clean up as Mike suggested.
v3, use struct instead of base+offset as Wolfgang suggested.

 drivers/spi/Makefile  |1 +
 drivers/spi/oc_tiny_spi.c |  248 +
 2 files changed, 249 insertions(+), 0 deletions(-)
 create mode 100644 drivers/spi/oc_tiny_spi.c

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index e34a124..8ad1d7f 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -35,6 +35,7 @@ COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+COBJS-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o
 COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
 
diff --git a/drivers/spi/oc_tiny_spi.c b/drivers/spi/oc_tiny_spi.c
new file mode 100644
index 000..f379da1
--- /dev/null
+++ b/drivers/spi/oc_tiny_spi.c
@@ -0,0 +1,248 @@
+/*
+ * Opencore tiny_spi driver
+ *
+ * http://opencores.org/project,tiny_spi
+ *
+ * based on bfin_spi.c
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (C) 2010 Thomas Chou 
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define TINY_SPI_STATUS_TXE 0x1
+#define TINY_SPI_STATUS_TXR 0x2
+
+struct tiny_spi_regs {
+   volatile unsigned rxdata;   /* Rx data reg */
+   volatile unsigned txdata;   /* Tx data reg */
+   volatile unsigned status;   /* Status reg */
+   volatile unsigned control;  /* Control reg */
+   volatile unsigned baud; /* Baud reg */
+};
+
+struct tiny_spi_host {
+   uint base;
+   uint freq;
+   uint baudwidth;
+};
+static const struct tiny_spi_host tiny_spi_host_list[] =
+   CONFIG_SYS_TINY_SPI_LIST;
+
+struct tiny_spi_slave {
+   struct spi_slave slave;
+   const struct tiny_spi_host *host;
+   uint mode;
+   uint baud;
+   uint flg;
+};
+#define to_tiny_spi_slave(s) container_of(s, struct tiny_spi_slave, slave)
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+   return bus < ARRAY_SIZE(tiny_spi_host_list) && gpio_is_valid(cs);
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+   struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+   unsigned int cs = slave->cs;
+
+   gpio_set_value(cs, tiny_spi->flg);
+   debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+   struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+   unsigned int cs = slave->cs;
+
+   gpio_set_value(cs, !tiny_spi->flg);
+   debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
+}
+
+void spi_set_speed(struct spi_slave *slave, uint hz)
+{
+   struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+   const struct tiny_spi_host *host = tiny_spi->host;
+
+   tiny_spi->baud = min(DIV_ROUND_UP(host->freq, hz * 2),
+(1 << host->baudwidth)) - 1;
+   debug("%s: speed %u actual %u\n", __func__, hz,
+ host->freq / ((tiny_spi->baud + 1) * 2));
+}
+
+void spi_init(void)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int hz, unsigned int mode)
+{
+   struct tiny_spi_slave *tiny_spi;
+
+   if (!spi_cs_is_valid(bus, cs) || gpio_request(cs, "tiny_spi"))
+   return NULL;
+
+   tiny_spi = malloc(sizeof(*tiny_spi));
+   if (!tiny_spi)
+   return NULL;
+   memset(tiny_spi, 0, sizeof(*tiny_spi));
+
+   tiny_spi->slave.bus = bus;
+   tiny_spi->slave.cs = cs;
+   tiny_spi->host = &tiny_spi_host_list[bus];
+   tiny_spi->mode = mode & (SPI_CPOL | SPI_CPHA);
+   tiny_spi->flg = mode & SPI_CS_HIGH ? 1 : 0;
+   spi_set_speed(&tiny_spi->slave, hz);
+
+   debug("%s: bus:%i cs:%i base:%lx\n", __func__,
+   bus, cs, tiny_spi->host->base);
+   return &tiny_spi->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+   struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+
+   gpio_free(slave->cs);
+   free(tiny_spi);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+   struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+   struct tiny_spi_regs *regs = (void *)tiny_spi->host->base;
+
+   debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+   gpio_direction_output(slave->cs, !tiny_spi->flg);
+   writel(tiny_spi->mode, ®s->control);
+   writel(tiny_spi->baud, ®s->baud);
+   return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+   debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+}
+
+#ifndef CONFIG_TINY_SPI_IDLE_VAL
+# define CONFIG_TINY_SPI_IDLE_VAL 0xff
+#endif
+