change prefix for kernelpatchbase 2.6.26
[openwrt.git] / target / linux / s3c24xx / patches-2.6.26 / 0027-glamo-mmc.patch.patch
diff --git a/target/linux/s3c24xx/patches-2.6.26/0027-glamo-mmc.patch.patch b/target/linux/s3c24xx/patches-2.6.26/0027-glamo-mmc.patch.patch
deleted file mode 100755 (executable)
index 0eefdb7..0000000
+++ /dev/null
@@ -1,1188 +0,0 @@
-From 448ffab41f86596340e9f34dc8141bf2ca857e4e Mon Sep 17 00:00:00 2001
-From: mokopatches <mokopatches@openmoko.org>
-Date: Wed, 16 Jul 2008 14:44:51 +0100
-Subject: [PATCH] glamo-mmc.patch
-
----
- drivers/mfd/glamo/Kconfig      |    9 +
- drivers/mfd/glamo/Makefile     |    1 +
- drivers/mfd/glamo/glamo-core.c |   17 +-
- drivers/mfd/glamo/glamo-mci.c  |  837 ++++++++++++++++++++++++++++++++++++++++
- drivers/mfd/glamo/glamo-mci.h  |   76 ++++
- drivers/mfd/glamo/glamo-regs.h |  169 ++++++++-
- 6 files changed, 1099 insertions(+), 10 deletions(-)
- create mode 100644 drivers/mfd/glamo/glamo-mci.c
- create mode 100644 drivers/mfd/glamo/glamo-mci.h
-
-diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig
-index b99f2b2..ec2ae3d 100644
---- a/drivers/mfd/glamo/Kconfig
-+++ b/drivers/mfd/glamo/Kconfig
-@@ -33,3 +33,12 @@ config MFD_GLAMO_SPI_FB
-        control channel.  This SPI interface is frequently used to
-        interconnect the LCM control interface.
-+config MFD_GLAMO_MCI
-+      tristate "Glamo S3C SD/MMC Card Interface support"
-+      depends on MFD_GLAMO && MMC
-+      help
-+        This selects a driver for the MCI interface found in
-+        the S-Media GLAMO chip, as used in OpenMoko
-+        neo1973 GTA-02.
-+
-+        If unsure, say N.
-\ No newline at end of file
-diff --git a/drivers/mfd/glamo/Makefile b/drivers/mfd/glamo/Makefile
-index fb53982..dc64d50 100644
---- a/drivers/mfd/glamo/Makefile
-+++ b/drivers/mfd/glamo/Makefile
-@@ -8,4 +8,5 @@ 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
-+obj-$(CONFIG_MFD_GLAMO_MCI)           += glamo-mci.o
-diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
-index acf545f..8497de2 100644
---- a/drivers/mfd/glamo/glamo-core.c
-+++ b/drivers/mfd/glamo/glamo-core.c
-@@ -440,7 +440,22 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
- {
-       spin_lock(&glamo->lock);
-       switch (engine) {
--      /* FIXME: Implementation */
-+      case GLAMO_ENGINE_MMC:
-+              __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC, 0,
-+                                                 GLAMO_CLOCK_MMC_EN_M9CLK |
-+                                                 GLAMO_CLOCK_MMC_EN_TCLK |
-+                                                 GLAMO_CLOCK_MMC_DG_M9CLK |
-+                                                 GLAMO_CLOCK_MMC_DG_TCLK);
-+              __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), 0,
-+                                                 GLAMO_HOSTBUS2_MMIO_EN_MMC);
-+              /* disable the TCLK divider clk input */
-+              __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0,
-+                                              GLAMO_CLOCK_GEN51_EN_DIV_TCLK);
-+              /* good idea to hold the thing in reset when we power it off? */
-+/*            writew(readw(glamo->base + GLAMO_REG_CLOCK_MMC) |
-+                    GLAMO_CLOCK_MMC_RESET, glamo->base + GLAMO_REG_CLOCK_MMC);
-+*/
-+              break;
-       default:
-               break;
-       }
-diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
-new file mode 100644
-index 0000000..f559e5e
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-mci.c
-@@ -0,0 +1,837 @@
-+/*
-+ *  linux/drivers/mmc/host/glamo-mmc.c - Glamo MMC driver
-+ *
-+ *  Copyright (C) 2007 OpenMoko, Inc,  Andy Green <andy@openmoko.com>
-+ *  Based on S3C MMC driver that was:
-+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>
-+ *
-+ * 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.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/clk.h>
-+#include <linux/mmc/mmc.h>
-+#include <linux/mmc/host.h>
-+#include <linux/platform_device.h>
-+#include <linux/irq.h>
-+#include <linux/pcf50633.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/dma.h>
-+#include <asm/dma-mapping.h>
-+#include <asm/io.h>
-+
-+#include "glamo-mci.h"
-+#include "glamo-core.h"
-+#include "glamo-regs.h"
-+
-+/* from glamo-core.c */
-+extern struct glamo_mci_pdata glamo_mci_def_pdata;
-+
-+
-+#define DRIVER_NAME "glamo-mci"
-+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start) + 1)
-+
-+static void glamo_mci_send_request(struct mmc_host *mmc);
-+
-+unsigned char CRC7(u8 * pu8, int cnt)
-+{
-+      u8 crc = 0;
-+
-+      while (cnt--) {
-+              int n;
-+              u8 d = *pu8++;
-+              for (n = 0; n < 8; n++) {
-+                      crc <<= 1;
-+                      if ((d & 0x80) ^ (crc & 0x80))
-+                              crc ^= 0x09;
-+                      d <<= 1;
-+              }
-+      }
-+      return (crc << 1) | 1;
-+}
-+
-+/* these _dly versions account for the dead time rules for reg access */
-+static u16 readw_dly(u16 __iomem * pu16)
-+{
-+      glamo_reg_access_delay();
-+      return readw(pu16);
-+}
-+
-+static void writew_dly(u16 val, u16 __iomem * pu16)
-+{
-+      glamo_reg_access_delay();
-+      writew(val, pu16);
-+}
-+
-+static int get_data_buffer(struct glamo_mci_host *host,
-+                         volatile u32 *words, volatile u16 **pointer)
-+{
-+      struct scatterlist *sg;
-+
-+      *words = 0;
-+      *pointer = NULL;
-+
-+      if (host->pio_active == XFER_NONE)
-+              return -EINVAL;
-+
-+      if ((!host->mrq) || (!host->mrq->data))
-+              return -EINVAL;
-+
-+      if (host->pio_sgptr >= host->mrq->data->sg_len) {
-+              dev_dbg(&host->pdev->dev, "no more buffers (%i/%i)\n",
-+                    host->pio_sgptr, host->mrq->data->sg_len);
-+              return -EBUSY;
-+      }
-+      sg = &host->mrq->data->sg[host->pio_sgptr];
-+
-+      *words = sg->length >> 1; /* we are working with a 16-bit data bus */
-+      *pointer = page_address(sg_page(sg)) + sg->offset;
-+
-+      BUG_ON(((long)(*pointer)) & 1);
-+
-+      host->pio_sgptr++;
-+
-+      /* dev_info(&host->pdev->dev, "new buffer (%i/%i)\n",
-+            host->pio_sgptr, host->mrq->data->sg_len); */
-+      return 0;
-+}
-+
-+static void do_pio_read(struct glamo_mci_host *host)
-+{
-+      int res;
-+      u16 __iomem *from_ptr = host->base_data + (RESSIZE(host->mem_data) /
-+                                                            sizeof(u16) / 2);
-+#ifdef DEBUG
-+      u16 * block;
-+#endif
-+
-+      while (1) {
-+              res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
-+              if (res) {
-+                      host->pio_active = XFER_NONE;
-+                      host->complete_what = COMPLETION_FINALIZE;
-+
-+                      dev_dbg(&host->pdev->dev, "pio_read(): "
-+                              "complete (no more data).\n");
-+                      return;
-+              }
-+
-+              dev_dbg(&host->pdev->dev, "pio_read(): host->pio_words: %d\n",
-+                              host->pio_words);
-+
-+              host->pio_count += host->pio_words << 1;
-+
-+#ifdef DEBUG
-+              block = (u16 *)host->pio_ptr;
-+              res = host->pio_words << 1;
-+#endif
-+              while (host->pio_words--)
-+                      *host->pio_ptr++ = *from_ptr++;
-+#ifdef DEBUG
-+              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
-+                             (void *)block, res, 1);
-+#endif
-+      }
-+}
-+
-+static int do_pio_write(struct glamo_mci_host *host)
-+{
-+      int res = 0;
-+      volatile u16 __iomem *to_ptr = host->base_data;
-+      int err = 0;
-+
-+      dev_dbg(&host->pdev->dev, "pio_write():\n");
-+      while (!res) {
-+              res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
-+              if (res)
-+                      continue;
-+
-+              dev_dbg(&host->pdev->dev, "pio_write():new source: [%i]@[%p]\n",
-+                      host->pio_words, host->pio_ptr);
-+
-+              host->pio_count += host->pio_words << 1;
-+              while (host->pio_words--)
-+                      writew(*host->pio_ptr++, to_ptr++);
-+      }
-+
-+      dev_dbg(&host->pdev->dev, "pio_write(): complete\n");
-+      host->pio_active = XFER_NONE;
-+      return err;
-+}
-+
-+static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
-+{
-+      struct glamo_mci_host *host = (struct glamo_mci_host *)
-+                                    desc->handler_data;
-+      u16 status;
-+      struct mmc_command *cmd;
-+      unsigned long iflags;
-+
-+      if (!host)
-+              return;
-+      if (!host->mrq)
-+              return;
-+      cmd = host->mrq->cmd;
-+      if (!cmd)
-+              return;
-+
-+      spin_lock_irqsave(&host->complete_lock, iflags);
-+
-+      status = readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1);
-+
-+      /* ack this interrupt source */
-+      writew(GLAMO_IRQ_MMC,
-+             glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR);
-+
-+      if (status & (GLAMO_STAT1_MMC_RTOUT |
-+                    GLAMO_STAT1_MMC_DTOUT))
-+              cmd->error = -ETIMEDOUT;
-+      if (status & (GLAMO_STAT1_MMC_BWERR |
-+                    GLAMO_STAT1_MMC_BRERR))
-+              cmd->error = -EILSEQ;
-+      if (cmd->error) {
-+              dev_err(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
-+              goto done;
-+      }
-+
-+      if (host->pio_active == XFER_READ)
-+              do_pio_read(host);
-+
-+      host->mrq->data->bytes_xfered = host->pio_count;
-+      dev_dbg(&host->pdev->dev, "status = 0x%04x count=%d\n",
-+               status, host->pio_count);
-+
-+      /* issue STOP if we have been given one to use */
-+      if (host->mrq->stop) {
-+              host->cmd_is_stop = 1;
-+              glamo_mci_send_request(host->mmc);
-+              host->cmd_is_stop = 0;
-+      }
-+done:
-+      host->complete_what = COMPLETION_NONE;
-+      host->mrq = NULL;
-+      mmc_request_done(host->mmc, cmd->mrq);
-+      spin_unlock_irqrestore(&host->complete_lock, iflags);
-+}
-+
-+static int glamo_mci_send_command(struct glamo_mci_host *host,
-+                                struct mmc_command *cmd)
-+{
-+      u8 u8a[6];
-+      u16 fire = 0;
-+
-+      /* if we can't do it, reject as busy */
-+      if (!readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1) &
-+           GLAMO_STAT1_MMC_IDLE) {
-+              host->mrq = NULL;
-+              cmd->error = -EBUSY;
-+              mmc_request_done(host->mmc, host->mrq);
-+              return -EBUSY;
-+      }
-+
-+      /* create an array in wire order for CRC computation */
-+      u8a[0] = 0x40 | (cmd->opcode & 0x3f);
-+      u8a[1] = (u8)(cmd->arg >> 24);
-+      u8a[2] = (u8)(cmd->arg >> 16);
-+      u8a[3] = (u8)(cmd->arg >> 8);
-+      u8a[4] = (u8)cmd->arg;
-+      u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */
-+
-+      /* issue the wire-order array including CRC in register order */
-+      writew_dly((u8a[4] << 8) | u8a[5], host->base + GLAMO_REG_MMC_CMD_REG1);
-+      writew_dly((u8a[2] << 8) | u8a[3], host->base + GLAMO_REG_MMC_CMD_REG2);
-+      writew_dly((u8a[0] << 8) | u8a[1], host->base + GLAMO_REG_MMC_CMD_REG3);
-+
-+      /* command index toggle */
-+      fire |= (host->ccnt & 1) << 12;
-+
-+      /* set type of command */
-+      switch (mmc_cmd_type(cmd)) {
-+      case MMC_CMD_BC:
-+              fire |= GLAMO_FIRE_MMC_CMDT_BNR;
-+              break;
-+      case MMC_CMD_BCR:
-+              fire |= GLAMO_FIRE_MMC_CMDT_BR;
-+              break;
-+      case MMC_CMD_AC:
-+              fire |= GLAMO_FIRE_MMC_CMDT_AND;
-+              break;
-+      case MMC_CMD_ADTC:
-+              fire |= GLAMO_FIRE_MMC_CMDT_AD;
-+              break;
-+      }
-+      /*
-+       * if it expects a response, set the type expected
-+       *
-+       * R1, Length  : 48bit, Normal response
-+       * R1b, Length : 48bit, same R1, but added card busy status
-+       * R2, Length  : 136bit (really 128 bits with CRC snipped)
-+       * R3, Length  : 48bit (OCR register value)
-+       * R4, Length  : 48bit, SDIO_OP_CONDITION, Reverse SDIO Card
-+       * R5, Length  : 48bit, IO_RW_DIRECTION, Reverse SDIO Card
-+       * R6, Length  : 48bit (RCA register)
-+       * R7, Length  : 48bit (interface condition, VHS(voltage supplied),
-+       *                     check pattern, CRC7)
-+       */
-+      switch (mmc_resp_type(cmd)) {
-+      case MMC_RSP_R6: /* same index as R7 and R1 */
-+              fire |= GLAMO_FIRE_MMC_RSPT_R1;
-+              break;
-+      case MMC_RSP_R1B:
-+              fire |= GLAMO_FIRE_MMC_RSPT_R1b;
-+              break;
-+      case MMC_RSP_R2:
-+              fire |= GLAMO_FIRE_MMC_RSPT_R2;
-+              break;
-+      case MMC_RSP_R3:
-+              fire |= GLAMO_FIRE_MMC_RSPT_R3;
-+              break;
-+      /* R4 and R5 supported by chip not defined in linux/mmc/core.h (sdio) */
-+      }
-+      /*
-+       * From the command index, set up the command class in the host ctrllr
-+       *
-+       * missing guys present on chip but couldn't figure out how to use yet:
-+       *     0x0 "stream read"
-+       *     0x9 "cancel running command"
-+       */
-+      switch (cmd->opcode) {
-+      case MMC_READ_SINGLE_BLOCK:
-+              fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */
-+              break;
-+      case MMC_SWITCH: /* 64 byte payload */
-+      case 0x33: /* observed issued by MCI */
-+      case MMC_READ_MULTIPLE_BLOCK:
-+              /* we will get an interrupt off this */
-+              if (!cmd->mrq->stop)
-+                      /* multiblock no stop */
-+                      fire |= GLAMO_FIRE_MMC_CC_MBRNS;
-+              else
-+                       /* multiblock with stop */
-+                      fire |= GLAMO_FIRE_MMC_CC_MBRS;
-+              break;
-+      case MMC_WRITE_BLOCK:
-+              fire |= GLAMO_FIRE_MMC_CC_SBW; /* single block write */
-+              break;
-+      case MMC_WRITE_MULTIPLE_BLOCK:
-+              if (cmd->mrq->stop)
-+                       /* multiblock with stop */
-+                      fire |= GLAMO_FIRE_MMC_CC_MBWS;
-+              else
-+                       /* multiblock NO stop-- 'RESERVED'? */
-+                      fire |= GLAMO_FIRE_MMC_CC_MBWNS;
-+              break;
-+      case MMC_STOP_TRANSMISSION:
-+              fire |= GLAMO_FIRE_MMC_CC_STOP; /* STOP */
-+              break;
-+      default:
-+              fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */
-+              break;
-+      }
-+      /* enforce timeout */
-+      if (cmd->data) {
-+              if (cmd->data->timeout_clks)
-+                      writew_dly(cmd->data->timeout_clks >> 4, /* / 16 clks */
-+                                      host->base + GLAMO_REG_MMC_TIMEOUT);
-+              else
-+                      writew_dly(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
-+      } else
-+              writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
-+
-+      /* Generate interrupt on txfer; drive strength max */
-+      writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) & 0xfe) |
-+                 0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT |
-+                 GLAMO_BASIC_MMC_EN_COMPL_INT |
-+                 GLAMO_BASIC_MMC_EN_DR_STR0 |
-+                 GLAMO_BASIC_MMC_EN_DR_STR1,
-+                 host->base + GLAMO_REG_MMC_BASIC);
-+
-+      /* send the command out on the wire */
-+      /* dev_info(&host->pdev->dev, "Using FIRE %04X\n", fire); */
-+      writew_dly(fire, host->base + GLAMO_REG_MMC_CMD_FIRE);
-+      cmd->error = 0;
-+      return 0;
-+}
-+
-+static int glamo_mci_prepare_pio(struct glamo_mci_host *host,
-+                               struct mmc_data *data)
-+{
-+      /*
-+       * the S-Media-internal RAM offset for our MMC buffer
-+       * Read is halfway up the buffer and write is at the start
-+       */
-+      if (data->flags & MMC_DATA_READ) {
-+              writew_dly((u16)(GLAMO_FB_SIZE + (RESSIZE(host->mem_data) / 2)),
-+                         host->base + GLAMO_REG_MMC_WDATADS1);
-+              writew_dly((u16)((GLAMO_FB_SIZE +
-+                                      (RESSIZE(host->mem_data) / 2)) >> 16),
-+                         host->base + GLAMO_REG_MMC_WDATADS2);
-+      } else {
-+              writew_dly((u16)GLAMO_FB_SIZE, host->base +
-+                                             GLAMO_REG_MMC_RDATADS1);
-+              writew_dly((u16)(GLAMO_FB_SIZE >> 16), host->base +
-+                                                     GLAMO_REG_MMC_RDATADS2);
-+      }
-+
-+      /* set up the block info */
-+      writew_dly(data->blksz, host->base + GLAMO_REG_MMC_DATBLKLEN);
-+      writew_dly(data->blocks, host->base + GLAMO_REG_MMC_DATBLKCNT);
-+      dev_dbg(&host->pdev->dev, "(blksz=%d, count=%d)\n",
-+                                 data->blksz, data->blocks);
-+      host->pio_sgptr = 0;
-+      host->pio_words = 0;
-+      host->pio_count = 0;
-+      host->pio_active = 0;
-+      /* if write, prep the write into the shared RAM before the command */
-+      if (data->flags & MMC_DATA_WRITE) {
-+              host->pio_active = XFER_WRITE;
-+              return do_pio_write(host);
-+      }
-+      host->pio_active = XFER_READ;
-+      return 0;
-+}
-+
-+static void glamo_mci_send_request(struct mmc_host *mmc)
-+{
-+      struct glamo_mci_host *host = mmc_priv(mmc);
-+      struct mmc_request *mrq = host->mrq;
-+      struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
-+      u16 * pu16 = (u16 *)&cmd->resp[0];
-+      u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1);
-+      u16 status;
-+      int n;
-+
-+      host->ccnt++;
-+      /*
-+       * somehow 2.6.24 MCI manages to issue MMC_WRITE_BLOCK *without* the
-+       * MMC_DATA_WRITE flag, WTF?  Work around the madness.
-+       */
-+      if (cmd->opcode == MMC_WRITE_BLOCK)
-+              if (mrq->data)
-+                      mrq->data->flags |= MMC_DATA_WRITE;
-+
-+       /* this guy has data to read/write? */
-+      if ((!host->cmd_is_stop) && cmd->data) {
-+              int res;
-+              host->dcnt++;
-+              res = glamo_mci_prepare_pio(host, cmd->data);
-+              if (res) {
-+                      cmd->error = -EIO;
-+                      cmd->data->error = -EIO;
-+                      mmc_request_done(mmc, mrq);
-+                      return;
-+              }
-+      }
-+
-+      dev_dbg(&host->pdev->dev,"cmd 0x%x, "
-+               "arg 0x%x data=%p mrq->stop=%p flags 0x%x\n",
-+               cmd->opcode, cmd->arg, cmd->data, cmd->mrq->stop,
-+               cmd->flags);
-+
-+      if (glamo_mci_send_command(host, cmd))
-+              return;
-+      /*
-+       * we must spin until response is ready or timed out
-+       * -- we don't get interrupts unless there is a bulk rx
-+       */
-+      do
-+              status = readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1);
-+      while ((((status >> 15) & 1) != (host->ccnt & 1)) ||
-+              (!(status & (GLAMO_STAT1_MMC_RB_RRDY |
-+                           GLAMO_STAT1_MMC_RTOUT |
-+                           GLAMO_STAT1_MMC_DTOUT |
-+                           GLAMO_STAT1_MMC_BWERR |
-+                           GLAMO_STAT1_MMC_BRERR))));
-+
-+      if (status & (GLAMO_STAT1_MMC_RTOUT |
-+                    GLAMO_STAT1_MMC_DTOUT))
-+              cmd->error = -ETIMEDOUT;
-+      if (status & (GLAMO_STAT1_MMC_BWERR |
-+                    GLAMO_STAT1_MMC_BRERR))
-+              cmd->error = -EILSEQ;
-+
-+      if (host->cmd_is_stop)
-+              return;
-+
-+      if (cmd->error) {
-+              dev_err(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
-+              goto done;
-+      }
-+      /*
-+       * mangle the response registers in two different exciting
-+       * undocumented ways discovered by trial and error
-+       */
-+      if (mmc_resp_type(cmd) == MMC_RSP_R2)
-+              /* grab the response */
-+              for (n = 0; n < 8; n++) /* super mangle power 1 */
-+                      pu16[n ^ 6] = readw_dly(&reg_resp[n]);
-+      else
-+              for (n = 0; n < 3; n++) /* super mangle power 2 */
-+                      pu16[n] = (readw_dly(&reg_resp[n]) >> 8) |
-+                                (readw_dly(&reg_resp[n + 1]) << 8);
-+      /*
-+       * if we don't have bulk data to take care of, we're done
-+       */
-+      if (!cmd->data)
-+              goto done;
-+      if (!(cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)))
-+              goto done;
-+      /*
-+       * Otherwise can can use the interrupt as async completion --
-+       * if there is read data coming, or we wait for write data to complete,
-+       * exit without mmc_request_done() as the payload interrupt
-+       * will service it
-+       */
-+      dev_dbg(&host->pdev->dev, "Waiting for payload data\n");
-+      /*
-+       * if the glamo INT# line isn't wired (*cough* it can happen)
-+       * I'm afraid we have to spin on the IRQ status bit and "be
-+       * our own INT# line"
-+       */
-+      if (!glamo_mci_def_pdata.pglamo->irq_works) {
-+              /* we have faith we will get an "interrupt"... */
-+              while (!(readw_dly(glamo_mci_def_pdata.pglamo->base +
-+                       GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC))
-+                      ;
-+              /* yay we are an interrupt controller! -- call the ISR */
-+              glamo_mci_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC),
-+                            irq_desc + IRQ_GLAMO(GLAMO_IRQIDX_MMC));
-+      }
-+      return;
-+
-+done:
-+      host->complete_what = COMPLETION_NONE;
-+      host->mrq = NULL;
-+      mmc_request_done(host->mmc, cmd->mrq);
-+}
-+
-+static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
-+{
-+      struct glamo_mci_host *host = mmc_priv(mmc);
-+
-+      host->cmd_is_stop = 0;
-+      host->mrq = mrq;
-+      glamo_mci_send_request(mmc);
-+}
-+
-+static void glamo_mci_reset(struct glamo_mci_host *host)
-+{
-+      /* reset MMC controller */
-+      writew_dly(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK |
-+                 GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
-+                 GLAMO_CLOCK_MMC_EN_M9CLK,
-+                 glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC);
-+      msleep(1);
-+      /* and disable reset */
-+      writew_dly(GLAMO_CLOCK_MMC_DG_TCLK |
-+                 GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
-+                 GLAMO_CLOCK_MMC_EN_M9CLK,
-+                 glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC);
-+}
-+
-+static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-+{
-+      struct glamo_mci_host *host = mmc_priv(mmc);
-+      int mci_psc = 0;
-+      int n = 0;
-+
-+      /* Set power */
-+      switch(ios->power_mode) {
-+      case MMC_POWER_ON:
-+      case MMC_POWER_UP:
-+              if (host->power_mode_current != MMC_POWER_OFF)
-+                      break;
-+              if (host->vdd_current != ios->vdd) {
-+                      host->pdata->glamo_set_mci_power(ios->power_mode,
-+                                                       ios->vdd);
-+                      host->vdd_current = ios->vdd;
-+              }
-+              glamo_engine_enable(glamo_mci_def_pdata.pglamo,
-+                                                      GLAMO_ENGINE_MMC);
-+              glamo_mci_reset(host);
-+              break;
-+
-+      case MMC_POWER_OFF:
-+      default:
-+              if (host->power_mode_current == MMC_POWER_OFF)
-+                      break;
-+              glamo_engine_disable(glamo_mci_def_pdata.pglamo,
-+                                   GLAMO_ENGINE_MMC);
-+              host->pdata->glamo_set_mci_power(MMC_POWER_OFF, 0);
-+              host->vdd_current = -1;
-+              break;
-+      }
-+      host->power_mode_current = ios->power_mode;
-+
-+       /* Set clock */
-+/*    if (ios->clock) { */
-+      for (mci_psc = 0; mci_psc < 256; mci_psc++) {
-+              host->real_rate = host->clk_rate / (mci_psc + 1);
-+              if (host->real_rate <= ios->clock)
-+                      break;
-+      }
-+      if (mci_psc > 255)
-+              mci_psc = 255;
-+      host->clk_div = mci_psc;
-+      /* set the nearest prescaler factor
-+      *
-+      * register shared with SCLK divisor -- no chance of race because
-+      * we don't use sensor interface
-+      */
-+      writew_dly((readw(glamo_mci_def_pdata.pglamo->base +
-+                      GLAMO_REG_CLOCK_GEN8) & 0xff00) | host->clk_div,
-+              glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8);
-+      /* enable clock to divider input */
-+      writew_dly(readw(glamo_mci_def_pdata.pglamo->base +
-+              GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK,
-+              glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
-+#if 0
-+      } else { /* stop clock */
-+              host->real_rate = 0;
-+              /* remove clock from divider input */
-+              writew(readw(glamo_mci_def_pdata.pglamo->base +
-+                   GLAMO_REG_CLOCK_GEN5_1) & (~GLAMO_CLOCK_GEN51_EN_DIV_TCLK),
-+                   glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
-+      }
-+#endif
-+      if ((ios->power_mode == MMC_POWER_ON) ||
-+          (ios->power_mode == MMC_POWER_UP)) {
-+              dev_info(&host->pdev->dev,
-+                      "powered (vdd = %d) clk: %lukHz div=%d (req: %ukHz). "
-+                      "Bus width=%d\n",ios->vdd,
-+                      host->real_rate / 1000, mci_psc,
-+                      ios->clock / 1000, ios->bus_width);
-+      } else
-+              dev_info(&host->pdev->dev, "glamo_mci_set_ios: power down.\n");
-+
-+      /* set bus width */
-+      host->bus_width = ios->bus_width;
-+      if (host->bus_width == MMC_BUS_WIDTH_4)
-+              n = GLAMO_BASIC_MMC_EN_4BIT_DATA;
-+      writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) &
-+                                        (~GLAMO_BASIC_MMC_EN_4BIT_DATA)) | n,
-+                                            host->base + GLAMO_REG_MMC_BASIC);
-+}
-+
-+
-+/*
-+ * no physical write protect supported by us
-+ */
-+static int glamo_mci_get_ro(struct mmc_host *mmc)
-+{
-+      return 0;
-+}
-+
-+static struct mmc_host_ops glamo_mci_ops = {
-+      .request        = glamo_mci_request,
-+      .set_ios        = glamo_mci_set_ios,
-+      .get_ro         = glamo_mci_get_ro,
-+};
-+
-+static int glamo_mci_probe(struct platform_device *pdev)
-+{
-+      struct mmc_host         *mmc;
-+      struct glamo_mci_host   *host;
-+      int ret;
-+
-+      dev_info(&pdev->dev, "glamo_mci driver (C)2007 OpenMoko, Inc\n");
-+
-+      mmc = mmc_alloc_host(sizeof(struct glamo_mci_host), &pdev->dev);
-+      if (!mmc) {
-+              ret = -ENOMEM;
-+              goto probe_out;
-+      }
-+
-+      host = mmc_priv(mmc);
-+      host->mmc = mmc;
-+      host->pdev = pdev;
-+      host->pdata = &glamo_mci_def_pdata;
-+      host->power_mode_current = MMC_POWER_OFF;
-+
-+      host->complete_what = COMPLETION_NONE;
-+      host->pio_active = XFER_NONE;
-+
-+      spin_lock_init(&host->complete_lock);
-+
-+      host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+      if (!host->mem) {
-+              dev_err(&pdev->dev,
-+                      "failed to get io memory region resouce.\n");
-+
-+              ret = -ENOENT;
-+              goto probe_free_host;
-+      }
-+
-+      host->mem = request_mem_region(host->mem->start,
-+              RESSIZE(host->mem), pdev->name);
-+
-+      if (!host->mem) {
-+              dev_err(&pdev->dev, "failed to request io memory region.\n");
-+              ret = -ENOENT;
-+              goto probe_free_host;
-+      }
-+
-+      host->base = ioremap(host->mem->start, RESSIZE(host->mem));
-+      if (!host->base) {
-+              dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
-+              ret = -EINVAL;
-+              goto probe_free_mem_region;
-+      }
-+
-+      /* set the handler for our bit of the shared chip irq register */
-+      set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), glamo_mci_irq);
-+      /* stash host as our handler's private data */
-+      set_irq_data(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host);
-+
-+      /* Get ahold of our data buffer we use for data in and out on MMC */
-+      host->mem_data = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+      if (!host->mem_data) {
-+              dev_err(&pdev->dev,
-+                      "failed to get io memory region resource.\n");
-+              ret = -ENOENT;
-+              goto probe_iounmap;
-+      }
-+
-+      host->mem_data = request_mem_region(host->mem_data->start,
-+              RESSIZE(host->mem_data), pdev->name);
-+
-+      if (!host->mem_data) {
-+              dev_err(&pdev->dev, "failed to request io memory region.\n");
-+              ret = -ENOENT;
-+              goto probe_iounmap;
-+      }
-+      host->base_data = ioremap(host->mem_data->start,
-+                                        RESSIZE(host->mem_data));
-+      host->data_max_size = RESSIZE(host->mem_data);
-+
-+      if (host->base_data == 0) {
-+              dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
-+              ret = -EINVAL;
-+              goto probe_free_mem_region_data;
-+      }
-+
-+      host->vdd_current = 0;
-+      host->clk_rate = 50000000; /* really it's 49152000 */
-+      host->clk_div = 16;
-+
-+      /* explain our host controller capabilities */
-+      mmc->ops        = &glamo_mci_ops;
-+      mmc->ocr_avail  = host->pdata->ocr_avail;
-+      mmc->caps       = MMC_CAP_4_BIT_DATA |
-+                        MMC_CAP_MULTIWRITE |
-+                        MMC_CAP_MMC_HIGHSPEED |
-+                        MMC_CAP_SD_HIGHSPEED;
-+      mmc->f_min      = host->clk_rate / 256;
-+      /*
-+       * held at /4 due to concerns of 100R recommended series resistor
-+       * allows 16MHz @ 4-bit --> 8MBytes/sec raw
-+       */
-+      mmc->f_max      = host->clk_rate / 3;
-+
-+      mmc->max_blk_count      = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */
-+      mmc->max_blk_size       = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */
-+      mmc->max_req_size       = RESSIZE(host->mem_data) / 2;
-+      mmc->max_seg_size       = mmc->max_req_size;
-+      mmc->max_phys_segs      = 1; /* hw doesn't talk about segs??? */
-+      mmc->max_hw_segs        = 1;
-+
-+      dev_info(&host->pdev->dev, "probe: mapped mci_base:%p irq:%u.\n",
-+              host->base, host->irq);
-+
-+      if ((ret = mmc_add_host(mmc))) {
-+              dev_err(&pdev->dev, "failed to add mmc host.\n");
-+              goto probe_free_mem_region_data;
-+      }
-+
-+      platform_set_drvdata(pdev, mmc);
-+
-+      dev_info(&pdev->dev,"initialisation done.\n");
-+      return 0;
-+
-+ probe_free_mem_region_data:
-+      release_mem_region(host->mem_data->start, RESSIZE(host->mem_data));
-+
-+ probe_iounmap:
-+      iounmap(host->base);
-+
-+ probe_free_mem_region:
-+      release_mem_region(host->mem->start, RESSIZE(host->mem));
-+
-+ probe_free_host:
-+      mmc_free_host(mmc);
-+ probe_out:
-+      return ret;
-+}
-+
-+static int glamo_mci_remove(struct platform_device *pdev)
-+{
-+      struct mmc_host         *mmc  = platform_get_drvdata(pdev);
-+      struct glamo_mci_host   *host = mmc_priv(mmc);
-+
-+      mmc_remove_host(mmc);
-+      /* stop using our handler, revert it to default */
-+      set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), handle_level_irq);
-+      iounmap(host->base);
-+      iounmap(host->base_data);
-+      release_mem_region(host->mem->start, RESSIZE(host->mem));
-+      release_mem_region(host->mem_data->start, RESSIZE(host->mem_data));
-+      mmc_free_host(mmc);
-+
-+      glamo_engine_disable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC);
-+      return 0;
-+}
-+
-+
-+#ifdef CONFIG_PM
-+
-+static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
-+{
-+      struct mmc_host *mmc = platform_get_drvdata(dev);
-+
-+      return  mmc_suspend_host(mmc, state);
-+}
-+
-+static int glamo_mci_resume(struct platform_device *dev)
-+{
-+      struct mmc_host *mmc = platform_get_drvdata(dev);
-+
-+      return mmc_resume_host(mmc);
-+}
-+
-+#else /* CONFIG_PM */
-+#define glamo_mci_suspend NULL
-+#define glamo_mci_resume NULL
-+#endif /* CONFIG_PM */
-+
-+
-+static struct platform_driver glamo_mci_driver =
-+{
-+      .driver.name    = "glamo-mci",
-+      .probe          = glamo_mci_probe,
-+      .remove         = glamo_mci_remove,
-+      .suspend        = glamo_mci_suspend,
-+      .resume         = glamo_mci_resume,
-+};
-+
-+static int __init glamo_mci_init(void)
-+{
-+      platform_driver_register(&glamo_mci_driver);
-+      return 0;
-+}
-+
-+static void __exit glamo_mci_exit(void)
-+{
-+      platform_driver_unregister(&glamo_mci_driver);
-+}
-+
-+module_init(glamo_mci_init);
-+module_exit(glamo_mci_exit);
-+
-+MODULE_DESCRIPTION("Glamo MMC/SD Card Interface driver");
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
-diff --git a/drivers/mfd/glamo/glamo-mci.h b/drivers/mfd/glamo/glamo-mci.h
-new file mode 100644
-index 0000000..40c3e24
---- /dev/null
-+++ b/drivers/mfd/glamo/glamo-mci.h
-@@ -0,0 +1,76 @@
-+/*
-+ *  linux/drivers/mmc/host/glamo-mmc.h - GLAMO MCI driver
-+ *
-+ *  Copyright (C) 2007-2008 OpenMoko, Inc, Andy Green <andy@openmoko.com>
-+ *   based on S3C MMC driver -->
-+ *  Copyright (C) 2004-2006 Thomas Kleffel, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+enum glamo_mci_waitfor {
-+      COMPLETION_NONE,
-+      COMPLETION_FINALIZE,
-+      COMPLETION_CMDSENT,
-+      COMPLETION_RSPFIN,
-+      COMPLETION_XFERFINISH,
-+      COMPLETION_XFERFINISH_RSPFIN,
-+};
-+
-+struct glamo_mci_host {
-+      struct platform_device  *pdev;
-+      struct glamo_mci_pdata  *pdata;
-+      struct mmc_host         *mmc;
-+      struct resource         *mem;
-+      struct resource         *mem_data;
-+      struct clk              *clk;
-+      void __iomem            *base;
-+      u16 __iomem             *base_data;
-+      int                     irq;
-+      int                     irq_cd;
-+      int                     dma;
-+      int                     data_max_size;
-+
-+      int                     power_mode_current;
-+      unsigned int            vdd_current;
-+
-+      unsigned long           clk_rate;
-+      unsigned long           clk_div;
-+      unsigned long           real_rate;
-+      u8                      prescaler;
-+
-+      unsigned                sdiimsk;
-+      int                     dodma;
-+
-+      volatile int            dmatogo;
-+
-+      struct mmc_request      *mrq;
-+      int                     cmd_is_stop;
-+
-+      spinlock_t              complete_lock;
-+      volatile enum glamo_mci_waitfor
-+                              complete_what;
-+
-+      volatile int            dma_complete;
-+
-+      volatile u32            pio_sgptr;
-+      volatile u32            pio_words;
-+      volatile u32            pio_count;
-+      volatile u16            *pio_ptr;
-+#define XFER_NONE 0
-+#define XFER_READ 1
-+#define XFER_WRITE 2
-+      volatile u32            pio_active;
-+
-+      int                     bus_width;
-+
-+      char                    dbgmsg_cmd[301];
-+      char                    dbgmsg_dat[301];
-+      volatile char           *status;
-+
-+      unsigned int            ccnt, dcnt;
-+      struct tasklet_struct   pio_tasklet;
-+};
-diff --git a/drivers/mfd/glamo/glamo-regs.h b/drivers/mfd/glamo/glamo-regs.h
-index 151cd66..8f6c45c 100644
---- a/drivers/mfd/glamo/glamo-regs.h
-+++ b/drivers/mfd/glamo/glamo-regs.h
-@@ -150,16 +150,28 @@ enum glamo_reg_mem_dram2 {
-       GLAMO_MEM_DRAM2_DEEP_PWRDOWN    = (1 << 12),
- };
-+enum glamo_irq_index {
-+      GLAMO_IRQIDX_HOSTBUS    = 0,
-+      GLAMO_IRQIDX_JPEG       = 1,
-+      GLAMO_IRQIDX_MPEG       = 2,
-+      GLAMO_IRQIDX_MPROC1     = 3,
-+      GLAMO_IRQIDX_MPROC0     = 4,
-+      GLAMO_IRQIDX_CMDQUEUE   = 5,
-+      GLAMO_IRQIDX_2D         = 6,
-+      GLAMO_IRQIDX_MMC        = 7,
-+      GLAMO_IRQIDX_RISC       = 8,
-+};
-+
- 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,
-+      GLAMO_IRQ_HOSTBUS       = (1 << GLAMO_IRQIDX_HOSTBUS),
-+      GLAMO_IRQ_JPEG          = (1 << GLAMO_IRQIDX_JPEG),
-+      GLAMO_IRQ_MPEG          = (1 << GLAMO_IRQIDX_MPEG),
-+      GLAMO_IRQ_MPROC1        = (1 << GLAMO_IRQIDX_MPROC1),
-+      GLAMO_IRQ_MPROC0        = (1 << GLAMO_IRQIDX_MPROC0),
-+      GLAMO_IRQ_CMDQUEUE      = (1 << GLAMO_IRQIDX_CMDQUEUE),
-+      GLAMO_IRQ_2D            = (1 << GLAMO_IRQIDX_2D),
-+      GLAMO_IRQ_MMC           = (1 << GLAMO_IRQIDX_MMC),
-+      GLAMO_IRQ_RISC          = (1 << GLAMO_IRQIDX_RISC),
- };
- enum glamo_reg_clock_host {
-@@ -197,6 +209,145 @@ enum glamo_reg_clock_mmc {
-       GLAMO_CLOCK_MMC_RESET           = 0x1000,
- };
-+enum glamo_reg_basic_mmc {
-+      /* set to disable CRC error rejection */
-+      GLAMO_BASIC_MMC_DISABLE_CRC     = 0x0001,
-+      /* enable completion interrupt */
-+      GLAMO_BASIC_MMC_EN_COMPL_INT    = 0x0002,
-+      /* stop MMC clock while enforced idle waiting for data from card */
-+      GLAMO_BASIC_MMC_NO_CLK_RD_WAIT  = 0x0004,
-+      /* 0 = 1-bit bus to card, 1 = use 4-bit bus (has to be negotiated) */
-+      GLAMO_BASIC_MMC_EN_4BIT_DATA    = 0x0008,
-+      /* enable 75K pullups on D3..D0 */
-+      GLAMO_BASIC_MMC_EN_DATA_PUPS    = 0x0010,
-+      /* enable 75K pullup on CMD */
-+      GLAMO_BASIC_MMC_EN_CMD_PUP      = 0x0020,
-+      /* IO drive strength 00=weak -> 11=strongest */
-+      GLAMO_BASIC_MMC_EN_DR_STR0      = 0x0040,
-+      GLAMO_BASIC_MMC_EN_DR_STR1      = 0x0080,
-+      /* TCLK delay stage A, 0000 = 500ps --> 1111 = 8ns */
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYA0   = 0x0100,
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYA1   = 0x0200,
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYA2   = 0x0400,
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYA3   = 0x0800,
-+      /* TCLK delay stage B (cumulative), 0000 = 500ps --> 1111 = 8ns */
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYB0   = 0x1000,
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYB1   = 0x2000,
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYB2   = 0x4000,
-+      GLAMO_BASIC_MMC_EN_TCLK_DLYB3   = 0x8000,
-+};
-+
-+enum glamo_reg_stat1_mmc {
-+      /* command "counter" (really: toggle) */
-+      GLAMO_STAT1_MMC_CMD_CTR = 0x8000,
-+      /* engine is idle */
-+      GLAMO_STAT1_MMC_IDLE    = 0x4000,
-+      /* readback response is ready */
-+      GLAMO_STAT1_MMC_RB_RRDY = 0x0200,
-+      /* readback data is ready */
-+      GLAMO_STAT1_MMC_RB_DRDY = 0x0100,
-+      /* no response timeout */
-+      GLAMO_STAT1_MMC_RTOUT   = 0x0020,
-+      /* no data timeout */
-+      GLAMO_STAT1_MMC_DTOUT   = 0x0010,
-+      /* CRC error on block write */
-+      GLAMO_STAT1_MMC_BWERR   = 0x0004,
-+      /* CRC error on block read */
-+      GLAMO_STAT1_MMC_BRERR   = 0x0002
-+};
-+
-+enum glamo_reg_fire_mmc {
-+      /* command "counter" (really: toggle)
-+       * the STAT1 register reflects this so you can ensure you don't look
-+       * at status for previous command
-+       */
-+      GLAMO_FIRE_MMC_CMD_CTR  = 0x8000,
-+      /* sets kind of response expected */
-+      GLAMO_FIRE_MMC_RES_MASK = 0x0700,
-+      /* sets command type */
-+      GLAMO_FIRE_MMC_TYP_MASK = 0x00C0,
-+      /* sets command class */
-+      GLAMO_FIRE_MMC_CLS_MASK = 0x000F,
-+};
-+
-+enum glamo_fire_mmc_response_types {
-+      GLAMO_FIRE_MMC_RSPT_R1  = 0x0000,
-+      GLAMO_FIRE_MMC_RSPT_R1b = 0x0100,
-+      GLAMO_FIRE_MMC_RSPT_R2  = 0x0200,
-+      GLAMO_FIRE_MMC_RSPT_R3  = 0x0300,
-+      GLAMO_FIRE_MMC_RSPT_R4  = 0x0400,
-+      GLAMO_FIRE_MMC_RSPT_R5  = 0x0500,
-+};
-+
-+enum glamo_fire_mmc_command_types {
-+      /* broadcast, no response */
-+      GLAMO_FIRE_MMC_CMDT_BNR = 0x0000,
-+      /* broadcast, with response */
-+      GLAMO_FIRE_MMC_CMDT_BR  = 0x0040,
-+      /* addressed, no data */
-+      GLAMO_FIRE_MMC_CMDT_AND = 0x0080,
-+      /* addressed, with data */
-+      GLAMO_FIRE_MMC_CMDT_AD  = 0x00C0,
-+};
-+
-+enum glamo_fire_mmc_command_class {
-+      /* "Stream Read" */
-+      GLAMO_FIRE_MMC_CC_STRR  = 0x0000,
-+      /* Single Block Read */
-+      GLAMO_FIRE_MMC_CC_SBR   = 0x0001,
-+      /* Multiple Block Read With Stop */
-+      GLAMO_FIRE_MMC_CC_MBRS  = 0x0002,
-+      /* Multiple Block Read No Stop */
-+      GLAMO_FIRE_MMC_CC_MBRNS = 0x0003,
-+      /* RESERVED for "Stream Write" */
-+      GLAMO_FIRE_MMC_CC_STRW  = 0x0004,
-+      /* "Stream Write" */
-+      GLAMO_FIRE_MMC_CC_SBW   = 0x0005,
-+      /* RESERVED for Multiple Block Write With Stop */
-+      GLAMO_FIRE_MMC_CC_MBWS  = 0x0006,
-+      /* Multiple Block Write No Stop */
-+      GLAMO_FIRE_MMC_CC_MBWNS = 0x0007,
-+      /* STOP command */
-+      GLAMO_FIRE_MMC_CC_STOP  = 0x0008,
-+      /* Cancel on Running Command */
-+      GLAMO_FIRE_MMC_CC_CANCL = 0x0009,
-+      /* "Basic Command" */
-+      GLAMO_FIRE_MMC_CC_BASIC = 0x000a,
-+};
-+
-+/* these are offsets from the start of the MMC register region */
-+enum glamo_register_mmc {
-+      /* MMC command, b15..8 = cmd arg b7..0; b7..1 = CRC; b0 = end bit */
-+      GLAMO_REG_MMC_CMD_REG1  = 0x00,
-+      /* MMC command, b15..0 = cmd arg b23 .. 8 */
-+      GLAMO_REG_MMC_CMD_REG2  = 0x02,
-+      /* MMC command, b15=start, b14=transmission,
-+       * b13..8=cmd idx, b7..0=cmd arg b31..24
-+       */
-+      GLAMO_REG_MMC_CMD_REG3  = 0x04,
-+      GLAMO_REG_MMC_CMD_FIRE  = 0x06,
-+      GLAMO_REG_MMC_CMD_RSP1  = 0x10,
-+      GLAMO_REG_MMC_CMD_RSP2  = 0x12,
-+      GLAMO_REG_MMC_CMD_RSP3  = 0x14,
-+      GLAMO_REG_MMC_CMD_RSP4  = 0x16,
-+      GLAMO_REG_MMC_CMD_RSP5  = 0x18,
-+      GLAMO_REG_MMC_CMD_RSP6  = 0x1a,
-+      GLAMO_REG_MMC_CMD_RSP7  = 0x1c,
-+      GLAMO_REG_MMC_CMD_RSP8  = 0x1e,
-+      GLAMO_REG_MMC_RB_STAT1  = 0x20,
-+      GLAMO_REG_MMC_RB_BLKCNT = 0x22,
-+      GLAMO_REG_MMC_RB_BLKLEN = 0x24,
-+      GLAMO_REG_MMC_BASIC     = 0x30,
-+      GLAMO_REG_MMC_RDATADS1  = 0x34,
-+      GLAMO_REG_MMC_RDATADS2  = 0x36,
-+      GLAMO_REG_MMC_WDATADS1  = 0x38,
-+      GLAMO_REG_MMC_WDATADS2  = 0x3a,
-+      GLAMO_REG_MMC_DATBLKCNT = 0x3c,
-+      GLAMO_REG_MMC_DATBLKLEN = 0x3e,
-+      GLAMO_REG_MMC_TIMEOUT   = 0x40,
-+
-+};
-+
- enum glamo_reg_clock_isp {
-       GLAMO_CLOCK_ISP_DG_I1CLK        = 0x0001,
-       GLAMO_CLOCK_ISP_EN_I1CLK        = 0x0002,
--- 
-1.5.6.3
-