aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.26/1026-smedia-glamo.patch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/1026-smedia-glamo.patch.patch')
-rwxr-xr-xtarget/linux/s3c24xx/patches-2.6.26/1026-smedia-glamo.patch.patch3501
1 files changed, 0 insertions, 3501 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/1026-smedia-glamo.patch.patch b/target/linux/s3c24xx/patches-2.6.26/1026-smedia-glamo.patch.patch
deleted file mode 100755
index e64744294f..0000000000
--- a/target/linux/s3c24xx/patches-2.6.26/1026-smedia-glamo.patch.patch
+++ /dev/null
@@ -1,3501 +0,0 @@
-From 7b73c5270e710d39dc45231087fe3e078d063225 Mon Sep 17 00:00:00 2001
-From: mokopatches <mokopatches@openmoko.org>
-Date: Wed, 16 Jul 2008 14:44:50 +0100
-Subject: [PATCH] smedia-glamo.patch
- [ FIXME:
- include/asm-arm/arch-s3c2410/irqs.h shouldn't contain device-specific
- changes. ]
-
-This is a Linux kernel driver for the Smedia Glamo336x / Glamo337x
-multi-function peripheral device.
-
-Signed-off-by: Harald Welte <laforge@openmoko.org>
----
- drivers/mfd/Kconfig | 2 +
- drivers/mfd/Makefile | 1 +
- drivers/mfd/glamo/Kconfig | 35 ++
- drivers/mfd/glamo/Makefile | 11 +
- drivers/mfd/glamo/glamo-core.c | 1151 +++++++++++++++++++++++++++++++++++
- drivers/mfd/glamo/glamo-core.h | 91 +++
- drivers/mfd/glamo/glamo-fb.c | 822 +++++++++++++++++++++++++
- drivers/mfd/glamo/glamo-gpio.c | 62 ++
- drivers/mfd/glamo/glamo-lcm-spi.c | 241 ++++++++
- drivers/mfd/glamo/glamo-regs.h | 477 +++++++++++++++
- drivers/mfd/glamo/glamo-spi-gpio.c | 256 ++++++++
- include/asm-arm/arch-s3c2410/irqs.h | 32 +-
- include/linux/glamo-gpio.h | 99 +++
- include/linux/glamofb.h | 39 ++
- include/linux/spi/glamo.h | 28 +
- 15 files changed, 3345 insertions(+), 2 deletions(-)
- create mode 100644 drivers/mfd/glamo/Kconfig
- create mode 100644 drivers/mfd/glamo/Makefile
- create mode 100644 drivers/mfd/glamo/glamo-core.c
- create mode 100644 drivers/mfd/glamo/glamo-core.h
- create mode 100644 drivers/mfd/glamo/glamo-fb.c
- create mode 100644 drivers/mfd/glamo/glamo-gpio.c
- create mode 100644 drivers/mfd/glamo/glamo-lcm-spi.c
- create mode 100644 drivers/mfd/glamo/glamo-regs.h
- create mode 100644 drivers/mfd/glamo/glamo-spi-gpio.c
- create mode 100644 include/linux/glamo-gpio.h
- create mode 100644 include/linux/glamofb.h
- create mode 100644 include/linux/spi/glamo.h
-
-diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
-index ae96bd6..79f934e 100644
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -38,6 +38,8 @@ config HTC_PASIC3
- HTC Magician devices, respectively. Actual functionality is
- handled by the leds-pasic3 and ds1wm drivers.
-
-+source "drivers/mfd/glamo/Kconfig"
-+
- endmenu
-
- menu "Multimedia Capabilities Port drivers"
-diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
-index eef4e26..b172418 100644
---- a/drivers/mfd/Makefile
-+++ b/drivers/mfd/Makefile
-@@ -4,6 +4,7 @@
-
- obj-$(CONFIG_MFD_SM501) += sm501.o
- obj-$(CONFIG_MFD_ASIC3) += asic3.o
-+obj-$(CONFIG_MFD_GLAMO) += glamo/
-
- obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
- obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
-diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig
-new file mode 100644
-index 0000000..b99f2b2
---- /dev/null
-+++ b/drivers/mfd/glamo/Kconfig
-@@ -0,0 +1,35 @@
-+config MFD_GLAMO
-+ bool "Smedia Glamo 336x/337x support"
-+ help
-+ This enables the core driver for the Smedia Glamo 336x/337x
-+ multi-function device. It includes irq_chip demultiplex as
-+ well as clock / power management and GPIO support.
-+
-+config MFD_GLAMO_FB
-+ tristate "Smedia Glamo 336x/337x framebuffer support"
-+ depends on FB && MFD_GLAMO
-+ help
-+ Frame buffer driver for the LCD controller in the Smedia Glamo
-+ 336x/337x.
-+
-+ This driver is also available as a module ( = code which can be
-+ inserted and removed from the running kernel whenever you want). The
-+ module will be called glamofb. If you want to compile it as a module,
-+ say M here and read <file:Documentation/modules.txt>.
-+
-+ If unsure, say N.
-+
-+config MFD_GLAMO_SPI_GPIO
-+ tristate "Glamo GPIO SPI bitbang support"
-+ depends on MFD_GLAMO
-+ help
-+ Enable a bitbanging SPI adapter driver for the Smedia Glamo.
-+
-+config MFD_GLAMO_SPI_FB
-+ tristate "Glamo LCM control channel SPI support"
-+ depends on MFD_GLAMO_FB
-+ help
-+ Enable a bitbanging SPI adapter driver for the Smedia Glamo LCM
-+ control channel. This SPI interface is frequently used to
-+ interconnect the LCM control interface.
-+
-diff --git a/drivers/mfd/glamo/Makefile b/drivers/mfd/glamo/Makefile
-new file mode 100644
-index 0000000..fb53982
---- /dev/null
-+++ b/drivers/mfd/glamo/Makefile
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the Smedia Glamo framebuffer driver
-+#
-+
-+obj-$(CONFIG_MFD_GLAMO) += glamo-core.o glamo-gpio.o
-+obj-$(CONFIG_MFD_GLAMO_SPI) += glamo-spi.o
-+obj-$(CONFIG_MFD_GLAMO_SPI_GPIO) += glamo-spi-gpio.o
-+
-+obj-$(CONFIG_MFD_GLAMO_FB) += glamo-fb.o
-+obj-$(CONFIG_MFD_GLAMO_SPI_FB) += glamo-lcm-spi.o
-+
-diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
-new file mode 100644
-index 0000000..acf545f
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-core.c
-@@ -0,0 +1,1151 @@
-+/* Smedia Glamo 336x/337x driver
-+ *
-+ * (C) 2007 by OpenMoko, Inc.
-+ * Author: Harald Welte <laforge@openmoko.org>
-+ * All rights reserved.
-+ *
-+ * 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 <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/tty.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/fb.h>
-+#include <linux/init.h>
-+#include <linux/irq.h>
-+#include <linux/interrupt.h>
-+#include <linux/workqueue.h>
-+#include <linux/wait.h>
-+#include <linux/platform_device.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/spinlock.h>
-+#include <linux/glamofb.h>
-+#include <linux/mmc/mmc.h>
-+#include <linux/mmc/host.h>
-+
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <asm/div64.h>
-+
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+#endif
-+
-+#include "glamo-regs.h"
-+#include "glamo-core.h"
-+
-+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-+
-+static struct glamo_core *glamo_handle;
-+
-+static inline void __reg_write(struct glamo_core *glamo,
-+ u_int16_t reg, u_int16_t val)
-+{
-+ writew(val, glamo->base + reg);
-+}
-+
-+static inline u_int16_t __reg_read(struct glamo_core *glamo,
-+ u_int16_t reg)
-+{
-+ return readw(glamo->base + reg);
-+}
-+
-+static void __reg_set_bit_mask(struct glamo_core *glamo,
-+ u_int16_t reg, u_int16_t mask,
-+ u_int16_t val)
-+{
-+ u_int16_t tmp;
-+
-+ val &= mask;
-+
-+ tmp = __reg_read(glamo, reg);
-+ tmp &= ~mask;
-+ tmp |= val;
-+ __reg_write(glamo, reg, tmp);
-+}
-+
-+static void reg_set_bit_mask(struct glamo_core *glamo,
-+ u_int16_t reg, u_int16_t mask,
-+ u_int16_t val)
-+{
-+ spin_lock(&glamo->lock);
-+ __reg_set_bit_mask(glamo, reg, mask, val);
-+ spin_unlock(&glamo->lock);
-+}
-+
-+static inline void __reg_set_bit(struct glamo_core *glamo,
-+ u_int16_t reg, u_int16_t bit)
-+{
-+ __reg_set_bit_mask(glamo, reg, bit, 0xffff);
-+}
-+
-+static inline void __reg_clear_bit(struct glamo_core *glamo,
-+ u_int16_t reg, u_int16_t bit)
-+{
-+ __reg_set_bit_mask(glamo, reg, bit, 0);
-+}
-+
-+static inline void glamo_vmem_write(struct glamo_core *glamo, u_int32_t addr,
-+ u_int16_t *src, int len)
-+{
-+ if (addr & 0x0001 || (unsigned long)src & 0x0001 || len & 0x0001) {
-+ dev_err(&glamo->pdev->dev, "unaligned write(0x%08x, 0x%p, "
-+ "0x%x)!!\n", addr, src, len);
-+ }
-+
-+}
-+
-+static inline void glamo_vmem_read(struct glamo_core *glamo, u_int16_t *buf,
-+ u_int32_t addr, int len)
-+{
-+ if (addr & 0x0001 || (unsigned long) buf & 0x0001 || len & 0x0001) {
-+ dev_err(&glamo->pdev->dev, "unaligned read(0x%p, 0x08%x, "
-+ "0x%x)!!\n", buf, addr, len);
-+ }
-+
-+
-+}
-+
-+/***********************************************************************
-+ * resources of sibling devices
-+ ***********************************************************************/
-+
-+#if 0
-+static struct resource glamo_core_resources[] = {
-+ {
-+ .start = GLAMO_REGOFS_GENERIC,
-+ .end = GLAMO_REGOFS_GENERIC + 0x400,
-+ .flags = IORESOURCE_MEM,
-+ }, {
-+ .start = 0,
-+ .end = 0,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device glamo_core_dev = {
-+ .name = "glamo-core",
-+ .resource = &glamo_core_resources,
-+ .num_resources = ARRAY_SIZE(glamo_core_resources),
-+};
-+#endif
-+
-+static struct resource glamo_jpeg_resources[] = {
-+ {
-+ .start = GLAMO_REGOFS_JPEG,
-+ .end = GLAMO_REGOFS_MPEG - 1,
-+ .flags = IORESOURCE_MEM,
-+ }, {
-+ .start = IRQ_GLAMO_JPEG,
-+ .end = IRQ_GLAMO_JPEG,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device glamo_jpeg_dev = {
-+ .name = "glamo-jpeg",
-+ .resource = glamo_jpeg_resources,
-+ .num_resources = ARRAY_SIZE(glamo_jpeg_resources),
-+};
-+
-+static struct resource glamo_mpeg_resources[] = {
-+ {
-+ .start = GLAMO_REGOFS_MPEG,
-+ .end = GLAMO_REGOFS_LCD - 1,
-+ .flags = IORESOURCE_MEM,
-+ }, {
-+ .start = IRQ_GLAMO_MPEG,
-+ .end = IRQ_GLAMO_MPEG,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device glamo_mpeg_dev = {
-+ .name = "glamo-mpeg",
-+ .resource = glamo_mpeg_resources,
-+ .num_resources = ARRAY_SIZE(glamo_mpeg_resources),
-+};
-+
-+static struct resource glamo_2d_resources[] = {
-+ {
-+ .start = GLAMO_REGOFS_2D,
-+ .end = GLAMO_REGOFS_3D - 1,
-+ .flags = IORESOURCE_MEM,
-+ }, {
-+ .start = IRQ_GLAMO_2D,
-+ .end = IRQ_GLAMO_2D,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device glamo_2d_dev = {
-+ .name = "glamo-2d",
-+ .resource = glamo_2d_resources,
-+ .num_resources = ARRAY_SIZE(glamo_2d_resources),
-+};
-+
-+static struct resource glamo_3d_resources[] = {
-+ {
-+ .start = GLAMO_REGOFS_3D,
-+ .end = GLAMO_REGOFS_END - 1,
-+ .flags = IORESOURCE_MEM,
-+ },
-+};
-+
-+static struct platform_device glamo_3d_dev = {
-+ .name = "glamo-3d",
-+ .resource = glamo_3d_resources,
-+ .num_resources = ARRAY_SIZE(glamo_3d_resources),
-+};
-+
-+static struct platform_device glamo_spigpio_dev = {
-+ .name = "glamo-spi-gpio",
-+};
-+
-+static struct resource glamo_fb_resources[] = {
-+ /* FIXME: those need to be incremented by parent base */
-+ {
-+ .name = "glamo-fb-regs",
-+ .start = GLAMO_REGOFS_LCD,
-+ .end = GLAMO_REGOFS_MMC - 1,
-+ .flags = IORESOURCE_MEM,
-+ }, {
-+ .name = "glamo-fb-mem",
-+ .start = GLAMO_OFFSET_FB,
-+ .end = GLAMO_OFFSET_FB + GLAMO_FB_SIZE - 1,
-+ .flags = IORESOURCE_MEM,
-+ },
-+};
-+
-+static struct platform_device glamo_fb_dev = {
-+ .name = "glamo-fb",
-+ .resource = glamo_fb_resources,
-+ .num_resources = ARRAY_SIZE(glamo_fb_resources),
-+};
-+
-+static struct resource glamo_mmc_resources[] = {
-+ {
-+ /* FIXME: those need to be incremented by parent base */
-+ .start = GLAMO_REGOFS_MMC,
-+ .end = GLAMO_REGOFS_MPROC0 - 1,
-+ .flags = IORESOURCE_MEM
-+ }, {
-+ .start = IRQ_GLAMO_MMC,
-+ .end = IRQ_GLAMO_MMC,
-+ .flags = IORESOURCE_IRQ,
-+ }, { /* our data buffer for MMC transfers */
-+ .start = GLAMO_OFFSET_FB + GLAMO_FB_SIZE,
-+ .end = GLAMO_OFFSET_FB + GLAMO_FB_SIZE +
-+ GLAMO_MMC_BUFFER_SIZE - 1,
-+ .flags = IORESOURCE_MEM
-+ },
-+};
-+
-+static struct platform_device glamo_mmc_dev = {
-+ .name = "glamo-mci",
-+ .resource = glamo_mmc_resources,
-+ .num_resources = ARRAY_SIZE(glamo_mmc_resources),
-+};
-+
-+struct glamo_mci_pdata glamo_mci_def_pdata = {
-+ .gpio_detect = 0,
-+ .glamo_set_mci_power = NULL, /* filled in from MFD platform data */
-+ .ocr_avail = MMC_VDD_32_33,
-+ .glamo_irq_is_wired = NULL, /* filled in from MFD platform data */
-+};
-+EXPORT_SYMBOL_GPL(glamo_mci_def_pdata);
-+
-+
-+
-+static void mangle_mem_resources(struct resource *res, int num_res,
-+ struct resource *parent)
-+{
-+ int i;
-+
-+ for (i = 0; i < num_res; i++) {
-+ if (res[i].flags != IORESOURCE_MEM)
-+ continue;
-+ res[i].start += parent->start;
-+ res[i].end += parent->start;
-+ res[i].parent = parent;
-+ }
-+}
-+
-+/***********************************************************************
-+ * IRQ demultiplexer
-+ ***********************************************************************/
-+#define irq2glamo(x) (x - IRQ_GLAMO(0))
-+
-+static void glamo_ack_irq(unsigned int irq)
-+{
-+ /* clear interrupt source */
-+ __reg_write(glamo_handle, GLAMO_REG_IRQ_CLEAR,
-+ 1 << irq2glamo(irq));
-+}
-+
-+static void glamo_mask_irq(unsigned int irq)
-+{
-+ u_int16_t tmp;
-+
-+ /* clear bit in enable register */
-+ tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
-+ tmp &= ~(1 << irq2glamo(irq));
-+ __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
-+}
-+
-+static void glamo_unmask_irq(unsigned int irq)
-+{
-+ u_int16_t tmp;
-+
-+ /* set bit in enable register */
-+ tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
-+ tmp |= (1 << irq2glamo(irq));
-+ __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
-+}
-+
-+static struct irq_chip glamo_irq_chip = {
-+ .ack = glamo_ack_irq,
-+ .mask = glamo_mask_irq,
-+ .unmask = glamo_unmask_irq,
-+};
-+
-+static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
-+{
-+ const unsigned int cpu = smp_processor_id();
-+
-+ spin_lock(&desc->lock);
-+
-+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-+
-+ if (unlikely(desc->status & IRQ_INPROGRESS)) {
-+ desc->status |= (IRQ_PENDING | IRQ_MASKED);
-+ desc->chip->mask(irq);
-+ desc->chip->ack(irq);
-+ goto out_unlock;
-+ }
-+
-+ kstat_cpu(cpu).irqs[irq]++;
-+ desc->chip->ack(irq);
-+ desc->status |= IRQ_INPROGRESS;
-+
-+ do {
-+ u_int16_t irqstatus;
-+ int i;
-+
-+ if (unlikely((desc->status &
-+ (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
-+ (IRQ_PENDING | IRQ_MASKED))) {
-+ /* dealing with pending IRQ, unmasking */
-+ desc->chip->unmask(irq);
-+ desc->status &= ~IRQ_MASKED;
-+ }
-+
-+ desc->status &= ~IRQ_PENDING;
-+
-+ /* read IRQ status register */
-+ irqstatus = __reg_read(glamo_handle, GLAMO_REG_IRQ_STATUS);
-+ for (i = 0; i < 9; i++)
-+ if (irqstatus & (1 << i))
-+ desc_handle_irq(IRQ_GLAMO(i),
-+ irq_desc+IRQ_GLAMO(i));
-+
-+ } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
-+
-+ desc->status &= ~IRQ_INPROGRESS;
-+
-+out_unlock:
-+ spin_unlock(&desc->lock);
-+}
-+
-+/***********************************************************************
-+ * 'engine' support
-+ ***********************************************************************/
-+
-+int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
-+{
-+ spin_lock(&glamo->lock);
-+ switch (engine) {
-+ case GLAMO_ENGINE_LCD:
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
-+ GLAMO_CLOCK_LCD_EN_M5CLK |
-+ GLAMO_CLOCK_LCD_EN_DHCLK |
-+ GLAMO_CLOCK_LCD_EN_DMCLK |
-+ GLAMO_CLOCK_LCD_EN_DCLK |
-+ GLAMO_CLOCK_LCD_DG_M5CLK |
-+ GLAMO_CLOCK_LCD_DG_DMCLK, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
-+ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK |
-+ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK |
-+ GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
-+ GLAMO_HOSTBUS2_MMIO_EN_LCD,
-+ 0xffff);
-+ break;
-+ case GLAMO_ENGINE_MMC:
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC,
-+ GLAMO_CLOCK_MMC_EN_M9CLK |
-+ GLAMO_CLOCK_MMC_EN_TCLK |
-+ GLAMO_CLOCK_MMC_DG_M9CLK |
-+ GLAMO_CLOCK_MMC_DG_TCLK, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
-+ GLAMO_HOSTBUS2_MMIO_EN_MMC,
-+ GLAMO_HOSTBUS2_MMIO_EN_MMC);
-+ break;
-+ case GLAMO_ENGINE_2D:
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
-+ GLAMO_CLOCK_2D_EN_M7CLK |
-+ GLAMO_CLOCK_2D_EN_GCLK |
-+ GLAMO_CLOCK_2D_DG_M7CLK |
-+ GLAMO_CLOCK_2D_DG_GCLK, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
-+ GLAMO_HOSTBUS2_MMIO_EN_2D,
-+ GLAMO_HOSTBUS2_MMIO_EN_2D);
-+ break;
-+ case GLAMO_ENGINE_CMDQ:
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
-+ GLAMO_CLOCK_2D_EN_M6CLK, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
-+ GLAMO_HOSTBUS2_MMIO_EN_CQ,
-+ GLAMO_HOSTBUS2_MMIO_EN_CQ);
-+ break;
-+ /* FIXME: Implementation */
-+ default:
-+ break;
-+ }
-+ spin_unlock(&glamo->lock);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(glamo_engine_enable);
-+
-+int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
-+{
-+ spin_lock(&glamo->lock);
-+ switch (engine) {
-+ /* FIXME: Implementation */
-+ default:
-+ break;
-+ }
-+ spin_unlock(&glamo->lock);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(glamo_engine_disable);
-+
-+struct glamo_script reset_regs[] = {
-+ [GLAMO_ENGINE_LCD] = {
-+ GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET
-+ },
-+#if 0
-+ [GLAMO_ENGINE_HOST] = {
-+ GLAMO_REG_CLOCK_HOST, GLAMO_CLOCK_HOST_RESET
-+ },
-+ [GLAMO_ENGINE_MEM] = {
-+ GLAMO_REG_CLOCK_MEM, GLAMO_CLOCK_MEM_RESET
-+ },
-+#endif
-+ [GLAMO_ENGINE_MMC] = {
-+ GLAMO_REG_CLOCK_MMC, GLAMO_CLOCK_MMC_RESET
-+ },
-+ [GLAMO_ENGINE_2D] = {
-+ GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_RESET
-+ },
-+ [GLAMO_ENGINE_JPEG] = {
-+ GLAMO_REG_CLOCK_JPEG, GLAMO_CLOCK_JPEG_RESET
-+ },
-+};
-+
-+void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine)
-+{
-+ struct glamo_script *rst;
-+
-+ if (engine >= ARRAY_SIZE(reset_regs)) {
-+ dev_warn(&glamo->pdev->dev, "unknown engine %u ", engine);
-+ return;
-+ }
-+
-+ rst = &reset_regs[engine];
-+
-+ spin_lock(&glamo->lock);
-+ __reg_set_bit(glamo, rst->reg, rst->val);
-+ spin_unlock(&glamo->lock);
-+
-+ msleep(1);
-+
-+ spin_lock(&glamo->lock);
-+ __reg_clear_bit(glamo, rst->reg, rst->val);
-+ spin_unlock(&glamo->lock);
-+
-+ msleep(1);
-+}
-+EXPORT_SYMBOL_GPL(glamo_engine_reset);
-+
-+enum glamo_pll {
-+ GLAMO_PLL1,
-+ GLAMO_PLL2,
-+};
-+
-+static int glamo_pll_rate(struct glamo_core *glamo,
-+ enum glamo_pll pll)
-+{
-+ u_int16_t reg;
-+ unsigned int div = 512;
-+ /* FIXME: move osci into platform_data */
-+ unsigned int osci = 32768;
-+
-+ if (osci == 32768)
-+ div = 1;
-+
-+ switch (pll) {
-+ case GLAMO_PLL1:
-+ reg = __reg_read(glamo, GLAMO_REG_PLL_GEN1);
-+ break;
-+ case GLAMO_PLL2:
-+ reg = __reg_read(glamo, GLAMO_REG_PLL_GEN3);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ return (osci/div)*reg;
-+}
-+
-+int glamo_engine_reclock(struct glamo_core *glamo,
-+ enum glamo_engine engine,
-+ int ps)
-+{
-+ int pll, khz;
-+ u_int16_t reg, mask, val = 0;
-+
-+ if (!ps)
-+ return 0;
-+
-+ switch (engine) {
-+ case GLAMO_ENGINE_LCD:
-+ pll = GLAMO_PLL1;
-+ reg = GLAMO_REG_CLOCK_GEN7;
-+ mask = 0xff;
-+ break;
-+ default:
-+ dev_warn(&glamo->pdev->dev,
-+ "reclock of engine 0x%x not supported\n", engine);
-+ return -EINVAL;
-+ break;
-+ }
-+
-+ pll = glamo_pll_rate(glamo, pll);
-+ khz = 1000000000UL / ps;
-+
-+ if (khz)
-+ val = (pll / khz) / 1000;
-+
-+ dev_dbg(&glamo->pdev->dev,
-+ "PLL %d, kHZ %d, div %d\n", pll, khz, val);
-+
-+ if (val) {
-+ val--;
-+ reg_set_bit_mask(glamo, reg, mask, val);
-+ msleep(5); /* wait some time to stabilize */
-+
-+ return 0;
-+ } else {
-+ return -EINVAL;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(glamo_engine_reclock);
-+
-+/***********************************************************************
-+ * script support
-+ ***********************************************************************/
-+
-+int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
-+ int len, int may_sleep)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ struct glamo_script *line = &script[i];
-+
-+ switch (line->reg) {
-+ case 0xffff:
-+ return 0;
-+ case 0xfffe:
-+ if (may_sleep)
-+ msleep(line->val);
-+ else
-+ mdelay(line->val);
-+ break;
-+ case 0xfffd:
-+ /* spin until PLLs lock */
-+ while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
-+ ;
-+ break;
-+ default:
-+ __reg_write(glamo, script[i].reg, script[i].val);
-+ break;
-+ }
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(glamo_run_script);
-+
-+static struct glamo_script glamo_init_script[] = {
-+ { GLAMO_REG_CLOCK_HOST, 0x1000 },
-+ { 0xfffe, 2 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x1000 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x2000 },
-+ { GLAMO_REG_CLOCK_LCD, 0x1000 },
-+ { GLAMO_REG_CLOCK_MMC, 0x1000 },
-+ { GLAMO_REG_CLOCK_ISP, 0x1000 },
-+ { GLAMO_REG_CLOCK_ISP, 0x3000 },
-+ { GLAMO_REG_CLOCK_JPEG, 0x1000 },
-+ { GLAMO_REG_CLOCK_3D, 0x1000 },
-+ { GLAMO_REG_CLOCK_3D, 0x3000 },
-+ { GLAMO_REG_CLOCK_2D, 0x1000 },
-+ { GLAMO_REG_CLOCK_2D, 0x3000 },
-+ { GLAMO_REG_CLOCK_RISC1, 0x1000 },
-+ { GLAMO_REG_CLOCK_MPEG, 0x3000 },
-+ { GLAMO_REG_CLOCK_MPEG, 0x3000 },
-+ { GLAMO_REG_CLOCK_MPROC, 0x1000 /*0x100f*/ },
-+ { 0xfffe, 2 },
-+ { GLAMO_REG_CLOCK_HOST, 0x0000 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x0000 },
-+ { GLAMO_REG_CLOCK_LCD, 0x0000 },
-+ { GLAMO_REG_CLOCK_MMC, 0x0000 },
-+#if 0
-+/* unused engines must be left in reset to stop MMC block read "blackouts" */
-+ { GLAMO_REG_CLOCK_ISP, 0x0000 },
-+ { GLAMO_REG_CLOCK_ISP, 0x0000 },
-+ { GLAMO_REG_CLOCK_JPEG, 0x0000 },
-+ { GLAMO_REG_CLOCK_3D, 0x0000 },
-+ { GLAMO_REG_CLOCK_3D, 0x0000 },
-+ { GLAMO_REG_CLOCK_2D, 0x0000 },
-+ { GLAMO_REG_CLOCK_2D, 0x0000 },
-+ { GLAMO_REG_CLOCK_RISC1, 0x0000 },
-+ { GLAMO_REG_CLOCK_MPEG, 0x0000 },
-+ { GLAMO_REG_CLOCK_MPEG, 0x0000 },
-+#endif
-+ { GLAMO_REG_PLL_GEN1, 0x05db }, /* 48MHz */
-+ { GLAMO_REG_PLL_GEN3, 0x09c3 }, /* 80MHz */
-+ { 0xfffd, 0 },
-+ /*
-+ * b9 of this register MUST be zero to get any interrupts on INT#
-+ * the other set bits enable all the engine interrupt sources
-+ */
-+ { GLAMO_REG_IRQ_ENABLE, 0x01ff },
-+ { GLAMO_REG_CLOCK_GEN6, 0x2000 },
-+ { GLAMO_REG_CLOCK_GEN7, 0x0101 },
-+ { GLAMO_REG_CLOCK_GEN8, 0x0100 },
-+ { GLAMO_REG_CLOCK_HOST, 0x000d },
-+ { 0x200, 0x0ef0 },
-+ { 0x202, 0x07ff },
-+ { 0x212, 0x0000 },
-+ { 0x214, 0x4000 },
-+ { 0x216, 0xf00e },
-+ { GLAMO_REG_MEM_TYPE, 0x0874 }, /* 8MB, 16 word pg wr+rd */
-+ { GLAMO_REG_MEM_GEN, 0xafaf }, /* 63 grants min + max */
-+ /*
-+ * the register below originally 0x0108 makes unreliable Glamo MMC
-+ * write operations. Cranked to 0x05ad to add a wait state, the
-+ * unreliability is not seen after 4GB of write / read testing
-+ */
-+ { GLAMO_REG_MEM_TIMING1, 0x0108 },
-+ { GLAMO_REG_MEM_TIMING2, 0x0010 }, /* Taa = 3 MCLK */
-+ { GLAMO_REG_MEM_TIMING3, 0x0000 },
-+ { GLAMO_REG_MEM_TIMING4, 0x0000 }, /* CE1# delay fall/rise */
-+ { GLAMO_REG_MEM_TIMING5, 0x0000 }, /* UB# LB# */
-+ { GLAMO_REG_MEM_TIMING6, 0x0000 }, /* OE# */
-+ { GLAMO_REG_MEM_TIMING7, 0x0000 }, /* WE# */
-+ { GLAMO_REG_MEM_TIMING8, 0x1002 }, /* MCLK delay, was 0x1000 */
-+ { GLAMO_REG_MEM_TIMING9, 0x6006 },
-+ { GLAMO_REG_MEM_TIMING10, 0x00ff },
-+ { GLAMO_REG_MEM_TIMING11, 0x0001 },
-+ { GLAMO_REG_MEM_POWER1, 0x0020 },
-+ { GLAMO_REG_MEM_POWER2, 0x0000 },
-+ { GLAMO_REG_MEM_DRAM1, 0x0000 },
-+ { 0xfffe, 1 },
-+ { GLAMO_REG_MEM_DRAM1, 0xc100 },
-+ { 0xfffe, 1 },
-+ { GLAMO_REG_MEM_DRAM1, 0xe100 },
-+ { GLAMO_REG_MEM_DRAM2, 0x01d6 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x000b },
-+};
-+
-+static struct glamo_script glamo_resume_script[] = {
-+ { GLAMO_REG_IRQ_ENABLE, 0x01ff },
-+ { GLAMO_REG_CLOCK_GEN6, 0x2000 },
-+ { GLAMO_REG_CLOCK_GEN7, 0x0001 }, /* 0101 */
-+ { GLAMO_REG_CLOCK_GEN8, 0x0100 },
-+ { GLAMO_REG_CLOCK_HOST, 0x000d },
-+ { 0x200, 0x0ef0 },
-+ { 0x202, 0x07ff },
-+ { 0x212, 0x0000 },
-+ { 0x214, 0x4000 },
-+ { 0x216, 0xf00e },
-+ { GLAMO_REG_MEM_TYPE, 0x0874 }, /* 8MB, 16 word pg wr+rd */
-+ { GLAMO_REG_MEM_GEN, 0xafaf }, /* 63 grants min + max */
-+
-+ { GLAMO_REG_MEM_TIMING1, 0x0108 },
-+ { GLAMO_REG_MEM_TIMING2, 0x0010 }, /* Taa = 3 MCLK */
-+ { GLAMO_REG_MEM_TIMING3, 0x0000 },
-+ { GLAMO_REG_MEM_TIMING4, 0x0000 }, /* CE1# delay fall/rise */
-+ { GLAMO_REG_MEM_TIMING5, 0x0000 }, /* UB# LB# */
-+ { GLAMO_REG_MEM_TIMING6, 0x0000 }, /* OE# */
-+ { GLAMO_REG_MEM_TIMING7, 0x0000 }, /* WE# */
-+ { GLAMO_REG_MEM_TIMING8, 0x1002 }, /* MCLK delay, was 0x1000 */
-+ { GLAMO_REG_MEM_TIMING9, 0x6006 },
-+ { GLAMO_REG_MEM_TIMING10, 0x00ff },
-+ { GLAMO_REG_MEM_TIMING11, 0x0001 },
-+ { GLAMO_REG_MEM_POWER1, 0x0020 },
-+ { GLAMO_REG_MEM_POWER2, 0x0000 },
-+ { GLAMO_REG_MEM_DRAM1, 0x0000 },
-+ { 0xfffe, 1 },
-+ { GLAMO_REG_MEM_DRAM1, 0xc100 },
-+ { 0xfffe, 1 },
-+ { GLAMO_REG_MEM_DRAM1, 0xe100 },
-+ { GLAMO_REG_MEM_DRAM2, 0x01d6 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x000b },
-+};
-+
-+#if 0 /* MM370 */
-+static const struct glamo_script regs_vram_2mb = {
-+ { GLAMO_REG_CLOCK_MEMORY, 0x3aaa },
-+ { 0xfffe, 50 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x0aaa },
-+ { 0xfffe, 3 },
-+ { GLAMO_REG_MEM_POWER1, 0x0020 },
-+ { 0x033a, 0x0000 },
-+ { 0x033c, 0x0000 },
-+ { 0x033e, 0x0000 },
-+ { 0x0340, 0x0000 },
-+ { 0x0342, 0x0000 },
-+ { 0x0344, 0x0000 },
-+ { 0x0346, 0x0240 },
-+ { GLAMO_REG_MEM_TIMING8, 0x1016 },
-+ { GLAMO_REG_MEM_TIMING9, 0x6067 },
-+ { GLAMO_REG_MEM_TIMING10, 0x00ff },
-+ { GLAMO_REG_MEM_TIMING11, 0x0030 },
-+ { GLAMO_REG_MEM_GEN, 0x3fff },
-+ { GLAMO_REG_MEM_GEN, 0xafaf },
-+ { GLAMO_REG_MEM_TIMING1, 0x0108 },
-+ { GLAMO_REG_MEM_TIMING2, 0x0010 },
-+ { GLAMO_REG_MEM_DRAM1, 0x0a00 },
-+ { 0xfffe, 3 },
-+ { GLAMO_REG_MEM_DRAM1, 0xe200 },
-+ { 0xfffe, 1 },
-+};
-+
-+static const struct glamo_script regs_vram_8mb = {
-+ { GLAMO_REG_CLOCK_MEMORY, 0x3aaa },
-+ { 0xfffe, 50 },
-+ { GLAMO_REG_CLOCK_MEMORY, 0x0aaa },
-+ { 0xfffe, 3 },
-+ { GLAMO_REG_MEM_POWER1, 0x0020 },
-+ { 0x033a, 0x45cf },
-+ { 0x033c, 0x4240 },
-+ { 0x033e, 0x53e0 },
-+ { 0x0340, 0x1401 },
-+ { 0x0342, 0x0c44 },
-+ { 0x0344, 0x1d0b },
-+ { 0x0346, 0x25ac },
-+ { 0x0348, 0x1953 },
-+ { 0xfffe, 1 },
-+ { GLAMO_REG_MEM_TYPE, 0x087a },
-+ { GLAMO_REG_MEM_DRAM2, 0x01d6 },
-+ { GLAMO_REG_MEM_TIMING8, 0x1060 },
-+ { GLAMO_REG_MEM_TIMING9, 0x6067 },
-+ { GLAMO_REG_MEM_TIMING10, 0x00ff },
-+ { GLAMO_REG_MEM_TIMING11, 0x0030 },
-+ { GLAMO_REG_MEM_GEN, 0x3fff },
-+ { GLAMO_REG_MEM_GEN, 0xafaf },
-+ { GLAMO_REG_MEM_TIMING1, 0x3108 },
-+ { GLAMO_REG_MEM_TIMING2, 0x0010 },
-+ { GLAMO_REG_MEM_DRAM1, 0x0a00 },
-+ { 0xfffe, 3 },
-+ { GLAMO_REG_MEM_DRAM1, 0xe200 },
-+ { 0xfffe, 1 },
-+};
-+#endif
-+
-+enum glamo_power {
-+ GLAMO_POWER_ON,
-+ GLAMO_POWER_STANDBY,
-+ GLAMO_POWER_SUSPEND,
-+};
-+
-+static void glamo_power(struct glamo_core *glamo,
-+ enum glamo_power new_state)
-+{
-+ spin_lock(&glamo->lock);
-+
-+ switch (new_state) {
-+ case GLAMO_POWER_ON:
-+ /* power up PLL1 and PLL2 */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN6, 0x0001, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0x0000);
-+
-+ /* spin until PLL1 and PLL2 lock */
-+ while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
-+ ;
-+
-+ /* enable memory clock and get it out of deep pwrdown */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
-+ GLAMO_CLOCK_MEM_EN_MOCACLK, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
-+ GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0x0000);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
-+ GLAMO_MEM_DRAM1_SELF_REFRESH, 0x0000);
-+
-+ glamo_run_script(glamo, glamo_resume_script,
-+ ARRAY_SIZE(glamo_resume_script), 0);
-+
-+ break;
-+ case GLAMO_POWER_STANDBY:
-+ /* enable memory self-refresh */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
-+ GLAMO_MEM_DRAM1_SELF_REFRESH, 0xffff);
-+ /* stop memory clock */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
-+ GLAMO_CLOCK_MEM_EN_MOCACLK, 0x0000);
-+ /* power down PLL2 and then PLL1 */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
-+ break;
-+ case GLAMO_POWER_SUSPEND:
-+ __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
-+ GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0xffff);
-+ /* stop memory clock */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
-+ GLAMO_CLOCK_MEM_EN_MOCACLK, 0x0000);
-+ /* power down PLL2 and then PLL1 */
-+ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
-+ __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
-+ break;
-+ }
-+
-+ spin_unlock(&glamo->lock);
-+}
-+
-+#if 0
-+#define MEMDETECT_RETRY 6
-+static unsigned int detect_memsize(struct glamo_core *glamo)
-+{
-+ int i;
-+
-+ /*static const u_int16_t pattern[] = {
-+ 0x1111, 0x8a8a, 0x2222, 0x7a7a,
-+ 0x3333, 0x6a6a, 0x4444, 0x5a5a,
-+ 0x5555, 0x4a4a, 0x6666, 0x3a3a,
-+ 0x7777, 0x2a2a, 0x8888, 0x1a1a
-+ }; */
-+
-+ for (i = 0; i < MEMDETECT_RETRY; i++) {
-+ switch (glamo->type) {
-+ case 3600:
-+ __reg_write(glamo, GLAMO_REG_MEM_TYPE, 0x0072);
-+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100);
-+ break;
-+ case 3650:
-+ switch (glamo->revision) {
-+ case GLAMO_CORE_REV_A0:
-+ if (i & 1)
-+ __reg_write(glamo, GLAMO_REG_MEM_TYPE,
-+ 0x097a);
-+ else
-+ __reg_write(glamo, GLAMO_REG_MEM_TYPE,
-+ 0x0173);
-+
-+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000);
-+ msleep(1);
-+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100);
-+ break;
-+ default:
-+ if (i & 1)
-+ __reg_write(glamo, GLAMO_REG_MEM_TYPE,
-+ 0x0972);
-+ else
-+ __reg_write(glamo, GLAMO_REG_MEM_TYPE,
-+ 0x0872);
-+
-+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000);
-+ msleep(1);
-+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xe100);
-+ break;
-+ }
-+ break;
-+ case 3700:
-+ /* FIXME */
-+ default:
-+ break;
-+ }
-+
-+#if 0
-+ /* FIXME: finish implementation */
-+ for (j = 0; j < 8; j++) {
-+ __
-+#endif
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+/* Find out if we can support this version of the Glamo chip */
-+static int glamo_supported(struct glamo_core *glamo)
-+{
-+ u_int16_t dev_id, rev_id; /*, memsize; */
-+
-+ dev_id = __reg_read(glamo, GLAMO_REG_DEVICE_ID);
-+ rev_id = __reg_read(glamo, GLAMO_REG_REVISION_ID);
-+
-+ switch (dev_id) {
-+ case 0x3650:
-+ switch (rev_id) {
-+ case GLAMO_CORE_REV_A2:
-+ break;
-+ case GLAMO_CORE_REV_A0:
-+ case GLAMO_CORE_REV_A1:
-+ case GLAMO_CORE_REV_A3:
-+ dev_warn(&glamo->pdev->dev, "untested core revision "
-+ "%04x, your mileage may vary\n", rev_id);
-+ break;
-+ default:
-+ dev_warn(&glamo->pdev->dev, "unknown glamo revision "
-+ "%04x, your mileage may vary\n", rev_id);
-+ /* maybe should abort ? */
-+ }
-+ break;
-+ case 0x3600:
-+ case 0x3700:
-+ default:
-+ dev_err(&glamo->pdev->dev, "unsupported Glamo device %04x\n",
-+ dev_id);
-+ return 0;
-+ }
-+
-+ dev_info(&glamo->pdev->dev, "Detected Glamo core %04x Revision %04x "
-+ "(%uHz CPU / %uHz Memory)\n", dev_id, rev_id,
-+ glamo_pll_rate(glamo, GLAMO_PLL1),
-+ glamo_pll_rate(glamo, GLAMO_PLL2));
-+
-+ return 1;
-+}
-+
-+
-+static int __init glamo_probe(struct platform_device *pdev)
-+{
-+ int rc, irq;
-+ struct glamo_core *glamo;
-+
-+ if (glamo_handle) {
-+ dev_err(&pdev->dev,
-+ "This driver supports only one instance\n");
-+ return -EBUSY;
-+ }
-+
-+ glamo = kmalloc(GFP_KERNEL, sizeof(*glamo));
-+ if (!glamo)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&glamo->lock);
-+ glamo_handle = glamo;
-+ glamo->pdev = pdev;
-+ glamo->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ glamo->irq = platform_get_irq(pdev, 0);
-+ glamo->pdata = pdev->dev.platform_data;
-+ if (!glamo->mem || !glamo->pdata) {
-+ dev_err(&pdev->dev, "platform device with no MEM/PDATA ?\n");
-+ rc = -ENOENT;
-+ goto out_free;
-+ }
-+
-+ /* register a number of sibling devices whoise IOMEM resources
-+ * are siblings of pdev's IOMEM resource */
-+#if 0
-+ glamo_core_dev.dev.parent = &pdev.dev;
-+ mangle_mem_resources(glamo_core_dev.resources,
-+ glamo_core_dev.num_resources, glamo->mem);
-+ glamo_core_dev.resources[1].start = glamo->irq;
-+ glamo_core_dev.resources[1].end = glamo->irq;
-+ platform_device_register(&glamo_core_dev);
-+#endif
-+ /* only remap the generic, hostbus and memory controller registers */
-+ glamo->base = ioremap(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
-+ if (!glamo->base) {
-+ dev_err(&pdev->dev, "failed to ioremap() memory region\n");
-+ goto out_free;
-+ }
-+
-+ /* bring MCI specific stuff over from our MFD platform data */
-+ glamo_mci_def_pdata.glamo_set_mci_power =
-+ glamo->pdata->glamo_set_mci_power;
-+ glamo_mci_def_pdata.glamo_irq_is_wired =
-+ glamo->pdata->glamo_irq_is_wired;
-+
-+ glamo_mmc_dev.dev.parent = &pdev->dev;
-+ /* we need it later to give to the engine enable and disable */
-+ glamo_mci_def_pdata.pglamo = glamo;
-+ mangle_mem_resources(glamo_mmc_dev.resource,
-+ glamo_mmc_dev.num_resources, glamo->mem);
-+ platform_device_register(&glamo_mmc_dev);
-+
-+ glamo_2d_dev.dev.parent = &pdev->dev;
-+ mangle_mem_resources(glamo_2d_dev.resource,
-+ glamo_2d_dev.num_resources, glamo->mem);
-+ platform_device_register(&glamo_2d_dev);
-+
-+ glamo_3d_dev.dev.parent = &pdev->dev;
-+ mangle_mem_resources(glamo_3d_dev.resource,
-+ glamo_3d_dev.num_resources, glamo->mem);
-+ platform_device_register(&glamo_3d_dev);
-+
-+ glamo_jpeg_dev.dev.parent = &pdev->dev;
-+ mangle_mem_resources(glamo_jpeg_dev.resource,
-+ glamo_jpeg_dev.num_resources, glamo->mem);
-+ platform_device_register(&glamo_jpeg_dev);
-+
-+ glamo_mpeg_dev.dev.parent = &pdev->dev;
-+ mangle_mem_resources(glamo_mpeg_dev.resource,
-+ glamo_mpeg_dev.num_resources, glamo->mem);
-+ platform_device_register(&glamo_mpeg_dev);
-+
-+ glamo->pdata->glamo = glamo;
-+ glamo_fb_dev.dev.parent = &pdev->dev;
-+ glamo_fb_dev.dev.platform_data = glamo->pdata;
-+ mangle_mem_resources(glamo_fb_dev.resource,
-+ glamo_fb_dev.num_resources, glamo->mem);
-+ platform_device_register(&glamo_fb_dev);
-+
-+ glamo->pdata->spigpio_info->glamo = glamo;
-+ glamo_spigpio_dev.dev.parent = &pdev->dev;
-+ glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
-+ platform_device_register(&glamo_spigpio_dev);
-+
-+ /* only request the generic, hostbus and memory controller MMIO */
-+ glamo->mem = request_mem_region(glamo->mem->start,
-+ GLAMO_REGOFS_VIDCAP, "glamo-core");
-+ if (!glamo->mem) {
-+ dev_err(&pdev->dev, "failed to request memory region\n");
-+ goto out_free;
-+ }
-+
-+ if (!glamo_supported(glamo)) {
-+ dev_err(&pdev->dev, "This Glamo is not supported\n");
-+ goto out_free;
-+ }
-+
-+ platform_set_drvdata(pdev, glamo);
-+
-+ dev_dbg(&glamo->pdev->dev, "running init script\n");
-+ glamo_run_script(glamo, glamo_init_script,
-+ ARRAY_SIZE(glamo_init_script), 1);
-+
-+ dev_info(&glamo->pdev->dev, "Glamo core now %uHz CPU / %uHz Memory)\n",
-+ glamo_pll_rate(glamo, GLAMO_PLL1),
-+ glamo_pll_rate(glamo, GLAMO_PLL2));
-+
-+ for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
-+ set_irq_chip(irq, &glamo_irq_chip);
-+ set_irq_handler(irq, handle_level_irq);
-+ set_irq_flags(irq, IRQF_VALID);
-+ }
-+
-+ if (glamo->pdata->glamo_irq_is_wired &&
-+ !glamo->pdata->glamo_irq_is_wired()) {
-+ set_irq_chained_handler(glamo->irq, glamo_irq_demux_handler);
-+ set_irq_type(glamo->irq, IRQT_FALLING);
-+ glamo->irq_works = 1;
-+ } else
-+ glamo->irq_works = 0;
-+ return 0;
-+
-+out_free:
-+ glamo_handle = NULL;
-+ kfree(glamo);
-+ return rc;
-+}
-+
-+static int glamo_remove(struct platform_device *pdev)
-+{
-+ struct glamo_core *glamo = platform_get_drvdata(pdev);
-+ int irq;
-+
-+ disable_irq(glamo->irq);
-+ set_irq_chained_handler(glamo->irq, NULL);
-+
-+ for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
-+ set_irq_flags(irq, 0);
-+ set_irq_chip(irq, NULL);
-+ }
-+
-+ platform_set_drvdata(pdev, NULL);
-+ platform_device_unregister(&glamo_fb_dev);
-+ platform_device_unregister(&glamo_mmc_dev);
-+ iounmap(glamo->base);
-+ release_mem_region(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
-+ glamo_handle = NULL;
-+ kfree(glamo);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+ return 0;
-+}
-+
-+static int glamo_resume(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+#else
-+#define glamo_suspend NULL
-+#define glamo_resume NULL
-+#endif
-+
-+static struct platform_driver glamo_driver = {
-+ .probe = glamo_probe,
-+ .remove = glamo_remove,
-+ .suspend = glamo_suspend,
-+ .resume = glamo_resume,
-+ .driver = {
-+ .name = "glamo3362",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __devinit glamo_init(void)
-+{
-+ return platform_driver_register(&glamo_driver);
-+}
-+
-+static void __exit glamo_cleanup(void)
-+{
-+ platform_driver_unregister(&glamo_driver);
-+}
-+
-+module_init(glamo_init);
-+module_exit(glamo_cleanup);
-+
-+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
-+MODULE_DESCRIPTION("Smedia Glamo 336x/337x core/resource driver");
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
-new file mode 100644
-index 0000000..cf89f03
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-core.h
-@@ -0,0 +1,91 @@
-+#ifndef __GLAMO_CORE_H
-+#define __GLAMO_CORE_H
-+
-+#include <asm/system.h>
-+
-+
-+/* for the time being, we put the on-screen framebuffer into the lowest
-+ * VRAM space. This should make the code easily compatible with the various
-+ * 2MB/4MB/8MB variants of the Smedia chips */
-+#define GLAMO_OFFSET_VRAM 0x800000
-+#define GLAMO_OFFSET_FB (GLAMO_OFFSET_VRAM)
-+
-+/* we only allocate the minimum possible size for the framebuffer to make
-+ * sure we have sufficient memory for other functions of the chip */
-+//#define GLAMO_FB_SIZE (640*480*4) /* == 0x12c000 */
-+#define GLAMO_INTERNAL_RAM_SIZE 0x800000
-+#define GLAMO_MMC_BUFFER_SIZE (64 * 1024)
-+#define GLAMO_FB_SIZE (GLAMO_INTERNAL_RAM_SIZE - GLAMO_MMC_BUFFER_SIZE)
-+
-+
-+struct glamo_core {
-+ int irq;
-+ int irq_works; /* 0 means PCB does not support Glamo IRQ */
-+ struct resource *mem;
-+ struct resource *mem_core;
-+ void __iomem *base;
-+ struct platform_device *pdev;
-+ struct glamofb_platform_data *pdata;
-+ u_int16_t type;
-+ u_int16_t revision;
-+ spinlock_t lock;
-+};
-+
-+struct glamo_script {
-+ u_int16_t reg;
-+ u_int16_t val;
-+};
-+
-+int glamo_run_script(struct glamo_core *glamo,
-+ struct glamo_script *script, int len, int may_sleep);
-+
-+enum glamo_engine {
-+ GLAMO_ENGINE_CAPTURE,
-+ GLAMO_ENGINE_ISP,
-+ GLAMO_ENGINE_JPEG,
-+ GLAMO_ENGINE_MPEG_ENC,
-+ GLAMO_ENGINE_MPEG_DEC,
-+ GLAMO_ENGINE_LCD,
-+ GLAMO_ENGINE_CMDQ,
-+ GLAMO_ENGINE_2D,
-+ GLAMO_ENGINE_3D,
-+ GLAMO_ENGINE_MMC,
-+ GLAMO_ENGINE_MICROP0,
-+ GLAMO_ENGINE_RISC,
-+ GLAMO_ENGINE_MICROP1_MPEG_ENC,
-+ GLAMO_ENGINE_MICROP1_MPEG_DEC,
-+#if 0
-+ GLAMO_ENGINE_H264_DEC,
-+ GLAMO_ENGINE_RISC1,
-+ GLAMO_ENGINE_SPI,
-+#endif
-+ __NUM_GLAMO_ENGINES
-+};
-+
-+struct glamo_mci_pdata {
-+ struct glamo_core * pglamo;
-+ unsigned int gpio_detect;
-+ unsigned int gpio_wprotect;
-+ unsigned long ocr_avail;
-+ void (*glamo_set_mci_power)(unsigned char power_mode,
-+ unsigned short vdd);
-+ int (*glamo_irq_is_wired)(void);
-+};
-+
-+
-+static inline void glamo_reg_access_delay(void)
-+{
-+ int n;
-+
-+ for (n = 0; n != 2; n++)
-+ nop();
-+}
-+
-+
-+int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine);
-+int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine);
-+void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine);
-+int glamo_engine_reclock(struct glamo_core *glamo,
-+ enum glamo_engine engine, int ps);
-+
-+#endif /* __GLAMO_CORE_H */
-diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
-new file mode 100644
-index 0000000..394a0ad
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-fb.c
-@@ -0,0 +1,822 @@
-+/* Smedia Glamo 336x/337x driver
-+ *
-+ * (C) 2007 by OpenMoko, Inc.
-+ * Author: Harald Welte <laforge@openmoko.org>
-+ * All rights reserved.
-+ *
-+ * 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 <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/fb.h>
-+#include <linux/init.h>
-+#include <linux/vmalloc.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/interrupt.h>
-+#include <linux/workqueue.h>
-+#include <linux/wait.h>
-+#include <linux/platform_device.h>
-+#include <linux/clk.h>
-+
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <asm/div64.h>
-+
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+#endif
-+
-+#include <linux/glamofb.h>
-+
-+#include "glamo-regs.h"
-+#include "glamo-core.h"
-+
-+#ifdef DEBUG
-+#define GLAMO_LOG(...)
-+#else
-+#define GLAMO_LOG(...) \
-+do { \
-+ printk(KERN_DEBUG "in %s:%s:%d", __FILE__, __func__, __LINE__); \
-+ printk(KERN_DEBUG __VA_ARGS__); \
-+} while (0);
-+#endif
-+
-+
-+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-+
-+struct glamofb_handle {
-+ struct fb_info *fb;
-+ struct device *dev;
-+ struct resource *reg;
-+ struct resource *fb_res;
-+ char __iomem *base;
-+ struct glamofb_platform_data *mach_info;
-+ char __iomem *cursor_addr;
-+ u_int32_t pseudo_pal[16];
-+};
-+
-+/* 'sibling' spi device for lcm init */
-+static struct platform_device glamo_spi_dev = {
-+ .name = "glamo-lcm-spi",
-+};
-+
-+
-+static int reg_read(struct glamofb_handle *glamo,
-+ u_int16_t reg)
-+{
-+ glamo_reg_access_delay();
-+ return readw(glamo->base + reg);
-+}
-+
-+static void reg_write(struct glamofb_handle *glamo,
-+ u_int16_t reg, u_int16_t val)
-+{
-+ glamo_reg_access_delay();
-+ writew(val, glamo->base + reg);
-+}
-+
-+static struct glamo_script glamo_regs[] = {
-+ { GLAMO_REG_LCD_MODE1, 0x0020 },
-+ /* no display rotation, no hardware cursor, no dither, no gamma,
-+ * no retrace flip, vsync low-active, hsync low active,
-+ * no TVCLK, no partial display, hw dest color from fb,
-+ * no partial display mode, LCD1, software flip, */
-+ { GLAMO_REG_LCD_MODE2, 0x1020 },
-+ /* no video flip, no ptr, no ptr, dhclk,
-+ * normal mode, no cpuif,
-+ * res, serial msb first, single fb, no fr ctrl,
-+ * cpu if bits all zero, no crc
-+ * 0000 0000 0010 0000 */
-+ { GLAMO_REG_LCD_MODE3, 0x0b40 },
-+ /* src data rgb565, res, 18bit rgb666
-+ * 000 01 011 0100 0000 */
-+ { GLAMO_REG_LCD_POLARITY, 0x440c },
-+ /* DE high active, no cpu/lcd if, cs0 force low, a0 low active,
-+ * np cpu if, 9bit serial data, sclk rising edge latch data
-+ * 01 00 0 100 0 000 01 0 0 */
-+ { GLAMO_REG_LCD_A_BASE1, 0x0000 }, /* display A base address 15:0 */
-+ { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */
-+};
-+
-+static int glamofb_run_script(struct glamofb_handle *glamo,
-+ struct glamo_script *script, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ struct glamo_script *line = &script[i];
-+
-+ if (line->reg == 0xffff)
-+ return 0;
-+ else if (line->reg == 0xfffe)
-+ msleep(line->val);
-+ else
-+ reg_write(glamo, script[i].reg, script[i].val);
-+ }
-+
-+ return 0;
-+}
-+
-+static int glamofb_check_var(struct fb_var_screeninfo *var,
-+ struct fb_info *info)
-+{
-+ struct glamofb_handle *glamo = info->par;
-+
-+ if (var->yres > glamo->mach_info->yres.max)
-+ var->yres = glamo->mach_info->yres.max;
-+ else if (var->yres < glamo->mach_info->yres.min)
-+ var->yres = glamo->mach_info->yres.min;
-+
-+ if (var->xres > glamo->mach_info->xres.max)
-+ var->xres = glamo->mach_info->xres.max;
-+ else if (var->xres < glamo->mach_info->xres.min)
-+ var->xres = glamo->mach_info->xres.min;
-+
-+ if (var->bits_per_pixel > glamo->mach_info->bpp.max)
-+ var->bits_per_pixel = glamo->mach_info->bpp.max;
-+ else if (var->bits_per_pixel < glamo->mach_info->bpp.min)
-+ var->bits_per_pixel = glamo->mach_info->bpp.min;
-+
-+ /* FIXME: set rgb positions */
-+ switch (var->bits_per_pixel) {
-+ case 16:
-+ switch (reg_read(glamo, GLAMO_REG_LCD_MODE3) & 0xc000) {
-+ case GLAMO_LCD_SRC_RGB565:
-+ var->red.offset = 11;
-+ var->green.offset = 5;
-+ var->blue.offset = 0;
-+ var->red.length = 5;
-+ var->green.length = 6;
-+ var->blue.length = 5;
-+ var->transp.length = 0;
-+ break;
-+ case GLAMO_LCD_SRC_ARGB1555:
-+ var->transp.offset = 15;
-+ var->red.offset = 10;
-+ var->green.offset = 5;
-+ var->blue.offset = 0;
-+ var->transp.length = 1;
-+ var->red.length = 5;
-+ var->green.length = 5;
-+ var->blue.length = 5;
-+ break;
-+ case GLAMO_LCD_SRC_ARGB4444:
-+ var->transp.offset = 12;
-+ var->red.offset = 8;
-+ var->green.offset = 4;
-+ var->blue.offset = 0;
-+ var->transp.length = 4;
-+ var->red.length = 4;
-+ var->green.length = 4;
-+ var->blue.length = 4;
-+ break;
-+ }
-+ break;
-+ case 24:
-+ case 32:
-+ default:
-+ /* The Smedia Glamo doesn't support anything but 16bit color */
-+ printk(KERN_ERR
-+ "Smedia driver does not [yet?] support 24/32bpp\n");
-+ return -EINVAL;
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static void reg_set_bit_mask(struct glamofb_handle *glamo,
-+ u_int16_t reg, u_int16_t mask,
-+ u_int16_t val)
-+{
-+ u_int16_t tmp;
-+
-+ val &= mask;
-+
-+ tmp = reg_read(glamo, reg);
-+ tmp &= ~mask;
-+ tmp |= val;
-+ reg_write(glamo, reg, tmp);
-+}
-+
-+#define GLAMO_LCD_WIDTH_MASK 0x03FF
-+#define GLAMO_LCD_HEIGHT_MASK 0x03FF
-+#define GLAMO_LCD_PITCH_MASK 0x07FE
-+#define GLAMO_LCD_HV_TOTAL_MASK 0x03FF
-+#define GLAMO_LCD_HV_RETR_START_MASK 0x03FF
-+#define GLAMO_LCD_HV_RETR_END_MASK 0x03FF
-+#define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF
-+#define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF
-+
-+enum orientation {
-+ ORIENTATION_PORTRAIT,
-+ ORIENTATION_LANDSCAPE
-+};
-+
-+
-+static void rotate_lcd(struct glamofb_handle *glamo,
-+ __u32 rotation)
-+{
-+ int glamo_rot;
-+
-+ switch (rotation) {
-+ case FB_ROTATE_UR:
-+ glamo_rot = GLAMO_LCD_ROT_MODE_0;
-+ break;
-+ case FB_ROTATE_CW:
-+ glamo_rot = GLAMO_LCD_ROT_MODE_90;
-+ break;
-+ case FB_ROTATE_UD:
-+ glamo_rot = GLAMO_LCD_ROT_MODE_180;
-+ break;
-+ case FB_ROTATE_CCW:
-+ glamo_rot = GLAMO_LCD_ROT_MODE_270;
-+ break;
-+ default:
-+ glamo_rot = GLAMO_LCD_ROT_MODE_0;
-+ break;
-+ }
-+ glamofb_cmd_mode(glamo, 1);
-+ reg_set_bit_mask(glamo,
-+ GLAMO_REG_LCD_WIDTH,
-+ GLAMO_LCD_ROT_MODE_MASK,
-+ glamo_rot);
-+ reg_set_bit_mask(glamo,
-+ GLAMO_REG_LCD_MODE1,
-+ GLAMO_LCD_MODE1_ROTATE_EN,
-+ (glamo_rot != GLAMO_LCD_ROT_MODE_0)?
-+ GLAMO_LCD_MODE1_ROTATE_EN : 0);
-+ glamofb_cmd_mode(glamo, 0);
-+}
-+
-+static enum orientation get_orientation(struct fb_var_screeninfo *var)
-+{
-+ GLAMO_LOG("mark\n")
-+ if (var->xres <= var->yres) {
-+ GLAMO_LOG("portrait\n")
-+ return ORIENTATION_PORTRAIT;
-+ }
-+ GLAMO_LOG("landscape\n")
-+ return ORIENTATION_LANDSCAPE;
-+}
-+
-+static int will_orientation_change(struct fb_var_screeninfo *var)
-+{
-+ enum orientation orient = get_orientation(var);
-+ switch (orient) {
-+ case ORIENTATION_LANDSCAPE:
-+ if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD)
-+ return 1;
-+ break;
-+ case ORIENTATION_PORTRAIT:
-+ if (var->rotate == FB_ROTATE_CW || var->rotate == FB_ROTATE_CCW)
-+ return 1;
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
-+ struct fb_var_screeninfo *var)
-+{
-+ int sync, bp, disp, fp, total, xres, yres, pitch, orientation_changing;
-+
-+ GLAMO_LOG("enter: glamo:%#x, var:%#x\n", (unsigned)glamo, (unsigned)var);
-+ if (!glamo || !var)
-+ return;
-+
-+ glamofb_cmd_mode(glamo, 1);
-+
-+ if (var->pixclock)
-+ glamo_engine_reclock(glamo->mach_info->glamo,
-+ GLAMO_ENGINE_LCD,
-+ var->pixclock);
-+
-+ xres = var->xres;
-+ yres = var->yres;
-+ GLAMO_LOG("xres:%d, yres:%d, rotate:%d\n", xres, yres, var->rotate);
-+
-+ /*
-+ * figure out if orientation is going to change
-+ */
-+ orientation_changing = will_orientation_change(var);
-+ GLAMO_LOG("orientation_changing:%d\n", orientation_changing);
-+
-+ /*
-+ * adjust the pitch according to new orientation to come
-+ */
-+ if (orientation_changing) {
-+ pitch = var->yres * var->bits_per_pixel / 8;
-+ } else {
-+ pitch = var->xres * var->bits_per_pixel / 8;
-+ }
-+ GLAMO_LOG("pitch:%d\n", pitch);
-+
-+ /*
-+ * set the awaiten LCD geometry
-+ */
-+ reg_set_bit_mask(glamo,
-+ GLAMO_REG_LCD_WIDTH,
-+ GLAMO_LCD_WIDTH_MASK,
-+ xres);
-+ reg_set_bit_mask(glamo,
-+ GLAMO_REG_LCD_HEIGHT,
-+ GLAMO_LCD_HEIGHT_MASK,
-+ yres);
-+ reg_set_bit_mask(glamo,
-+ GLAMO_REG_LCD_PITCH,
-+ GLAMO_LCD_PITCH_MASK,
-+ pitch);
-+
-+ GLAMO_LOG("mark:\n");
-+ /*
-+ * honour the rotation request
-+ */
-+ rotate_lcd(glamo, var->rotate);
-+
-+ /*
-+ * update the reported geometry
-+ * of the framebuffer.
-+ */
-+ if (orientation_changing) {
-+ var->xres_virtual = var->xres = yres;
-+ var->yres_virtual = var->yres = xres;
-+ } else {
-+ var->xres_virtual = var->xres = xres;
-+ var->yres_virtual = var->yres = yres;
-+ }
-+
-+ GLAMO_LOG("reported res:(%d,%d)\n", var->xres, var->yres);
-+ /*
-+ * update scannout timings
-+ */
-+ sync = 0;
-+ bp = sync + var->hsync_len;
-+ disp = bp + var->left_margin;
-+ fp = disp + xres;
-+ total = fp + var->right_margin;
-+
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL,
-+ GLAMO_LCD_HV_TOTAL_MASK, total);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_RETR_START,
-+ GLAMO_LCD_HV_RETR_START_MASK, sync);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_RETR_END,
-+ GLAMO_LCD_HV_RETR_END_MASK, bp);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_START,
-+ GLAMO_LCD_HV_RETR_DISP_START_MASK, disp);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_END,
-+ GLAMO_LCD_HV_RETR_DISP_END_MASK, fp);
-+
-+ GLAMO_LOG("mark:\n");
-+
-+ sync = 0;
-+ bp = sync + var->vsync_len;
-+ disp = bp + var->upper_margin;
-+ fp = disp + yres;
-+ total = fp + var->lower_margin;
-+
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL,
-+ GLAMO_LCD_HV_TOTAL_MASK, total);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_RETR_START,
-+ GLAMO_LCD_HV_RETR_START_MASK, sync);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_RETR_END,
-+ GLAMO_LCD_HV_RETR_END_MASK, bp);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_START,
-+ GLAMO_LCD_HV_RETR_DISP_START_MASK, disp);
-+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_END,
-+ GLAMO_LCD_HV_RETR_DISP_END_MASK, fp);
-+
-+ GLAMO_LOG("mark:\n");
-+ glamofb_cmd_mode(glamo, 0);
-+
-+ GLAMO_LOG("leave:\n");
-+}
-+
-+static int glamofb_set_par(struct fb_info *info)
-+{
-+ struct glamofb_handle *glamo = info->par;
-+ struct fb_var_screeninfo *var = &info->var;
-+
-+ switch (var->bits_per_pixel) {
-+ case 16:
-+ info->fix.visual = FB_VISUAL_TRUECOLOR;
-+ break;
-+ default:
-+ printk("Smedia driver doesn't support != 16bpp\n");
-+ return -EINVAL;
-+ }
-+
-+ info->fix.line_length = (var->xres * var->bits_per_pixel) / 8;
-+
-+ glamofb_update_lcd_controller(glamo, var);
-+
-+ return 0;
-+}
-+
-+static int glamofb_blank(int blank_mode, struct fb_info *info)
-+{
-+ /* FIXME */
-+ return 0;
-+}
-+
-+static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
-+{
-+ chan &= 0xffff;
-+ chan >>= 16 - bf->length;
-+ return chan << bf->offset;
-+}
-+
-+static int glamofb_setcolreg(unsigned regno,
-+ unsigned red, unsigned green, unsigned blue,
-+ unsigned transp, struct fb_info *info)
-+{
-+ struct glamofb_handle *glamo = info->par;
-+ unsigned int val;
-+
-+ switch (glamo->fb->fix.visual) {
-+ case FB_VISUAL_TRUECOLOR:
-+ case FB_VISUAL_DIRECTCOLOR:
-+ /* true-colour, use pseuo-palette */
-+
-+ if (regno < 16) {
-+ u32 *pal = glamo->fb->pseudo_palette;
-+
-+ val = chan_to_field(red, &glamo->fb->var.red);
-+ val |= chan_to_field(green, &glamo->fb->var.green);
-+ val |= chan_to_field(blue, &glamo->fb->var.blue);
-+
-+ pal[regno] = val;
-+ };
-+ break;
-+ default:
-+ return 1; /* unknown type */
-+ }
-+
-+ return 0;
-+}
-+
-+static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
-+{
-+ struct glamofb_handle *glamo = info->par;
-+ u_int16_t reg;
-+
-+ if (cursor->image.depth > 2)
-+ return -EINVAL;
-+
-+ reg = reg_read(glamo, GLAMO_REG_LCD_MODE1);
-+
-+ if (cursor->enable)
-+ reg_write(glamo, GLAMO_REG_LCD_MODE1,
-+ reg | GLAMO_LCD_MODE1_CURSOR_EN);
-+ else
-+ reg_write(glamo, GLAMO_REG_LCD_MODE1,
-+ reg & ~GLAMO_LCD_MODE1_CURSOR_EN);
-+
-+ if (cursor->set & FB_CUR_SETPOS) {
-+ reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_POS,
-+ cursor->image.dx);
-+ reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_POS,
-+ cursor->image.dy);
-+ }
-+
-+ if (cursor->set & FB_CUR_SETCMAP) {
-+ /* FIXME */
-+ }
-+
-+ if (cursor->set & FB_CUR_SETSIZE ||
-+ cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
-+ int x, y, op;
-+ const unsigned char *pcol = cursor->image.data;
-+ const unsigned char *pmsk = cursor->mask;
-+ void __iomem *dst = glamo->cursor_addr;
-+ unsigned char dcol = 0;
-+ unsigned char dmsk = 0;
-+
-+ reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_SIZE,
-+ cursor->image.width);
-+ reg_write(glamo, GLAMO_REG_LCD_CURSOR_PITCH,
-+ cursor->image.width * 2);
-+ reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_SIZE,
-+ cursor->image.height);
-+
-+ for (op = 0; op < (cursor->image.width *
-+ cursor->image.height * 2)/8; op += 4)
-+ writel(0x0, dst + op);
-+
-+ for (y = 0; y < cursor->image.height; y++) {
-+ for (x = 0; x < cursor->image.width; x++) {
-+ if ((x % 8) == 0) {
-+ dcol = *pcol++;
-+ dmsk = *pmsk++;
-+ } else {
-+ dcol >>= 1;
-+ dmsk >>= 1;
-+ }
-+
-+ if (dmsk & 1) {
-+ unsigned int op;
-+
-+ op = (dcol & 1) ? 1 : 3;
-+ op <<= ((x % 4) * 2);
-+
-+ op |= readb(dst + (x / 4));
-+ writeb(op, dst + (x / 4));
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
-+{
-+ return reg_read(gfb, GLAMO_REG_LCD_STATUS1) & (1 << 15);
-+}
-+
-+void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
-+{
-+ dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on);
-+ if (on) {
-+ dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
-+ __FUNCTION__);
-+ while (!glamofb_cmdq_empty(gfb))
-+ yield();
-+ dev_dbg(gfb->dev, "empty!\n");
-+
-+ /* display the entire frame then switch to command */
-+ reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
-+ GLAMO_LCD_CMD_TYPE_DISP |
-+ GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
-+
-+ /* wait until LCD is idle */
-+ dev_dbg(gfb->dev, "waiting for LCD idle: ");
-+ while (!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12))
-+ yield();
-+ dev_dbg(gfb->dev, "idle!\n");
-+
-+ msleep(90);
-+ } else {
-+ /* RGB interface needs vsync/hsync */
-+ if (reg_read(gfb, GLAMO_REG_LCD_MODE3) & GLAMO_LCD_MODE3_RGB)
-+ reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
-+ GLAMO_LCD_CMD_TYPE_DISP |
-+ GLAMO_LCD_CMD_DATA_DISP_SYNC);
-+
-+ reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
-+ GLAMO_LCD_CMD_TYPE_DISP |
-+ GLAMO_LCD_CMD_DATA_DISP_FIRE);
-+ }
-+}
-+EXPORT_SYMBOL_GPL(glamofb_cmd_mode);
-+
-+int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
-+{
-+ dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n",
-+ __FUNCTION__);
-+ while (!glamofb_cmdq_empty(gfb))
-+ yield();
-+ dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val);
-+
-+ reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(glamofb_cmd_write);
-+
-+static struct fb_ops glamofb_ops = {
-+ .owner = THIS_MODULE,
-+ .fb_check_var = glamofb_check_var,
-+ .fb_set_par = glamofb_set_par,
-+ .fb_blank = glamofb_blank,
-+ .fb_setcolreg = glamofb_setcolreg,
-+ //.fb_cursor = glamofb_cursor,
-+ .fb_fillrect = cfb_fillrect,
-+ .fb_copyarea = cfb_copyarea,
-+ .fb_imageblit = cfb_imageblit,
-+};
-+
-+static int glamofb_init_regs(struct glamofb_handle *glamo)
-+{
-+ struct fb_info *info = glamo->fb;
-+
-+ glamofb_check_var(&info->var, info);
-+ glamofb_run_script(glamo, glamo_regs, ARRAY_SIZE(glamo_regs));
-+ glamofb_set_par(info);
-+
-+ return 0;
-+}
-+
-+static int __init glamofb_probe(struct platform_device *pdev)
-+{
-+ int rc = -EIO;
-+ struct fb_info *fbinfo;
-+ struct glamofb_handle *glamofb;
-+ struct glamofb_platform_data *mach_info = pdev->dev.platform_data;
-+
-+ printk(KERN_INFO "SMEDIA Glamo frame buffer driver (C) 2007 "
-+ "OpenMoko, Inc.\n");
-+
-+ fbinfo = framebuffer_alloc(sizeof(struct glamofb_handle), &pdev->dev);
-+ if (!fbinfo)
-+ return -ENOMEM;
-+
-+ glamofb = fbinfo->par;
-+ glamofb->fb = fbinfo;
-+ glamofb->dev = &pdev->dev;
-+
-+ strcpy(fbinfo->fix.id, "SMedia Glamo");
-+
-+ glamofb->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-+ "glamo-fb-regs");
-+ if (!glamofb->reg) {
-+ dev_err(&pdev->dev, "platform device with no registers?\n");
-+ rc = -ENOENT;
-+ goto out_free;
-+ }
-+
-+ glamofb->fb_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-+ "glamo-fb-mem");
-+ if (!glamofb->fb_res) {
-+ dev_err(&pdev->dev, "platform device with no memory ?\n");
-+ rc = -ENOENT;
-+ goto out_free;
-+ }
-+
-+ glamofb->reg = request_mem_region(glamofb->reg->start,
-+ RESSIZE(glamofb->reg), pdev->name);
-+ if (!glamofb->reg) {
-+ dev_err(&pdev->dev, "failed to request mmio region\n");
-+ goto out_free;
-+ }
-+
-+ glamofb->fb_res = request_mem_region(glamofb->fb_res->start,
-+ mach_info->fb_mem_size,
-+ pdev->name);
-+ if (!glamofb->fb_res) {
-+ dev_err(&pdev->dev, "failed to request vram region\n");
-+ goto out_release_reg;
-+ }
-+
-+ /* we want to remap only the registers required for this core
-+ * driver. */
-+ glamofb->base = ioremap(glamofb->reg->start, RESSIZE(glamofb->reg));
-+ if (!glamofb->base) {
-+ dev_err(&pdev->dev, "failed to ioremap() mmio memory\n");
-+ goto out_release_fb;
-+ }
-+ fbinfo->fix.smem_start = (unsigned long) glamofb->fb_res->start;
-+ fbinfo->fix.smem_len = mach_info->fb_mem_size;
-+
-+ fbinfo->screen_base = ioremap(glamofb->fb_res->start,
-+ RESSIZE(glamofb->fb_res));
-+ if (!fbinfo->screen_base) {
-+ dev_err(&pdev->dev, "failed to ioremap() vram memory\n");
-+ goto out_release_fb;
-+ }
-+
-+ platform_set_drvdata(pdev, fbinfo);
-+
-+ glamofb->mach_info = pdev->dev.platform_data;
-+
-+ fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;
-+ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
-+ fbinfo->fix.type_aux = 0;
-+ fbinfo->fix.xpanstep = 0;
-+ fbinfo->fix.ypanstep = 0;
-+ fbinfo->fix.ywrapstep = 0;
-+ fbinfo->fix.accel = FB_ACCEL_NONE; /* FIXME */
-+
-+ fbinfo->var.nonstd = 0;
-+ fbinfo->var.activate = FB_ACTIVATE_NOW;
-+ fbinfo->var.height = mach_info->height;
-+ fbinfo->var.width = mach_info->width;
-+ fbinfo->var.accel_flags = 0;
-+ fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
-+
-+ fbinfo->fbops = &glamofb_ops;
-+ fbinfo->flags = FBINFO_FLAG_DEFAULT;
-+ fbinfo->pseudo_palette = &glamofb->pseudo_pal;
-+
-+ fbinfo->var.xres = mach_info->xres.defval;
-+ fbinfo->var.xres_virtual = mach_info->xres.defval;
-+ fbinfo->var.yres = mach_info->yres.defval;
-+ fbinfo->var.yres_virtual = mach_info->yres.defval;
-+ fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
-+
-+ fbinfo->var.pixclock = mach_info->pixclock;
-+ fbinfo->var.left_margin = mach_info->left_margin;
-+ fbinfo->var.right_margin = mach_info->right_margin;
-+ fbinfo->var.upper_margin = mach_info->upper_margin;
-+ fbinfo->var.lower_margin = mach_info->lower_margin;
-+ fbinfo->var.hsync_len = mach_info->hsync_len;
-+ fbinfo->var.vsync_len = mach_info->vsync_len;
-+
-+ memset(fbinfo->screen_base, 0, fbinfo->fix.smem_len);
-+
-+ glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD);
-+ glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD);
-+ glamofb_init_regs(glamofb);
-+
-+ rc = register_framebuffer(fbinfo);
-+ if (rc < 0) {
-+ dev_err(&pdev->dev, "failed to register framebuffer\n");
-+ goto out_unmap_fb;
-+ }
-+
-+ if (mach_info->spi_info) {
-+ /* register the sibling spi device */
-+ mach_info->spi_info->glamofb_handle = glamofb;
-+ glamo_spi_dev.dev.parent = &pdev->dev;
-+ glamo_spi_dev.dev.platform_data = mach_info->spi_info;
-+ platform_device_register(&glamo_spi_dev);
-+ }
-+
-+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
-+ fbinfo->node, fbinfo->fix.id);
-+
-+ return 0;
-+
-+out_unmap_fb:
-+ iounmap(fbinfo->screen_base);
-+ iounmap(glamofb->base);
-+out_release_fb:
-+ release_mem_region(glamofb->fb_res->start, RESSIZE(glamofb->fb_res));
-+out_release_reg:
-+ release_mem_region(glamofb->reg->start, RESSIZE(glamofb->reg));
-+out_free:
-+ framebuffer_release(fbinfo);
-+ return rc;
-+}
-+
-+static int glamofb_remove(struct platform_device *pdev)
-+{
-+ struct glamofb_handle *glamofb = platform_get_drvdata(pdev);
-+
-+ platform_set_drvdata(pdev, NULL);
-+ iounmap(glamofb->base);
-+ release_mem_region(glamofb->reg->start, RESSIZE(glamofb->reg));
-+ kfree(glamofb);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int glamofb_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+ return 0;
-+}
-+
-+static int glamofb_resume(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+#else
-+#define glamofb_suspend NULL
-+#define glamofb_resume NULL
-+#endif
-+
-+static struct platform_driver glamofb_driver = {
-+ .probe = glamofb_probe,
-+ .remove = glamofb_remove,
-+ .suspend = glamofb_suspend,
-+ .resume = glamofb_resume,
-+ .driver = {
-+ .name = "glamo-fb",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __devinit glamofb_init(void)
-+{
-+ return platform_driver_register(&glamofb_driver);
-+}
-+
-+static void __exit glamofb_cleanup(void)
-+{
-+ platform_driver_unregister(&glamofb_driver);
-+}
-+
-+module_init(glamofb_init);
-+module_exit(glamofb_cleanup);
-+
-+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
-+MODULE_DESCRIPTION("Smedia Glamo 336x/337x framebuffer driver");
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/glamo/glamo-gpio.c b/drivers/mfd/glamo/glamo-gpio.c
-new file mode 100644
-index 0000000..45d0bf9
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-gpio.c
-@@ -0,0 +1,62 @@
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/spinlock.h>
-+#include <linux/io.h>
-+
-+#include <linux/glamo-gpio.h>
-+
-+#include "glamo-core.h"
-+#include "glamo-regs.h"
-+
-+void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin,
-+ unsigned int value)
-+{
-+ unsigned int reg = REG_OF_GPIO(pin);
-+ u_int16_t tmp;
-+
-+ spin_lock(&glamo->lock);
-+ tmp = readw(glamo->base + reg);
-+ if (value)
-+ tmp |= OUTPUT_BIT(pin);
-+ else
-+ tmp &= ~OUTPUT_BIT(pin);
-+ writew(tmp, glamo->base + reg);
-+ spin_unlock(&glamo->lock);
-+}
-+EXPORT_SYMBOL(glamo_gpio_setpin);
-+
-+int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin)
-+{
-+ return readw(REG_OF_GPIO(pin)) & INPUT_BIT(pin) ? 1 : 0;
-+}
-+EXPORT_SYMBOL(glamo_gpio_getpin);
-+
-+void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc)
-+{
-+ unsigned int reg = REG_OF_GPIO(pinfunc);
-+ u_int16_t tmp;
-+
-+ spin_lock(&glamo->lock);
-+ tmp = readw(glamo->base + reg);
-+
-+ if ((pinfunc & 0x00f0) == GLAMO_GPIO_F_FUNC) {
-+ /* pin is a function pin: clear gpio bit */
-+ tmp &= ~FUNC_BIT(pinfunc);
-+ } else {
-+ /* pin is gpio: set gpio bit */
-+ tmp |= FUNC_BIT(pinfunc);
-+
-+ if (pinfunc & GLAMO_GPIO_F_IN) {
-+ /* gpio input: set bit to disable output mode */
-+ tmp |= GPIO_OUT_BIT(pinfunc);
-+ } else if (pinfunc & GLAMO_GPIO_F_OUT) {
-+ /* gpio output: clear bit to enable output mode */
-+ tmp &= ~GPIO_OUT_BIT(pinfunc);
-+ }
-+ }
-+ writew(tmp, glamo->base + reg);
-+ spin_unlock(&glamo->lock);
-+}
-+EXPORT_SYMBOL(glamo_gpio_cfgpin);
-+
-diff --git a/drivers/mfd/glamo/glamo-lcm-spi.c b/drivers/mfd/glamo/glamo-lcm-spi.c
-new file mode 100644
-index 0000000..92cabe4
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-lcm-spi.c
-@@ -0,0 +1,241 @@
-+/*
-+ * Copyright (C) 2007 OpenMoko, Inc.
-+ * Author: Harald Welte <laforge@openmoko.org>
-+ *
-+ * Smedia Glamo GPIO based SPI driver
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This driver currently only implements a minimum subset of the hardware
-+ * features, esp. those features that are required to drive the jbt6k74
-+ * LCM controller asic in the TD028TTEC1 LCM.
-+ *
-+*/
-+
-+#define DEBUG
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/platform_device.h>
-+
-+#include <linux/spi/spi.h>
-+#include <linux/spi/spi_bitbang.h>
-+#include <linux/spi/glamo.h>
-+
-+#include <linux/glamofb.h>
-+
-+#include <asm/hardware.h>
-+
-+#include "glamo-core.h"
-+#include "glamo-regs.h"
-+
-+struct glamo_spi {
-+ struct spi_bitbang bitbang;
-+ struct spi_master *master;
-+ struct glamo_spi_info *info;
-+ struct device *dev;
-+};
-+
-+static inline struct glamo_spi *to_gs(struct spi_device *spi)
-+{
-+ return spi->controller_data;
-+}
-+
-+static int glamo_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
-+{
-+ struct glamo_spi *gs = to_gs(spi);
-+ unsigned int bpw;
-+
-+ bpw = t ? t->bits_per_word : spi->bits_per_word;
-+
-+ if (bpw != 9 && bpw != 8) {
-+ dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static void glamo_spi_chipsel(struct spi_device *spi, int value)
-+{
-+#if 0
-+ struct glamo_spi *gs = to_gs(spi);
-+
-+ dev_dbg(&spi->dev, "chipsel %d: spi=%p, gs=%p, info=%p, handle=%p\n",
-+ value, spi, gs, gs->info, gs->info->glamofb_handle);
-+
-+ glamofb_cmd_mode(gs->info->glamofb_handle, value);
-+#endif
-+}
-+
-+static int glamo_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
-+{
-+ struct glamo_spi *gs = to_gs(spi);
-+ const u_int16_t *ui16 = (const u_int16_t *) t->tx_buf;
-+ u_int16_t nine_bits;
-+ int i;
-+
-+ dev_dbg(&spi->dev, "txrx: tx %p, rx %p, bpw %d, len %d\n",
-+ t->tx_buf, t->rx_buf, t->bits_per_word, t->len);
-+
-+ if (spi->bits_per_word == 9)
-+ nine_bits = (1 << 9);
-+ else
-+ nine_bits = 0;
-+
-+ if (t->len > 3 * sizeof(u_int16_t)) {
-+ dev_err(&spi->dev, "this driver doesn't support "
-+ "%u sized xfers\n", t->len);
-+ return -EINVAL;
-+ }
-+
-+ for (i = 0; i < t->len/sizeof(u_int16_t); i++) {
-+ /* actually transfer the data */
-+#if 1
-+ glamofb_cmd_write(gs->info->glamofb_handle,
-+ GLAMO_LCD_CMD_TYPE_SERIAL | nine_bits |
-+ (1 << 10) | (1 << 11) | (ui16[i] & 0x1ff));
-+#endif
-+ /* FIXME: fire ?!? */
-+ if (i == 0 && (ui16[i] & 0x1ff) == 0x29) {
-+ dev_dbg(&spi->dev, "leaving command mode\n");
-+ glamofb_cmd_mode(gs->info->glamofb_handle, 0);
-+ }
-+ }
-+
-+ return t->len;
-+}
-+
-+static int glamo_spi_setup(struct spi_device *spi)
-+{
-+ int ret;
-+
-+ if (!spi->bits_per_word)
-+ spi->bits_per_word = 9;
-+
-+ /* FIXME: hardware can do this */
-+ if (spi->mode & SPI_LSB_FIRST)
-+ return -EINVAL;
-+
-+ ret = glamo_spi_setupxfer(spi, NULL);
-+ if (ret < 0) {
-+ dev_err(&spi->dev, "setupxfer returned %d\n", ret);
-+ return ret;
-+ }
-+
-+ dev_dbg(&spi->dev, "%s: mode %d, %u bpw\n",
-+ __FUNCTION__, spi->mode, spi->bits_per_word);
-+
-+ return 0;
-+}
-+
-+static int glamo_spi_probe(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct glamo_spi *sp;
-+ int ret;
-+ int i;
-+
-+ master = spi_alloc_master(&pdev->dev, sizeof(struct glamo_spi));
-+ if (master == NULL) {
-+ dev_err(&pdev->dev, "failed to allocate spi master\n");
-+ ret = -ENOMEM;
-+ goto err;
-+ }
-+
-+ sp = spi_master_get_devdata(master);
-+ memset(sp, 0, sizeof(struct glamo_spi));
-+
-+ sp->master = spi_master_get(master);
-+ sp->info = pdev->dev.platform_data;
-+ if (!sp->info) {
-+ dev_err(&pdev->dev, "can't operate without platform data\n");
-+ ret = -EIO;
-+ goto err_no_pdev;
-+ }
-+ dev_dbg(&pdev->dev, "sp->info(pdata) = %p\n", sp->info);
-+
-+ sp->dev = &pdev->dev;
-+
-+ platform_set_drvdata(pdev, sp);
-+
-+ sp->bitbang.master = sp->master;
-+ sp->bitbang.setup_transfer = glamo_spi_setupxfer;
-+ sp->bitbang.chipselect = glamo_spi_chipsel;
-+ sp->bitbang.txrx_bufs = glamo_spi_txrx;
-+ sp->bitbang.master->setup = glamo_spi_setup;
-+
-+ ret = spi_bitbang_start(&sp->bitbang);
-+ if (ret)
-+ goto err_no_bitbang;
-+
-+ /* register the chips to go with the board */
-+
-+ glamofb_cmd_mode(sp->info->glamofb_handle, 1);
-+
-+ for (i = 0; i < sp->info->board_size; i++) {
-+ dev_info(&pdev->dev, "registering %p: %s\n",
-+ &sp->info->board_info[i],
-+ sp->info->board_info[i].modalias);
-+
-+ sp->info->board_info[i].controller_data = sp;
-+ spi_new_device(master, sp->info->board_info + i);
-+ }
-+
-+ return 0;
-+
-+err_no_bitbang:
-+ platform_set_drvdata(pdev, NULL);
-+err_no_pdev:
-+ spi_master_put(sp->bitbang.master);
-+err:
-+ return ret;
-+
-+}
-+
-+static int glamo_spi_remove(struct platform_device *pdev)
-+{
-+ struct glamo_spi *sp = platform_get_drvdata(pdev);
-+
-+ spi_bitbang_stop(&sp->bitbang);
-+ spi_master_put(sp->bitbang.master);
-+
-+ return 0;
-+}
-+
-+#define glamo_spi_suspend NULL
-+#define glamo_spi_resume NULL
-+
-+static struct platform_driver glamo_spi_drv = {
-+ .probe = glamo_spi_probe,
-+ .remove = glamo_spi_remove,
-+ .suspend = glamo_spi_suspend,
-+ .resume = glamo_spi_resume,
-+ .driver = {
-+ .name = "glamo-lcm-spi",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init glamo_spi_init(void)
-+{
-+ return platform_driver_register(&glamo_spi_drv);
-+}
-+
-+static void __exit glamo_spi_exit(void)
-+{
-+ platform_driver_unregister(&glamo_spi_drv);
-+}
-+
-+module_init(glamo_spi_init);
-+module_exit(glamo_spi_exit);
-+
-+MODULE_DESCRIPTION("Smedia Glamo 336x/337x LCM serial command SPI Driver");
-+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>")
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/glamo/glamo-regs.h b/drivers/mfd/glamo/glamo-regs.h
-new file mode 100644
-index 0000000..151cd66
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-regs.h
-@@ -0,0 +1,477 @@
-+#ifndef _GLAMO_REGS_H
-+#define _GLAMO_REGS_H
-+
-+/* Smedia Glamo 336x/337x driver
-+ *
-+ * (C) 2007 by OpenMoko, Inc.
-+ * Author: Harald Welte <laforge@openmoko.org>
-+ * All rights reserved.
-+ *
-+ * 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
-+ */
-+
-+enum glamo_regster_offsets {
-+ GLAMO_REGOFS_GENERIC = 0x0000,
-+ GLAMO_REGOFS_HOSTBUS = 0x0200,
-+ GLAMO_REGOFS_MEMORY = 0x0300,
-+ GLAMO_REGOFS_VIDCAP = 0x0400,
-+ GLAMO_REGOFS_ISP = 0x0500,
-+ GLAMO_REGOFS_JPEG = 0x0800,
-+ GLAMO_REGOFS_MPEG = 0x0c00,
-+ GLAMO_REGOFS_LCD = 0x1100,
-+ GLAMO_REGOFS_MMC = 0x1400,
-+ GLAMO_REGOFS_MPROC0 = 0x1500,
-+ GLAMO_REGOFS_MPROC1 = 0x1580,
-+ GLAMO_REGOFS_CMDQUEUE = 0x1600,
-+ GLAMO_REGOFS_RISC = 0x1680,
-+ GLAMO_REGOFS_2D = 0x1700,
-+ GLAMO_REGOFS_3D = 0x1b00,
-+ GLAMO_REGOFS_END = 0x2400,
-+};
-+
-+
-+enum glamo_register_generic {
-+ GLAMO_REG_GCONF1 = 0x0000,
-+ GLAMO_REG_GCONF2 = 0x0002,
-+#define GLAMO_REG_DEVICE_ID GLAMO_REG_GCONF2
-+ GLAMO_REG_GCONF3 = 0x0004,
-+#define GLAMO_REG_REVISION_ID GLAMO_REG_GCONF3
-+ GLAMO_REG_IRQ_GEN1 = 0x0006,
-+#define GLAMO_REG_IRQ_ENABLE GLAMO_REG_IRQ_GEN1
-+ GLAMO_REG_IRQ_GEN2 = 0x0008,
-+#define GLAMO_REG_IRQ_SET GLAMO_REG_IRQ_GEN2
-+ GLAMO_REG_IRQ_GEN3 = 0x000a,
-+#define GLAMO_REG_IRQ_CLEAR GLAMO_REG_IRQ_GEN3
-+ GLAMO_REG_IRQ_GEN4 = 0x000c,
-+#define GLAMO_REG_IRQ_STATUS GLAMO_REG_IRQ_GEN4
-+ GLAMO_REG_CLOCK_HOST = 0x0010,
-+ GLAMO_REG_CLOCK_MEMORY = 0x0012,
-+ GLAMO_REG_CLOCK_LCD = 0x0014,
-+ GLAMO_REG_CLOCK_MMC = 0x0016,
-+ GLAMO_REG_CLOCK_ISP = 0x0018,
-+ GLAMO_REG_CLOCK_JPEG = 0x001a,
-+ GLAMO_REG_CLOCK_3D = 0x001c,
-+ GLAMO_REG_CLOCK_2D = 0x001e,
-+ GLAMO_REG_CLOCK_RISC1 = 0x0020, /* 3365 only? */
-+ GLAMO_REG_CLOCK_RISC2 = 0x0022, /* 3365 only? */
-+ GLAMO_REG_CLOCK_MPEG = 0x0024,
-+ GLAMO_REG_CLOCK_MPROC = 0x0026,
-+
-+ GLAMO_REG_CLOCK_GEN5_1 = 0x0030,
-+ GLAMO_REG_CLOCK_GEN5_2 = 0x0032,
-+ GLAMO_REG_CLOCK_GEN6 = 0x0034,
-+ GLAMO_REG_CLOCK_GEN7 = 0x0036,
-+ GLAMO_REG_CLOCK_GEN8 = 0x0038,
-+ GLAMO_REG_CLOCK_GEN9 = 0x003a,
-+ GLAMO_REG_CLOCK_GEN10 = 0x003c,
-+ GLAMO_REG_CLOCK_GEN11 = 0x003e,
-+ GLAMO_REG_PLL_GEN1 = 0x0040,
-+ GLAMO_REG_PLL_GEN2 = 0x0042,
-+ GLAMO_REG_PLL_GEN3 = 0x0044,
-+ GLAMO_REG_PLL_GEN4 = 0x0046,
-+ GLAMO_REG_PLL_GEN5 = 0x0048,
-+ GLAMO_REG_GPIO_GEN1 = 0x0050,
-+ GLAMO_REG_GPIO_GEN2 = 0x0052,
-+ GLAMO_REG_GPIO_GEN3 = 0x0054,
-+ GLAMO_REG_GPIO_GEN4 = 0x0056,
-+ GLAMO_REG_GPIO_GEN5 = 0x0058,
-+ GLAMO_REG_GPIO_GEN6 = 0x005a,
-+ GLAMO_REG_GPIO_GEN7 = 0x005c,
-+ GLAMO_REG_GPIO_GEN8 = 0x005e,
-+ GLAMO_REG_GPIO_GEN9 = 0x0060,
-+ GLAMO_REG_GPIO_GEN10 = 0x0062,
-+ GLAMO_REG_DFT_GEN1 = 0x0070,
-+ GLAMO_REG_DFT_GEN2 = 0x0072,
-+ GLAMO_REG_DFT_GEN3 = 0x0074,
-+ GLAMO_REG_DFT_GEN4 = 0x0076,
-+
-+ GLAMO_REG_DFT_GEN5 = 0x01e0,
-+ GLAMO_REG_DFT_GEN6 = 0x01f0,
-+};
-+
-+#define GLAMO_REG_HOSTBUS(x) (GLAMO_REGOFS_HOSTBUS-2+(x*2))
-+
-+#define REG_MEM(x) (GLAMO_REGOFS_MEMORY+(x))
-+#define GLAMO_REG_MEM_TIMING(x) (GLAMO_REG_MEM_TIMING1-2+(x*2))
-+
-+enum glamo_register_mem {
-+ GLAMO_REG_MEM_TYPE = REG_MEM(0x00),
-+ GLAMO_REG_MEM_GEN = REG_MEM(0x02),
-+ GLAMO_REG_MEM_TIMING1 = REG_MEM(0x04),
-+ GLAMO_REG_MEM_TIMING2 = REG_MEM(0x06),
-+ GLAMO_REG_MEM_TIMING3 = REG_MEM(0x08),
-+ GLAMO_REG_MEM_TIMING4 = REG_MEM(0x0a),
-+ GLAMO_REG_MEM_TIMING5 = REG_MEM(0x0c),
-+ GLAMO_REG_MEM_TIMING6 = REG_MEM(0x0e),
-+ GLAMO_REG_MEM_TIMING7 = REG_MEM(0x10),
-+ GLAMO_REG_MEM_TIMING8 = REG_MEM(0x12),
-+ GLAMO_REG_MEM_TIMING9 = REG_MEM(0x14),
-+ GLAMO_REG_MEM_TIMING10 = REG_MEM(0x16),
-+ GLAMO_REG_MEM_TIMING11 = REG_MEM(0x18),
-+ GLAMO_REG_MEM_POWER1 = REG_MEM(0x1a),
-+ GLAMO_REG_MEM_POWER2 = REG_MEM(0x1c),
-+ GLAMO_REG_MEM_LCD_BUF1 = REG_MEM(0x1e),
-+ GLAMO_REG_MEM_LCD_BUF2 = REG_MEM(0x20),
-+ GLAMO_REG_MEM_LCD_BUF3 = REG_MEM(0x22),
-+ GLAMO_REG_MEM_LCD_BUF4 = REG_MEM(0x24),
-+ GLAMO_REG_MEM_BIST1 = REG_MEM(0x26),
-+ GLAMO_REG_MEM_BIST2 = REG_MEM(0x28),
-+ GLAMO_REG_MEM_BIST3 = REG_MEM(0x2a),
-+ GLAMO_REG_MEM_BIST4 = REG_MEM(0x2c),
-+ GLAMO_REG_MEM_BIST5 = REG_MEM(0x2e),
-+ GLAMO_REG_MEM_MAH1 = REG_MEM(0x30),
-+ GLAMO_REG_MEM_MAH2 = REG_MEM(0x32),
-+ GLAMO_REG_MEM_DRAM1 = REG_MEM(0x34),
-+ GLAMO_REG_MEM_DRAM2 = REG_MEM(0x36),
-+ GLAMO_REG_MEM_CRC = REG_MEM(0x38),
-+};
-+
-+#define GLAMO_MEM_TYPE_MASK 0x03
-+
-+enum glamo_reg_mem_dram1 {
-+ GLAMO_MEM_DRAM1_EN_SDRAM_CLK = (1 << 11),
-+ GLAMO_MEM_DRAM1_SELF_REFRESH = (1 << 12),
-+};
-+
-+enum glamo_reg_mem_dram2 {
-+ GLAMO_MEM_DRAM2_DEEP_PWRDOWN = (1 << 12),
-+};
-+
-+enum glamo_irq {
-+ GLAMO_IRQ_HOSTBUS = 0x0001,
-+ GLAMO_IRQ_JPEG = 0x0002,
-+ GLAMO_IRQ_MPEG = 0x0004,
-+ GLAMO_IRQ_MPROC1 = 0x0008,
-+ GLAMO_IRQ_MPROC0 = 0x0010,
-+ GLAMO_IRQ_CMDQUEUE = 0x0020,
-+ GLAMO_IRQ_2D = 0x0040,
-+ GLAMO_IRQ_MMC = 0x0080,
-+ GLAMO_IRQ_RISC = 0x0100,
-+};
-+
-+enum glamo_reg_clock_host {
-+ GLAMO_CLOCK_HOST_DG_BCLK = 0x0001,
-+ GLAMO_CLOCK_HOST_DG_M0CLK = 0x0004,
-+ GLAMO_CLOCK_HOST_RESET = 0x1000,
-+};
-+
-+enum glamo_reg_clock_mem {
-+ GLAMO_CLOCK_MEM_DG_M1CLK = 0x0001,
-+ GLAMO_CLOCK_MEM_EN_M1CLK = 0x0002,
-+ GLAMO_CLOCK_MEM_DG_MOCACLK = 0x0004,
-+ GLAMO_CLOCK_MEM_EN_MOCACLK = 0x0008,
-+ GLAMO_CLOCK_MEM_RESET = 0x1000,
-+ GLAMO_CLOCK_MOCA_RESET = 0x2000,
-+};
-+
-+enum glamo_reg_clock_lcd {
-+ GLAMO_CLOCK_LCD_DG_DCLK = 0x0001,
-+ GLAMO_CLOCK_LCD_EN_DCLK = 0x0002,
-+ GLAMO_CLOCK_LCD_DG_DMCLK = 0x0004,
-+ GLAMO_CLOCK_LCD_EN_DMCLK = 0x0008,
-+ //
-+ GLAMO_CLOCK_LCD_EN_DHCLK = 0x0020,
-+ GLAMO_CLOCK_LCD_DG_M5CLK = 0x0040,
-+ GLAMO_CLOCK_LCD_EN_M5CLK = 0x0080,
-+ GLAMO_CLOCK_LCD_RESET = 0x1000,
-+};
-+
-+enum glamo_reg_clock_mmc {
-+ GLAMO_CLOCK_MMC_DG_TCLK = 0x0001,
-+ GLAMO_CLOCK_MMC_EN_TCLK = 0x0002,
-+ GLAMO_CLOCK_MMC_DG_M9CLK = 0x0004,
-+ GLAMO_CLOCK_MMC_EN_M9CLK = 0x0008,
-+ GLAMO_CLOCK_MMC_RESET = 0x1000,
-+};
-+
-+enum glamo_reg_clock_isp {
-+ GLAMO_CLOCK_ISP_DG_I1CLK = 0x0001,
-+ GLAMO_CLOCK_ISP_EN_I1CLK = 0x0002,
-+ GLAMO_CLOCK_ISP_DG_CCLK = 0x0004,
-+ GLAMO_CLOCK_ISP_EN_CCLK = 0x0008,
-+ //
-+ GLAMO_CLOCK_ISP_EN_SCLK = 0x0020,
-+ GLAMO_CLOCK_ISP_DG_M2CLK = 0x0040,
-+ GLAMO_CLOCK_ISP_EN_M2CLK = 0x0080,
-+ GLAMO_CLOCK_ISP_DG_M15CLK = 0x0100,
-+ GLAMO_CLOCK_ISP_EN_M15CLK = 0x0200,
-+ GLAMO_CLOCK_ISP1_RESET = 0x1000,
-+ GLAMO_CLOCK_ISP2_RESET = 0x2000,
-+};
-+
-+enum glamo_reg_clock_jpeg {
-+ GLAMO_CLOCK_JPEG_DG_JCLK = 0x0001,
-+ GLAMO_CLOCK_JPEG_EN_JCLK = 0x0002,
-+ GLAMO_CLOCK_JPEG_DG_M3CLK = 0x0004,
-+ GLAMO_CLOCK_JPEG_EN_M3CLK = 0x0008,
-+ GLAMO_CLOCK_JPEG_RESET = 0x1000,
-+};
-+
-+enum glamo_reg_clock_2d {
-+ GLAMO_CLOCK_2D_DG_GCLK = 0x0001,
-+ GLAMO_CLOCK_2D_EN_GCLK = 0x0002,
-+ GLAMO_CLOCK_2D_DG_M7CLK = 0x0004,
-+ GLAMO_CLOCK_2D_EN_M7CLK = 0x0008,
-+ GLAMO_CLOCK_2D_DG_M6CLK = 0x0010,
-+ GLAMO_CLOCK_2D_EN_M6CLK = 0x0020,
-+ GLAMO_CLOCK_2D_RESET = 0x1000,
-+ GLAMO_CLOCK_2D_CQ_RESET = 0x2000,
-+};
-+
-+enum glamo_reg_clock_3d {
-+ GLAMO_CLOCK_3D_DG_ECLK = 0x0001,
-+ GLAMO_CLOCK_3D_EN_ECLK = 0x0002,
-+ GLAMO_CLOCK_3D_DG_RCLK = 0x0004,
-+ GLAMO_CLOCK_3D_EN_RCLK = 0x0008,
-+ GLAMO_CLOCK_3D_DG_M8CLK = 0x0010,
-+ GLAMO_CLOCK_3D_EN_M8CLK = 0x0020,
-+ GLAMO_CLOCK_3D_BACK_RESET = 0x1000,
-+ GLAMO_CLOCK_3D_FRONT_RESET = 0x2000,
-+};
-+
-+enum glamo_reg_clock_mpeg {
-+ GLAMO_CLOCK_MPEG_DG_X0CLK = 0x0001,
-+ GLAMO_CLOCK_MPEG_EN_X0CLK = 0x0002,
-+ GLAMO_CLOCK_MPEG_DG_X1CLK = 0x0004,
-+ GLAMO_CLOCK_MPEG_EN_X1CLK = 0x0008,
-+ GLAMO_CLOCK_MPEG_DG_X2CLK = 0x0010,
-+ GLAMO_CLOCK_MPEG_EN_X2CLK = 0x0020,
-+ GLAMO_CLOCK_MPEG_DG_X3CLK = 0x0040,
-+ GLAMO_CLOCK_MPEG_EN_X3CLK = 0x0080,
-+ GLAMO_CLOCK_MPEG_DG_X4CLK = 0x0100,
-+ GLAMO_CLOCK_MPEG_EN_X4CLK = 0x0200,
-+ GLAMO_CLOCK_MPEG_DG_X6CLK = 0x0400,
-+ GLAMO_CLOCK_MPEG_EN_X6CLK = 0x0800,
-+ GLAMO_CLOCK_MPEG_ENC_RESET = 0x1000,
-+ GLAMO_CLOCK_MPEG_DEC_RESET = 0x2000,
-+};
-+
-+enum glamo_reg_clock51 {
-+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK = 0x0001,
-+ GLAMO_CLOCK_GEN51_EN_DIV_SCLK = 0x0002,
-+ GLAMO_CLOCK_GEN51_EN_DIV_JCLK = 0x0004,
-+ GLAMO_CLOCK_GEN51_EN_DIV_DCLK = 0x0008,
-+ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK = 0x0010,
-+ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK = 0x0020,
-+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK = 0x0040,
-+ GLAMO_CLOCK_GEN51_EN_DIV_TCLK = 0x0080,
-+ /* FIXME: higher bits */
-+};
-+
-+enum glamo_reg_hostbus2 {
-+ GLAMO_HOSTBUS2_MMIO_EN_ISP = 0x0001,
-+ GLAMO_HOSTBUS2_MMIO_EN_JPEG = 0x0002,
-+ GLAMO_HOSTBUS2_MMIO_EN_MPEG = 0x0004,
-+ GLAMO_HOSTBUS2_MMIO_EN_LCD = 0x0008,
-+ GLAMO_HOSTBUS2_MMIO_EN_MMC = 0x0010,
-+ GLAMO_HOSTBUS2_MMIO_EN_MICROP0 = 0x0020,
-+ GLAMO_HOSTBUS2_MMIO_EN_MICROP1 = 0x0040,
-+ GLAMO_HOSTBUS2_MMIO_EN_CQ = 0x0080,
-+ GLAMO_HOSTBUS2_MMIO_EN_RISC = 0x0100,
-+ GLAMO_HOSTBUS2_MMIO_EN_2D = 0x0200,
-+ GLAMO_HOSTBUS2_MMIO_EN_3D = 0x0400,
-+};
-+
-+/* LCD Controller */
-+
-+#define REG_LCD(x) (x)
-+enum glamo_reg_lcd {
-+ GLAMO_REG_LCD_MODE1 = REG_LCD(0x00),
-+ GLAMO_REG_LCD_MODE2 = REG_LCD(0x02),
-+ GLAMO_REG_LCD_MODE3 = REG_LCD(0x04),
-+ GLAMO_REG_LCD_WIDTH = REG_LCD(0x06),
-+ GLAMO_REG_LCD_HEIGHT = REG_LCD(0x08),
-+ GLAMO_REG_LCD_POLARITY = REG_LCD(0x0a),
-+ GLAMO_REG_LCD_A_BASE1 = REG_LCD(0x0c),
-+ GLAMO_REG_LCD_A_BASE2 = REG_LCD(0x0e),
-+ GLAMO_REG_LCD_B_BASE1 = REG_LCD(0x10),
-+ GLAMO_REG_LCD_B_BASE2 = REG_LCD(0x12),
-+ GLAMO_REG_LCD_C_BASE1 = REG_LCD(0x14),
-+ GLAMO_REG_LCD_C_BASE2 = REG_LCD(0x16),
-+ GLAMO_REG_LCD_PITCH = REG_LCD(0x18),
-+ /* RES */
-+ GLAMO_REG_LCD_HORIZ_TOTAL = REG_LCD(0x1c),
-+ /* RES */
-+ GLAMO_REG_LCD_HORIZ_RETR_START = REG_LCD(0x20),
-+ /* RES */
-+ GLAMO_REG_LCD_HORIZ_RETR_END = REG_LCD(0x24),
-+ /* RES */
-+ GLAMO_REG_LCD_HORIZ_DISP_START = REG_LCD(0x28),
-+ /* RES */
-+ GLAMO_REG_LCD_HORIZ_DISP_END = REG_LCD(0x2c),
-+ /* RES */
-+ GLAMO_REG_LCD_VERT_TOTAL = REG_LCD(0x30),
-+ /* RES */
-+ GLAMO_REG_LCD_VERT_RETR_START = REG_LCD(0x34),
-+ /* RES */
-+ GLAMO_REG_LCD_VERT_RETR_END = REG_LCD(0x38),
-+ /* RES */
-+ GLAMO_REG_LCD_VERT_DISP_START = REG_LCD(0x3c),
-+ /* RES */
-+ GLAMO_REG_LCD_VERT_DISP_END = REG_LCD(0x40),
-+ /* RES */
-+ GLAMO_REG_LCD_POL = REG_LCD(0x44),
-+ GLAMO_REG_LCD_DATA_START = REG_LCD(0x46),
-+ GLAMO_REG_LCD_FRATE_CONTRO = REG_LCD(0x48),
-+ GLAMO_REG_LCD_DATA_CMD_HDR = REG_LCD(0x4a),
-+ GLAMO_REG_LCD_SP_START = REG_LCD(0x4c),
-+ GLAMO_REG_LCD_SP_END = REG_LCD(0x4e),
-+ GLAMO_REG_LCD_CURSOR_BASE1 = REG_LCD(0x50),
-+ GLAMO_REG_LCD_CURSOR_BASE2 = REG_LCD(0x52),
-+ GLAMO_REG_LCD_CURSOR_PITCH = REG_LCD(0x54),
-+ GLAMO_REG_LCD_CURSOR_X_SIZE = REG_LCD(0x56),
-+ GLAMO_REG_LCD_CURSOR_Y_SIZE = REG_LCD(0x58),
-+ GLAMO_REG_LCD_CURSOR_X_POS = REG_LCD(0x5a),
-+ GLAMO_REG_LCD_CURSOR_Y_POS = REG_LCD(0x5c),
-+ GLAMO_REG_LCD_CURSOR_PRESET = REG_LCD(0x5e),
-+ GLAMO_REG_LCD_CURSOR_FG_COLOR = REG_LCD(0x60),
-+ /* RES */
-+ GLAMO_REG_LCD_CURSOR_BG_COLOR = REG_LCD(0x64),
-+ /* RES */
-+ GLAMO_REG_LCD_CURSOR_DST_COLOR = REG_LCD(0x68),
-+ /* RES */
-+ GLAMO_REG_LCD_STATUS1 = REG_LCD(0x80),
-+ GLAMO_REG_LCD_STATUS2 = REG_LCD(0x82),
-+ GLAMO_REG_LCD_STATUS3 = REG_LCD(0x84),
-+ GLAMO_REG_LCD_STATUS4 = REG_LCD(0x86),
-+ /* RES */
-+ GLAMO_REG_LCD_COMMAND1 = REG_LCD(0xa0),
-+ GLAMO_REG_LCD_COMMAND2 = REG_LCD(0xa2),
-+ /* RES */
-+ GLAMO_REG_LCD_WFORM_DELAY1 = REG_LCD(0xb0),
-+ GLAMO_REG_LCD_WFORM_DELAY2 = REG_LCD(0xb2),
-+ /* RES */
-+ GLAMO_REG_LCD_GAMMA_CORR = REG_LCD(0x100),
-+ /* RES */
-+ GLAMO_REG_LCD_GAMMA_R_ENTRY01 = REG_LCD(0x110),
-+ GLAMO_REG_LCD_GAMMA_R_ENTRY23 = REG_LCD(0x112),
-+ GLAMO_REG_LCD_GAMMA_R_ENTRY45 = REG_LCD(0x114),
-+ GLAMO_REG_LCD_GAMMA_R_ENTRY67 = REG_LCD(0x116),
-+ GLAMO_REG_LCD_GAMMA_R_ENTRY8 = REG_LCD(0x118),
-+ /* RES */
-+ GLAMO_REG_LCD_GAMMA_G_ENTRY01 = REG_LCD(0x130),
-+ GLAMO_REG_LCD_GAMMA_G_ENTRY23 = REG_LCD(0x132),
-+ GLAMO_REG_LCD_GAMMA_G_ENTRY45 = REG_LCD(0x134),
-+ GLAMO_REG_LCD_GAMMA_G_ENTRY67 = REG_LCD(0x136),
-+ GLAMO_REG_LCD_GAMMA_G_ENTRY8 = REG_LCD(0x138),
-+ /* RES */
-+ GLAMO_REG_LCD_GAMMA_B_ENTRY01 = REG_LCD(0x150),
-+ GLAMO_REG_LCD_GAMMA_B_ENTRY23 = REG_LCD(0x152),
-+ GLAMO_REG_LCD_GAMMA_B_ENTRY45 = REG_LCD(0x154),
-+ GLAMO_REG_LCD_GAMMA_B_ENTRY67 = REG_LCD(0x156),
-+ GLAMO_REG_LCD_GAMMA_B_ENTRY8 = REG_LCD(0x158),
-+ /* RES */
-+ GLAMO_REG_LCD_SRAM_DRIVING1 = REG_LCD(0x160),
-+ GLAMO_REG_LCD_SRAM_DRIVING2 = REG_LCD(0x162),
-+ GLAMO_REG_LCD_SRAM_DRIVING3 = REG_LCD(0x164),
-+};
-+
-+enum glamo_reg_lcd_mode1 {
-+ GLAMO_LCD_MODE1_PWRSAVE = 0x0001,
-+ GLAMO_LCD_MODE1_PARTIAL_PRT = 0x0002,
-+ GLAMO_LCD_MODE1_HWFLIP = 0x0004,
-+ GLAMO_LCD_MODE1_LCD2 = 0x0008,
-+ /* RES */
-+ GLAMO_LCD_MODE1_PARTIAL_MODE = 0x0020,
-+ GLAMO_LCD_MODE1_CURSOR_DSTCOLOR = 0x0040,
-+ GLAMO_LCD_MODE1_PARTIAL_ENABLE = 0x0080,
-+ GLAMO_LCD_MODE1_TVCLK_IN_ENABLE = 0x0100,
-+ GLAMO_LCD_MODE1_HSYNC_HIGH_ACT = 0x0200,
-+ GLAMO_LCD_MODE1_VSYNC_HIGH_ACT = 0x0400,
-+ GLAMO_LCD_MODE1_HSYNC_FLIP = 0x0800,
-+ GLAMO_LCD_MODE1_GAMMA_COR_EN = 0x1000,
-+ GLAMO_LCD_MODE1_DITHER_EN = 0x2000,
-+ GLAMO_LCD_MODE1_CURSOR_EN = 0x4000,
-+ GLAMO_LCD_MODE1_ROTATE_EN = 0x8000,
-+};
-+
-+enum glamo_reg_lcd_mode2 {
-+ GLAMO_LCD_MODE2_CRC_CHECK_EN = 0x0001,
-+ GLAMO_LCD_MODE2_DCMD_PER_LINE = 0x0002,
-+ GLAMO_LCD_MODE2_NOUSE_BDEF = 0x0004,
-+ GLAMO_LCD_MODE2_OUT_POS_MODE = 0x0008,
-+ GLAMO_LCD_MODE2_FRATE_CTRL_EN = 0x0010,
-+ GLAMO_LCD_MODE2_SINGLE_BUFFER = 0x0020,
-+ GLAMO_LCD_MODE2_SER_LSB_TO_MSB = 0x0040,
-+ /* FIXME */
-+};
-+
-+enum glamo_reg_lcd_mode3 {
-+ /* LCD color source data format */
-+ GLAMO_LCD_SRC_RGB565 = 0x0000,
-+ GLAMO_LCD_SRC_ARGB1555 = 0x4000,
-+ GLAMO_LCD_SRC_ARGB4444 = 0x8000,
-+ /* interface type */
-+ GLAMO_LCD_MODE3_LCD = 0x1000,
-+ GLAMO_LCD_MODE3_RGB = 0x0800,
-+ GLAMO_LCD_MODE3_CPU = 0x0000,
-+ /* mode */
-+ GLAMO_LCD_MODE3_RGB332 = 0x0000,
-+ GLAMO_LCD_MODE3_RGB444 = 0x0100,
-+ GLAMO_LCD_MODE3_RGB565 = 0x0200,
-+ GLAMO_LCD_MODE3_RGB666 = 0x0300,
-+ /* depth */
-+ GLAMO_LCD_MODE3_6BITS = 0x0000,
-+ GLAMO_LCD_MODE3_8BITS = 0x0010,
-+ GLAMO_LCD_MODE3_9BITS = 0x0020,
-+ GLAMO_LCD_MODE3_16BITS = 0x0030,
-+ GLAMO_LCD_MODE3_18BITS = 0x0040,
-+};
-+
-+enum glamo_lcd_rot_mode {
-+ GLAMO_LCD_ROT_MODE_0 = 0x0000,
-+ GLAMO_LCD_ROT_MODE_180 = 0x2000,
-+ GLAMO_LCD_ROT_MODE_MIRROR = 0x4000,
-+ GLAMO_LCD_ROT_MODE_FLIP = 0x6000,
-+ GLAMO_LCD_ROT_MODE_90 = 0x8000,
-+ GLAMO_LCD_ROT_MODE_270 = 0xa000,
-+};
-+#define GLAMO_LCD_ROT_MODE_MASK 0xe000
-+
-+enum glamo_lcd_cmd_type {
-+ GLAMO_LCD_CMD_TYPE_DISP = 0x0000,
-+ GLAMO_LCD_CMD_TYPE_PARALLEL = 0x4000,
-+ GLAMO_LCD_CMD_TYPE_SERIAL = 0x8000,
-+ GLAMO_LCD_CMD_TYPE_SERIAL_DIRECT= 0xc000,
-+};
-+#define GLAMO_LCD_CMD_TYPE_MASK 0xc000
-+
-+enum glamo_lcd_cmds {
-+ GLAMO_LCD_CMD_DATA_DISP_FIRE = 0x00,
-+ GLAMO_LCD_CMD_DATA_DISP_SYNC = 0x01, /* RGB only */
-+ /* switch to command mode, no display */
-+ GLAMO_LCD_CMD_DATA_FIRE_NO_DISP = 0x02,
-+ /* display until VSYNC, switch to command */
-+ GLAMO_LCD_CMD_DATA_FIRE_VSYNC = 0x11,
-+ /* display until HSYNC, switch to command */
-+ GLAMO_LCD_CMD_DATA_FIRE_HSYNC = 0x12,
-+ /* display until VSYNC, 1 black frame, VSYNC, switch to command */
-+ GLAMO_LCD_CMD_DATA_FIRE_VSYNC_B = 0x13,
-+ /* don't care about display and switch to command */
-+ GLAMO_LCD_CMD_DATA_FIRE_FREE = 0x14, /* RGB only */
-+ /* don't care about display, keep data display but disable data,
-+ * and switch to command */
-+ GLAMO_LCD_CMD_DATA_FIRE_FREE_D = 0x15, /* RGB only */
-+};
-+
-+enum glamo_core_revisions {
-+ GLAMO_CORE_REV_A0 = 0x0000,
-+ GLAMO_CORE_REV_A1 = 0x0001,
-+ GLAMO_CORE_REV_A2 = 0x0002,
-+ GLAMO_CORE_REV_A3 = 0x0003,
-+};
-+
-+#endif /* _GLAMO_REGS_H */
-diff --git a/drivers/mfd/glamo/glamo-spi-gpio.c b/drivers/mfd/glamo/glamo-spi-gpio.c
-new file mode 100644
-index 0000000..73926bd
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-spi-gpio.c
-@@ -0,0 +1,256 @@
-+/*
-+ * Copyright (C) 2007 OpenMoko, Inc.
-+ * Author: Harald Welte <laforge@openmoko.org>
-+ *
-+ * Smedia Glamo GPIO based SPI driver
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This driver currently only implements a minimum subset of the hardware
-+ * features, esp. those features that are required to drive the jbt6k74
-+ * LCM controller asic in the TD028TTEC1 LCM.
-+ *
-+*/
-+
-+#define DEBUG
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/platform_device.h>
-+
-+#include <linux/spi/spi.h>
-+#include <linux/spi/spi_bitbang.h>
-+#include <linux/spi/glamo.h>
-+
-+#include <linux/glamofb.h>
-+
-+#include <asm/hardware.h>
-+
-+#include "glamo-core.h"
-+#include "glamo-regs.h"
-+
-+struct glamo_spigpio {
-+ struct spi_bitbang bitbang;
-+ struct spi_master *master;
-+ struct glamo_spigpio_info *info;
-+ struct glamo_core *glamo;
-+};
-+
-+static inline struct glamo_spigpio *to_sg(struct spi_device *spi)
-+{
-+ return spi->controller_data;
-+}
-+
-+static inline void setsck(struct spi_device *dev, int on)
-+{
-+ struct glamo_spigpio *sg = to_sg(dev);
-+ glamo_gpio_setpin(sg->glamo, sg->info->pin_clk, on ? 1 : 0);
-+}
-+
-+static inline void setmosi(struct spi_device *dev, int on)
-+{
-+ struct glamo_spigpio *sg = to_sg(dev);
-+ glamo_gpio_setpin(sg->glamo, sg->info->pin_mosi, on ? 1 : 0);
-+}
-+
-+static inline u32 getmiso(struct spi_device *dev)
-+{
-+ struct glamo_spigpio *sg = to_sg(dev);
-+ if (sg->info->pin_miso)
-+ return glamo_gpio_getpin(sg->glamo, sg->info->pin_miso) ? 1 : 0;
-+ else
-+ return 0;
-+}
-+
-+#define spidelay(x) ndelay(x)
-+
-+#define EXPAND_BITBANG_TXRX
-+#include <linux/spi/spi_bitbang.h>
-+
-+static u32 glamo_spigpio_txrx_mode0(struct spi_device *spi,
-+ unsigned nsecs, u32 word, u8 bits)
-+{
-+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
-+}
-+
-+static u32 glamo_spigpio_txrx_mode1(struct spi_device *spi,
-+ unsigned nsecs, u32 word, u8 bits)
-+{
-+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
-+}
-+
-+static u32 glamo_spigpio_txrx_mode2(struct spi_device *spi,
-+ unsigned nsecs, u32 word, u8 bits)
-+{
-+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
-+}
-+
-+static u32 glamo_spigpio_txrx_mode3(struct spi_device *spi,
-+ unsigned nsecs, u32 word, u8 bits)
-+{
-+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
-+}
-+
-+
-+#if 0
-+static int glamo_spigpio_setupxfer(struct spi_device *spi,
-+ struct spi_transfer *t)
-+{
-+ struct glamo_spi *gs = to_sg(spi);
-+ unsigned int bpw;
-+
-+ bpw = t ? t->bits_per_word : spi->bits_per_word;
-+
-+ if (bpw != 9 && bpw != 8) {
-+ dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+static void glamo_spigpio_chipsel(struct spi_device *spi, int value)
-+{
-+ struct glamo_spigpio *gs = to_sg(spi);
-+#if 0
-+ dev_dbg(&spi->dev, "chipsel %d: spi=%p, gs=%p, info=%p, handle=%p\n",
-+ value, spi, gs, gs->info, gs->info->glamo);
-+#endif
-+ glamo_gpio_setpin(gs->glamo, gs->info->pin_cs, value ? 0 : 1);
-+}
-+
-+
-+static int glamo_spigpio_probe(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct glamo_spigpio *sp;
-+ int ret;
-+ int i;
-+
-+ master = spi_alloc_master(&pdev->dev, sizeof(struct glamo_spigpio));
-+ if (master == NULL) {
-+ dev_err(&pdev->dev, "failed to allocate spi master\n");
-+ ret = -ENOMEM;
-+ goto err;
-+ }
-+
-+ sp = spi_master_get_devdata(master);
-+ platform_set_drvdata(pdev, sp);
-+ sp->info = pdev->dev.platform_data;
-+ if (!sp->info) {
-+ dev_err(&pdev->dev, "can't operate without platform data\n");
-+ ret = -EIO;
-+ goto err_no_pdev;
-+ }
-+
-+ master->num_chipselect = 1;
-+ master->bus_num = 2; /* FIXME: use dynamic number */
-+
-+ sp->master = spi_master_get(master);
-+ sp->glamo = sp->info->glamo;
-+
-+ sp->bitbang.master = sp->master;
-+ sp->bitbang.chipselect = glamo_spigpio_chipsel;
-+ sp->bitbang.txrx_word[SPI_MODE_0] = glamo_spigpio_txrx_mode0;
-+ sp->bitbang.txrx_word[SPI_MODE_1] = glamo_spigpio_txrx_mode1;
-+ sp->bitbang.txrx_word[SPI_MODE_2] = glamo_spigpio_txrx_mode2;
-+ sp->bitbang.txrx_word[SPI_MODE_3] = glamo_spigpio_txrx_mode3;
-+
-+ /* set state of spi pins */
-+ glamo_gpio_setpin(sp->glamo, sp->info->pin_clk, 0);
-+ glamo_gpio_setpin(sp->glamo, sp->info->pin_mosi, 0);
-+ glamo_gpio_setpin(sp->glamo, sp->info->pin_cs, 1);
-+
-+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_clk);
-+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_mosi);
-+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_cs);
-+ if (sp->info->pin_miso)
-+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_miso);
-+
-+ /* bring the LCM panel out of reset if it isn't already */
-+
-+ glamo_gpio_setpin(sp->glamo, GLAMO_GPIO4, 1);
-+ glamo_gpio_cfgpin(sp->glamo, GLAMO_GPIO4_OUTPUT);
-+ msleep(90);
-+
-+#if 0
-+ sp->dev = &pdev->dev;
-+
-+ sp->bitbang.setup_transfer = glamo_spi_setupxfer;
-+ sp->bitbang.txrx_bufs = glamo_spi_txrx;
-+ sp->bitbang.master->setup = glamo_spi_setup;
-+#endif
-+
-+ ret = spi_bitbang_start(&sp->bitbang);
-+ if (ret)
-+ goto err_no_bitbang;
-+
-+ /* register the chips to go with the board */
-+
-+ for (i = 0; i < sp->info->board_size; i++) {
-+ dev_info(&pdev->dev, "registering %p: %s\n",
-+ &sp->info->board_info[i],
-+ sp->info->board_info[i].modalias);
-+
-+ sp->info->board_info[i].controller_data = sp;
-+ spi_new_device(master, sp->info->board_info + i);
-+ }
-+
-+ return 0;
-+
-+err_no_bitbang:
-+ platform_set_drvdata(pdev, NULL);
-+err_no_pdev:
-+ spi_master_put(sp->bitbang.master);
-+err:
-+ return ret;
-+
-+}
-+
-+static int glamo_spigpio_remove(struct platform_device *pdev)
-+{
-+ struct glamo_spigpio *sp = platform_get_drvdata(pdev);
-+
-+ spi_bitbang_stop(&sp->bitbang);
-+ spi_master_put(sp->bitbang.master);
-+
-+ return 0;
-+}
-+
-+#define glamo_spigpio_suspend NULL
-+#define glamo_spigpio_resume NULL
-+
-+static struct platform_driver glamo_spi_drv = {
-+ .probe = glamo_spigpio_probe,
-+ .remove = glamo_spigpio_remove,
-+ .suspend = glamo_spigpio_suspend,
-+ .resume = glamo_spigpio_resume,
-+ .driver = {
-+ .name = "glamo-spi-gpio",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init glamo_spi_init(void)
-+{
-+ return platform_driver_register(&glamo_spi_drv);
-+}
-+
-+static void __exit glamo_spi_exit(void)
-+{
-+ platform_driver_unregister(&glamo_spi_drv);
-+}
-+
-+module_init(glamo_spi_init);
-+module_exit(glamo_spi_exit);
-+
-+MODULE_DESCRIPTION("Smedia Glamo 336x/337x LCM serial command SPI Driver");
-+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>")
-+MODULE_LICENSE("GPL");
-diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
-index f5435d8..ea945ea 100644
---- a/include/asm-arm/arch-s3c2410/irqs.h
-+++ b/include/asm-arm/arch-s3c2410/irqs.h
-@@ -155,12 +155,40 @@
- #define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28)
-
- #ifdef CONFIG_CPU_S3C2443
--#define NR_IRQS (IRQ_S3C2443_AC97+1)
-+#define _NR_IRQS (IRQ_S3C2443_AC97+1)
- #else
--#define NR_IRQS (IRQ_S3C2440_AC97+1)
-+#define _NR_IRQS (IRQ_S3C2440_AC97+1)
- #endif
-
- /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
- #define FIQ_START IRQ_EINT0
-
-+/*
-+ * The next 16 interrupts are for board specific purposes. Since
-+ * the kernel can only run on one machine at a time, we can re-use
-+ * these. If you need more, increase IRQ_BOARD_END, but keep it
-+ * within sensible limits.
-+ */
-+#define IRQ_BOARD_START _NR_IRQS
-+#define IRQ_BOARD_END (_NR_IRQS + 10)
-+
-+#if defined(CONFIG_MACH_NEO1973_GTA02)
-+#define NR_IRQS (IRQ_BOARD_END)
-+#else
-+#define NR_IRQS (IRQ_BOARD_START)
-+#endif
-+
-+/* Neo1973 GTA02 interrupts */
-+#define NEO1973_GTA02_IRQ(x) (IRQ_BOARD_START + (x))
-+#define IRQ_GLAMO(x) NEO1973_GTA02_IRQ(x)
-+#define IRQ_GLAMO_HOSTBUS IRQ_GLAMO(0)
-+#define IRQ_GLAMO_JPEG IRQ_GLAMO(1)
-+#define IRQ_GLAMO_MPEG IRQ_GLAMO(2)
-+#define IRQ_GLAMO_MPROC1 IRQ_GLAMO(3)
-+#define IRQ_GLAMO_MPROC0 IRQ_GLAMO(4)
-+#define IRQ_GLAMO_CMDQUEUE IRQ_GLAMO(5)
-+#define IRQ_GLAMO_2D IRQ_GLAMO(6)
-+#define IRQ_GLAMO_MMC IRQ_GLAMO(7)
-+#define IRQ_GLAMO_RISC IRQ_GLAMO(8)
-+
- #endif /* __ASM_ARCH_IRQ_H */
-diff --git a/include/linux/glamo-gpio.h b/include/linux/glamo-gpio.h
-new file mode 100644
-index 0000000..d00f7e9
---- /dev/null
-+++ b/include/linux/glamo-gpio.h
-@@ -0,0 +1,99 @@
-+#ifndef __GLAMO_GPIO_H
-+#define __GLAMO_GPIO_H
-+
-+struct glamo_core;
-+
-+#define GLAMO_GPIO_BANKA 0x0000
-+#define GLAMO_GPIO_BANKB 0x1000
-+#define GLAMO_GPIO_BANKC 0x2000
-+#define GLAMO_GPIO_BANKD 0x3000
-+
-+#define GLAMO_GPIONO(bank, pin) ((bank & 0xf000) | ((pin & 0xf) << 8))
-+
-+#define GLAMO_GPIO_F_IN 0x0010
-+#define GLAMO_GPIO_F_OUT 0x0020
-+#define GLAMO_GPIO_F_FUNC 0x0030
-+
-+#define GLAMO_GPIO0 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 0)
-+#define GLAMO_GPIO0_INPUT (GLAMO_GPIO0 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO0_OUTPUT (GLAMO_GPIO0 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO0_HA20 (GLAMO_GPIO0 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO1 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 1)
-+#define GLAMO_GPIO1_INPUT (GLAMO_GPIO1 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO1_OUTPUT (GLAMO_GPIO1 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO1_HA21 (GLAMO_GPIO1 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO2 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 2)
-+#define GLAMO_GPIO2_INPUT (GLAMO_GPIO2 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO2_OUTPUT (GLAMO_GPIO2 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO2_HA22 (GLAMO_GPIO2 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO3 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 3)
-+#define GLAMO_GPIO3_INPUT (GLAMO_GPIO3 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO3_OUTPUT (GLAMO_GPIO3 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO3_HA23 (GLAMO_GPIO3 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO4 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 0)
-+#define GLAMO_GPIO4_INPUT (GLAMO_GPIO4 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO4_OUTPUT (GLAMO_GPIO4 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO4_nLCS0 (GLAMO_GPIO4 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO5 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 1)
-+#define GLAMO_GPIO5_INPUT (GLAMO_GPIO5 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO5_OUTPUT (GLAMO_GPIO5 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO5_nLCS1 (GLAMO_GPIO5 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO6 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 2)
-+#define GLAMO_GPIO6_INPUT (GLAMO_GPIO6 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO6_OUTPUT (GLAMO_GPIO6 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO6_LDCLK (GLAMO_GPIO6 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO7 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 3)
-+#define GLAMO_GPIO7_INPUT (GLAMO_GPIO7 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO7_OUTPUT (GLAMO_GPIO7 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO7_nLDE (GLAMO_GPIO7 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO8 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 0)
-+#define GLAMO_GPIO8_INPUT (GLAMO_GPIO8 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO8_OUTPUT (GLAMO_GPIO8 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO8_LD16 (GLAMO_GPIO8 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO9 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 1)
-+#define GLAMO_GPIO9_INPUT (GLAMO_GPIO9 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO9_OUTPUT (GLAMO_GPIO9 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO9_LD17 (GLAMO_GPIO9 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO10 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 2)
-+#define GLAMO_GPIO10_INPUT (GLAMO_GPIO10 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO10_OUTPUT (GLAMO_GPIO10 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO10_LSCK (GLAMO_GPIO10 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO11 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 3)
-+#define GLAMO_GPIO11_INPUT (GLAMO_GPIO11 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO11_OUTPUT (GLAMO_GPIO11 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO11_LSDA (GLAMO_GPIO11 | GLAMO_GPIO_F_FUNC)
-+
-+#define GLAMO_GPIO12 GLAMO_GPIONO(GLAMO_GPIO_BANKD, 0)
-+#define GLAMO_GPIO12_INPUT (GLAMO_GPIO12 | GLAMO_GPIO_F_IN)
-+#define GLAMO_GPIO12_OUTPUT (GLAMO_GPIO12 | GLAMO_GPIO_F_OUT)
-+#define GLAMO_GPIO12_LSA0 (GLAMO_GPIO12 | GLAMO_GPIO_F_FUNC)
-+
-+
-+#define REG_OF_GPIO(gpio) (((gpio & 0xf000) >> 12)*2 \
-+ + GLAMO_REG_GPIO_GEN1)
-+#define NUM_OF_GPIO(gpio) ((gpio & 0x0f00) >> 8)
-+#define GPIO_OUT_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 0))
-+#define OUTPUT_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 4))
-+#define INPUT_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 8))
-+#define FUNC_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 12))
-+
-+void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin,
-+ unsigned int value);
-+
-+int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin);
-+
-+void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc);
-+
-+
-+#endif /* _GLAMO_GPIO */
-diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h
-new file mode 100644
-index 0000000..24742a2
---- /dev/null
-+++ b/include/linux/glamofb.h
-@@ -0,0 +1,39 @@
-+#ifndef _LINUX_GLAMOFB_H
-+#define _LINUX_GLAMOFB_H
-+
-+#include <linux/spi/glamo.h>
-+
-+struct glamofb_val {
-+ unsigned int defval;
-+ unsigned int min;
-+ unsigned int max;
-+};
-+
-+struct glamo_core;
-+
-+struct glamofb_platform_data {
-+ int width, height;
-+ int pixclock;
-+ int left_margin, right_margin;
-+ int upper_margin, lower_margin;
-+ int hsync_len, vsync_len;
-+ int fb_mem_size;
-+
-+ struct glamofb_val xres;
-+ struct glamofb_val yres;
-+ struct glamofb_val bpp;
-+
-+ struct glamo_spi_info *spi_info;
-+ struct glamo_spigpio_info *spigpio_info;
-+ struct glamo_core *glamo;
-+
-+ /* glamo mmc platform specific info */
-+ void (*glamo_set_mci_power)(unsigned char power_mode,
-+ unsigned short vdd);
-+ int (*glamo_irq_is_wired)(void);
-+};
-+
-+void glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
-+int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val);
-+
-+#endif
-diff --git a/include/linux/spi/glamo.h b/include/linux/spi/glamo.h
-new file mode 100644
-index 0000000..86419ea
---- /dev/null
-+++ b/include/linux/spi/glamo.h
-@@ -0,0 +1,28 @@
-+#ifndef __GLAMO_SPI_H
-+#define __GLAMO_SPI_H
-+
-+#include <linux/glamo-gpio.h>
-+
-+struct spi_board_info;
-+struct glamofb_handle;
-+struct glamo_core;
-+
-+struct glamo_spi_info {
-+ unsigned long board_size;
-+ struct spi_board_info *board_info;
-+ struct glamofb_handle *glamofb_handle;
-+};
-+
-+struct glamo_spigpio_info {
-+ unsigned int pin_clk;
-+ unsigned int pin_mosi;
-+ unsigned int pin_miso;
-+ unsigned int pin_cs;
-+
-+ unsigned int board_size;
-+ struct spi_board_info *board_info;
-+ struct glamo_core *glamo;
-+};
-+
-+
-+#endif
---
-1.5.6.3
-