linux-openzaurus-2.6.18+git: Attempt to update tosa patches to 2.6.19-rc4 - untested
authorRichard Purdie <rpurdie@rpsys.net>
Tue, 7 Nov 2006 23:40:20 +0000 (23:40 +0000)
committerRichard Purdie <rpurdie@rpsys.net>
Tue, 7 Nov 2006 23:40:20 +0000 (23:40 +0000)
packages/linux/linux-openzaurus-2.6.18+git/sharpsl-pm-postresume-r1.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/tmio-nand-r7.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/tmio-ohci-r6.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/tmio-tc6393-r8.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/tosa-keyboard-r18.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/tosa-lcdnoise-r1.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/tosa-tmio-lcd-r10.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/wm9712-reset-loop-r2.patch [new file with mode: 0644]
packages/linux/linux-openzaurus-2.6.18+git/wm9712-suspend-cold-res-r2.patch [new file with mode: 0644]
packages/linux/linux-openzaurus_2.6.18+git.bb

diff --git a/packages/linux/linux-openzaurus-2.6.18+git/sharpsl-pm-postresume-r1.patch b/packages/linux/linux-openzaurus-2.6.18+git/sharpsl-pm-postresume-r1.patch
new file mode 100644 (file)
index 0000000..409daf0
--- /dev/null
@@ -0,0 +1,30 @@
+ arch/arm/common/sharpsl_pm.c          |    3 +++
+ include/asm-arm/hardware/sharpsl_pm.h |    1 +
+ 2 files changed, 4 insertions(+)
+
+Index: git/include/asm-arm/hardware/sharpsl_pm.h
+===================================================================
+--- git.orig/include/asm-arm/hardware/sharpsl_pm.h     2006-10-31 16:09:33.000000000 +0000
++++ git/include/asm-arm/hardware/sharpsl_pm.h  2006-11-07 22:08:41.000000000 +0000
+@@ -26,6 +26,7 @@ struct sharpsl_charger_machinfo {
+       void (*presuspend)(void);
+       void (*postsuspend)(void);
+       void (*earlyresume)(void);
++      void (*postresume)(void);
+       unsigned long (*read_devdata)(int);
+ #define SHARPSL_BATT_VOLT       1
+ #define SHARPSL_BATT_TEMP       2
+Index: git/arch/arm/common/sharpsl_pm.c
+===================================================================
+--- git.orig/arch/arm/common/sharpsl_pm.c      2006-11-07 22:03:48.000000000 +0000
++++ git/arch/arm/common/sharpsl_pm.c   2006-11-07 22:04:20.000000000 +0000
+@@ -584,6 +584,9 @@ static int corgi_pxa_pm_enter(suspend_st
+       if (sharpsl_pm.machinfo->earlyresume)
+               sharpsl_pm.machinfo->earlyresume();
++      if (sharpsl_pm.machinfo->postresume)
++              sharpsl_pm.machinfo->postresume();
++      
+       dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
+       return 0;
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/tmio-nand-r7.patch b/packages/linux/linux-openzaurus-2.6.18+git/tmio-nand-r7.patch
new file mode 100644 (file)
index 0000000..b6ce56e
--- /dev/null
@@ -0,0 +1,593 @@
+ drivers/mtd/nand/Kconfig  |    7 
+ drivers/mtd/nand/Makefile |    1 
+ drivers/mtd/nand/tmio.c   |  554 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 562 insertions(+)
+
+Index: git/drivers/mtd/nand/tmio.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ git/drivers/mtd/nand/tmio.c        2006-11-07 23:31:12.000000000 +0000
+@@ -0,0 +1,554 @@
++/*
++ * A device driver for NAND flash connected to a Toshiba Mobile IO
++ * controller. This is known to work with the following variants:
++ *    TC6393XB revision 3
++ *
++ * Maintainer: Chris Humbert <mahadri+mtd@drigon.com>
++ *
++ * Copyright (C) 2005 Chris Humbert
++ * Copyright (C) 2005 Dirk Opfer
++ * Copyright (C) 2004 SHARP
++ * Copyright (C) 2002 Lineo Japan, Inc.
++ * Copyright (C) Ian Molton and Sebastian Carlier
++ *
++ * Based on Sharp's NAND driver, sharp_sl_tc6393.c
++ *
++ * 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/types.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/ioport.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/nand_ecc.h>
++#include <linux/mtd/partitions.h>
++#include <asm/io.h>
++#include <asm/hardware/tmio.h>
++
++#include <linux/interrupt.h>
++
++#define mtd_printk(level, mtd, format, arg...)        \
++      printk (level "%s: " format, mtd->name, ## arg)
++#define mtd_warn(mtd, format, arg...)         \
++      mtd_printk (KERN_WARNING, mtd, format, ## arg)
++
++/*--------------------------------------------------------------------------*/
++
++/* tmio_nfcr.mode Register Command List */
++#define FCR_MODE_DATA         0x94    // Data Data_Mode
++#define FCR_MODE_COMMAND      0x95    // Data Command_Mode
++#define FCR_MODE_ADDRESS      0x96    // Data Address_Mode
++
++#define FCR_MODE_HWECC_CALC   0xB4    // HW-ECC Data
++#define FCR_MODE_HWECC_RESULT 0xD4    // HW-ECC Calculation Result Read_Mode
++#define FCR_MODE_HWECC_RESET  0xF4    // HW-ECC Reset
++
++#define FCR_MODE_POWER_ON     0x0C    // Power Supply ON  to SSFDC card
++#define FCR_MODE_POWER_OFF    0x08    // Power Supply OFF to SSFDC card
++
++#define FCR_MODE_LED_OFF      0x00    // LED OFF
++#define FCR_MODE_LED_ON               0x04    // LED ON
++
++#define FCR_MODE_EJECT_ON     0x68    // Ejection Demand from Penguin is Advanced
++#define FCR_MODE_EJECT_OFF    0x08    // Ejection Demand from Penguin is Not Advanced
++
++#define FCR_MODE_LOCK         0x6C    // Operates By Lock_Mode. Ejection Switch is Invalid
++#define FCR_MODE_UNLOCK               0x0C    // Operates By UnLock_Mode.Ejection Switch is Effective
++
++#define FCR_MODE_CONTROLLER_ID        0x40    // Controller ID Read
++#define FCR_MODE_STANDBY      0x00    // SSFDC card Changes Standby State
++
++#define FCR_MODE_WE           0x80
++#define FCR_MODE_ECC1         0x40
++#define FCR_MODE_ECC0         0x20
++#define FCR_MODE_CE           0x10
++#define FCR_MODE_PCNT1                0x08
++#define FCR_MODE_PCNT0                0x04
++#define FCR_MODE_ALE          0x02
++#define FCR_MODE_CLE          0x01
++
++#define FCR_STATUS_BUSY               0x80
++
++/*
++ * NAND Flash Host Controller Configuration Register
++ */
++struct tmio_nfhccr {
++      u8 x00[4];
++      u16     command;        /* 0x04 Command                         */
++      u8 x01[0x0a];
++      u16     base[2];        /* 0x10 NAND Flash Control Reg Base Addr*/
++      u8 x02[0x29];
++      u8      intp;           /* 0x3d Interrupt Pin                   */
++      u8 x03[0x0a];
++      u8      inte;           /* 0x48 Interrupt Enable                */
++      u8 x04;
++      u8      ec;             /* 0x4a Event Control                   */
++      u8 x05;
++      u8      icc;            /* 0x4c Internal Clock Control          */
++      u8 x06[0x0e];
++      u8      eccc;           /* 0x5b ECC Control                     */
++      u8 x07[4];
++      u8      nftc;           /* 0x60 NAND Flash Transaction Control  */
++      u8      nfm;            /* 0x61 NAND Flash Monitor              */
++      u8      nfpsc;          /* 0x62 NAND Flash Power Supply Control */
++      u8      nfdc;           /* 0x63 NAND Flash Detect Control       */
++      u8 x08[0x9c];
++} __attribute__ ((packed));
++
++/*
++ * NAND Flash Control Register
++ */
++struct tmio_nfcr {
++union {
++      u8      u8;             /* 0x00 Data Register                   */
++      u16     u16;
++      u32     u32;
++} __attribute__ ((packed));
++      u8      mode;           /* 0x04 Mode Register                   */
++      u8      status;         /* 0x05 Status Register                 */
++      u8      isr;            /* 0x06 Interrupt Status Register       */
++      u8      imr;            /* 0x07 Interrupt Mask Register         */
++} __attribute__ ((packed));
++
++struct tmio_nand {
++      struct mtd_info                 mtd;
++      struct nand_chip                chip;
++
++      struct tmio_nfhccr __iomem *    ccr;
++      struct tmio_nfcr __iomem *      fcr;
++
++      unsigned int                    irq;
++
++      /* for tmio_nand_read_byte */
++      u8                              read;
++      unsigned                        read_good:1;
++};
++
++#define mtd_to_tmio(m)                        container_of(m, struct tmio_nand, mtd)
++
++/*--------------------------------------------------------------------------*/
++
++static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
++                                 unsigned int ctrl)
++{
++      struct tmio_nand *tmio = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *fcr = tmio->fcr;
++      struct nand_chip *chip = mtd->priv;
++
++      if (ctrl & NAND_CTRL_CHANGE) {
++              u8 mode;
++
++              if (ctrl & NAND_NCE) {
++                      mode = FCR_MODE_DATA;
++
++                      if (ctrl & NAND_CLE)
++                              mode |=  FCR_MODE_CLE;
++                      else
++                              mode &= ~FCR_MODE_CLE;
++
++                      if (ctrl & NAND_ALE)
++                              mode |=  FCR_MODE_ALE;
++                      else
++                              mode &= ~FCR_MODE_ALE;
++              } else {
++                      mode = FCR_MODE_STANDBY;
++              }
++
++              iowrite8 (mode, &fcr->mode);
++              tmio->read_good = 0;
++      }
++
++      if (cmd != NAND_CMD_NONE)
++              writeb(cmd, chip->IO_ADDR_W);
++}
++
++static int tmio_nand_dev_ready (struct mtd_info* mtd)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++
++      return !(ioread8 (&fcr->status) & FCR_STATUS_BUSY);
++}
++
++static irqreturn_t tmio_irq (int irq, void *__tmio)
++{
++      struct tmio_nand*               tmio    = __tmio;
++      struct nand_chip*               this    = &tmio->chip;
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++
++      /* disable RDYREQ interrupt */
++      iowrite8 (0x00, &fcr->imr);
++
++      if (unlikely (!waitqueue_active (&this->controller->wq)))
++              printk (KERN_WARNING TMIO_NAME_NAND ": spurious interrupt\n");
++
++      wake_up (&this->controller->wq);
++      return IRQ_HANDLED;
++}
++
++/*
++ * The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
++ * This interrupt is normally disabled, but for long operations like
++ * erase and write, we enable it to wake us up.  The irq handler
++ * disables the interrupt.
++ */
++static int
++tmio_nand_wait (struct mtd_info *mtd, struct nand_chip *this)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++      long                            timeout;
++
++      /* enable RDYREQ interrupt */
++      iowrite8 (0x0f, &fcr->isr);
++      iowrite8 (0x81, &fcr->imr);
++
++      timeout = wait_event_timeout (this->controller->wq, tmio_nand_dev_ready (mtd),
++                      msecs_to_jiffies (this->state == FL_ERASING ? 400 : 20));
++
++      if (unlikely (!tmio_nand_dev_ready (mtd))) {
++              iowrite8 (0x00, &fcr->imr);
++              mtd_warn (mtd, "still busy with %s after %d ms\n",
++                              this->state == FL_ERASING ? "erase" : "program",
++                              this->state == FL_ERASING ? 400 : 20);
++
++      } else if (unlikely (!timeout)) {
++              iowrite8 (0x00, &fcr->imr);
++              mtd_warn (mtd, "timeout waiting for interrupt\n");
++      }
++
++      this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
++      return this->read_byte (mtd);
++}
++
++/*
++ * The TMIO controller combines two 8-bit data bytes into one 16-bit
++ * word. This function separates them so nand_base.c works as expected,
++ * especially its NAND_CMD_READID routines.
++ *
++ * To prevent stale data from being read, tmio_nand_hwcontrol() clears
++ * tmio->read_good.
++ */
++static u_char tmio_nand_read_byte (struct mtd_info *mtd)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++      unsigned int                    data;
++
++      if (tmio->read_good--)
++              return tmio->read;
++
++      data            = ioread16 (&fcr->u16);
++      tmio->read      = data >> 8;
++      return data;
++}
++
++/*
++ * The TMIO controller converts an 8-bit NAND interface to a 16-bit
++ * bus interface, so all data reads and writes must be 16-bit wide.
++ * Thus, we implement 16-bit versions of the read, write, and verify
++ * buffer functions.
++ */
++static void
++tmio_nand_write_buf (struct mtd_info *mtd, const u_char *buf, int len)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++
++      iowrite16_rep (&fcr->u16, buf, len >> 1);
++}
++
++static void tmio_nand_read_buf (struct mtd_info *mtd, u_char *buf, int len)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++
++      ioread16_rep (&fcr->u16, buf, len >> 1);
++}
++
++static int
++tmio_nand_verify_buf (struct mtd_info *mtd, const u_char *buf, int len)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++      u16*                            p       = (u16*) buf;
++
++      for (len >>= 1; len; len--)
++              if (*(p++) != ioread16 (&fcr->u16))
++                      return -EFAULT;
++      return 0;
++}
++
++static void tmio_nand_enable_hwecc (struct mtd_info* mtd, int mode)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++
++      iowrite8 (FCR_MODE_HWECC_RESET, &fcr->mode);
++      ioread8 (&fcr->u8);     /* dummy read */
++      iowrite8 (FCR_MODE_HWECC_CALC, &fcr->mode);
++}
++
++static int tmio_nand_calculate_ecc (struct mtd_info* mtd, const u_char* dat,
++                                                      u_char* ecc_code)
++{
++      struct tmio_nand*               tmio    = mtd_to_tmio (mtd);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++      unsigned int                    ecc;
++
++      iowrite8 (FCR_MODE_HWECC_RESULT, &fcr->mode);
++
++      ecc = ioread16 (&fcr->u16);
++      ecc_code[1] = ecc;      // 000-255 LP7-0
++      ecc_code[0] = ecc >> 8; // 000-255 LP15-8
++      ecc = ioread16 (&fcr->u16);
++      ecc_code[2] = ecc;      // 000-255 CP5-0,11b
++      ecc_code[4] = ecc >> 8; // 256-511 LP7-0
++      ecc = ioread16 (&fcr->u16);
++      ecc_code[3] = ecc;      // 256-511 LP15-8
++      ecc_code[5] = ecc >> 8; // 256-511 CP5-0,11b
++
++      iowrite8 (FCR_MODE_DATA, &fcr->mode);
++      return 0;
++}
++
++static void tmio_hw_init (struct device *dev, struct tmio_nand *tmio)
++{
++      struct resource*                nfcr    = tmio_resource_control (dev);
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      struct tmio_nfhccr __iomem *    ccr     = tmio->ccr;
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++      unsigned long                   base;
++
++      /* (89h) SMD Buffer ON By TC6393XB SystemConfig gpibfc1 */
++      tdev->ops->clock (dev, 1);
++      tdev->ops->function (dev, 1);
++
++      /* (4Ch) CLKRUN Enable    1st spcrunc */
++      iowrite8 (0x81,                 &ccr->icc);
++
++      /* (10h)BaseAddress    0x1000 spba.spba2 */
++      base = nfcr->start - tdev->iomem->start;
++      iowrite16 (base,                ccr->base + 0);
++      iowrite16 (base >> 16,          ccr->base + 1);
++
++      /* (04h)Command Register I/O spcmd */
++      iowrite8 (0x02,                 &ccr->command);
++
++      /* (62h) Power Supply Control ssmpwc */
++      /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
++      iowrite8 (0x02,                 &ccr->nfpsc);
++
++      /* (63h) Detect Control ssmdtc */
++      iowrite8 (0x02,                 &ccr->nfdc);
++
++      /* Interrupt status register clear sintst */
++      iowrite8 (0x0f,                 &fcr->isr);
++
++      /* After power supply, Media are reset smode */
++      iowrite8 (FCR_MODE_POWER_ON,    &fcr->mode);
++      iowrite8 (FCR_MODE_COMMAND,     &fcr->mode);
++      iowrite8 (NAND_CMD_RESET,       &fcr->u8);
++
++      /* Standby Mode smode */
++      iowrite8 (FCR_MODE_STANDBY,     &fcr->mode);
++
++      mdelay (5);
++}
++
++static void tmio_hw_stop (struct device *dev, struct tmio_nand *tmio)
++{
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      struct tmio_nfcr __iomem *      fcr     = tmio->fcr;
++
++      iowrite8 (FCR_MODE_POWER_OFF,   &fcr->mode);
++      tdev->ops->function (dev, 0);
++      tdev->ops->clock (dev, 0);
++}
++
++/*--------------------------------------------------------------------------*/
++
++#ifdef CONFIG_MTD_PARTITIONS
++static const char *part_probes[] = { "cmdlinepart", NULL };
++#endif
++
++static int tmio_probe (struct device *dev)
++{
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      struct tmio_nand_platform_data* tnpd    = dev->platform_data;
++      struct resource*                ccr     = tmio_resource_config (dev);
++      struct resource*                fcr     = tmio_resource_control (dev);
++      struct resource*                irq     = tmio_resource_irq (dev);
++      struct tmio_nand*               tmio;
++      struct mtd_info*                mtd;
++      struct nand_chip*               this;
++      struct mtd_partition*           parts;
++      int                             nbparts = 0;
++      int                             retval;
++
++      if (!tnpd)
++              return -EINVAL;
++
++      retval = request_resource (tdev->iomem, ccr);
++      if (retval)
++              goto err_request_ccr;
++
++      retval = request_resource (tdev->iomem, fcr);
++      if (retval)
++              goto err_request_fcr;
++
++      tmio = kzalloc (sizeof *tmio, GFP_KERNEL);
++      if (!tmio) {
++              retval = -ENOMEM;
++              goto err_kzalloc;
++      }
++
++      dev_set_drvdata (dev, tmio);
++      mtd             = &tmio->mtd;
++      this            = &tmio->chip;
++      mtd->priv       = this;
++      mtd->name       = TMIO_NAME_NAND;
++
++      tmio->ccr = ioremap (ccr->start, ccr->end - ccr->start + 1);
++      if (!tmio->ccr) {
++              retval = -EIO;
++              goto err_iomap_ccr;
++      }
++
++      tmio->fcr = ioremap (fcr->start, fcr->end - fcr->start + 1);
++      if (!tmio->fcr) {
++              retval = -EIO;
++              goto err_iomap_fcr;
++      }
++
++      tmio_hw_init (dev, tmio);
++
++      /* Set address of NAND IO lines */
++      this->IO_ADDR_R         = tmio->fcr;
++      this->IO_ADDR_W         = tmio->fcr;
++
++      /* Set address of hardware control function */
++      this->cmd_ctrl          = tmio_nand_hwcontrol;
++      this->dev_ready         = tmio_nand_dev_ready;
++      this->read_byte         = tmio_nand_read_byte;
++      this->write_buf         = tmio_nand_write_buf;
++      this->read_buf          = tmio_nand_read_buf;
++      this->verify_buf        = tmio_nand_verify_buf;
++
++      /* set eccmode using hardware ECC */
++      this->ecc.mode          = NAND_ECC_HW;
++      this->ecc.size          = 512;
++      this->ecc.bytes         = 6;
++      this->ecc.hwctl         = tmio_nand_enable_hwecc;
++      this->ecc.calculate     = tmio_nand_calculate_ecc;
++      this->ecc.correct       = nand_correct_data;
++      this->badblock_pattern  = tnpd->badblock_pattern;
++
++      /* 15 us command delay time */
++      this->chip_delay        = 15;
++
++      if (irq->start) {
++              retval = request_irq (irq->start, &tmio_irq,
++                                      SA_INTERRUPT, irq->name, tmio);
++              if (!retval) {
++                      tmio->irq       = irq->start;
++                      this->waitfunc  = tmio_nand_wait;
++              } else
++                      mtd_warn (mtd, "request_irq error %d\n", retval);
++      }
++
++      /* Scan to find existence of the device */
++      if (nand_scan (mtd, 1)) {
++              retval = -ENODEV;
++              goto err_scan;
++      }
++
++      /* Register the partitions */
++#ifdef CONFIG_MTD_PARTITIONS
++      nbparts = parse_mtd_partitions (mtd, part_probes, &parts, 0);
++#endif
++      if (nbparts <= 0) {
++              parts   = tnpd->partition;
++              nbparts = tnpd->num_partitions;
++      }
++
++      add_mtd_partitions (mtd, parts, nbparts);
++      return 0;
++
++err_scan:
++      if (tmio->irq)
++              free_irq (tmio->irq, tmio);
++      tmio_hw_stop (dev, tmio);
++      iounmap (tmio->fcr);
++err_iomap_fcr:
++      iounmap (tmio->ccr);
++err_iomap_ccr:
++      kfree (tmio);
++err_kzalloc:
++      release_resource (fcr);
++err_request_fcr:
++      release_resource (ccr);
++err_request_ccr:
++      return retval;
++}
++
++static int tmio_remove (struct device *dev)
++{
++      struct tmio_nand*               tmio    = dev_get_drvdata (dev);
++
++      nand_release (&tmio->mtd);
++      if (tmio->irq)
++              free_irq (tmio->irq, tmio);
++      tmio_hw_stop (dev, tmio);
++      iounmap (tmio->fcr);
++      iounmap (tmio->ccr);
++      kfree (tmio);
++      release_resource (tmio_resource_control (dev));
++      release_resource (tmio_resource_config (dev));
++      return 0;
++}
++
++#ifdef CONFIG_PM
++static int tmio_suspend (struct device *dev, pm_message_t state)
++{
++      tmio_hw_stop (dev, dev_get_drvdata (dev));
++      return 0;
++}
++
++static int tmio_resume (struct device *dev)
++{
++      tmio_hw_init (dev, dev_get_drvdata (dev));
++      return 0;
++}
++#endif
++
++static struct device_driver tmio_driver = {
++      .name           = TMIO_NAME_NAND,
++      .bus            = &tmio_bus_type,
++      .probe          = tmio_probe,
++      .remove         = tmio_remove,
++#ifdef CONFIG_PM
++      .suspend        = tmio_suspend,
++      .resume         = tmio_resume,
++#endif
++};
++
++static int __init tmio_init (void) {
++      return driver_register (&tmio_driver);
++}
++
++static void __exit tmio_exit (void) {
++      driver_unregister (&tmio_driver);
++}
++
++module_init (tmio_init);
++module_exit (tmio_exit);
++
++MODULE_LICENSE ("GPL");
++MODULE_AUTHOR ("Dirk Opfer, Chris Humbert");
++MODULE_DESCRIPTION ("NAND flash driver on Toshiba Mobile IO controller");
+Index: git/drivers/mtd/nand/Kconfig
+===================================================================
+--- git.orig/drivers/mtd/nand/Kconfig  2006-10-31 16:09:03.000000000 +0000
++++ git/drivers/mtd/nand/Kconfig       2006-11-07 22:13:09.000000000 +0000
+@@ -63,6 +63,13 @@ config MTD_NAND_AMS_DELTA
+       help
+         Support for NAND flash on Amstrad E3 (Delta).
++config MTD_NAND_TMIO
++      tristate "NAND Flash device on Toshiba Mobile IO Controller"
++      depends on MTD_NAND && TOSHIBA_TC6393XB
++      help
++        Support for NAND flash connected to a Toshiba Mobile IO
++        Controller in some PDAs, including the Sharp SL6000x.
++
+ config MTD_NAND_TOTO
+       tristate "NAND Flash device on TOTO board"
+       depends on ARCH_OMAP && MTD_NAND && BROKEN
+Index: git/drivers/mtd/nand/Makefile
+===================================================================
+--- git.orig/drivers/mtd/nand/Makefile 2006-10-31 16:09:03.000000000 +0000
++++ git/drivers/mtd/nand/Makefile      2006-11-07 22:13:09.000000000 +0000
+@@ -22,5 +22,6 @@ obj-$(CONFIG_MTD_NAND_TS7250)                += ts7250
+ obj-$(CONFIG_MTD_NAND_NANDSIM)                += nandsim.o
+ obj-$(CONFIG_MTD_NAND_CS553X)         += cs553x_nand.o
+ obj-$(CONFIG_MTD_NAND_NDFC)           += ndfc.o
++obj-$(CONFIG_MTD_NAND_TMIO)           += tmio.o
+ nand-objs = nand_base.o nand_bbt.o
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/tmio-ohci-r6.patch b/packages/linux/linux-openzaurus-2.6.18+git/tmio-ohci-r6.patch
new file mode 100644 (file)
index 0000000..9fdd296
--- /dev/null
@@ -0,0 +1,929 @@
+
+ drivers/usb/host/Kconfig     |    1 
+ drivers/usb/host/ohci-hcd.c  |    1 
+ drivers/usb/host/ohci-tmio.c |  894 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 896 insertions(+)
+
+Index: git/drivers/usb/host/ohci-tmio.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ git/drivers/usb/host/ohci-tmio.c   2006-11-07 21:48:33.000000000 +0000
+@@ -0,0 +1,894 @@
++/*
++ * OHCI HCD (Host Controller Driver) for USB.
++ *
++ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
++ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
++ * (C) Copyright 2002 Hewlett-Packard Company
++ *
++ * Bus glue for Toshiba Mobile IO (TMIO) Controller's OHCI core
++ * (C) Copyright 2005 Chris Humbert <mahadri-usb@drigon.com>
++ *
++ * This is known to work with the following variants:
++ *    TC6393XB revision 3     (32kB SRAM)
++ *
++ * The TMIO's OHCI core DMAs through a small internal buffer that
++ * is directly addressable by the CPU.  dma_declare_coherent_memory
++ * and DMA bounce buffers allow the higher-level OHCI host driver to
++ * work.  However, the dma API doesn't handle dma mapping failures
++ * well (dma_sg_map() is a prime example), so it is unusable.
++ *
++ * This HC pretends be a PIO-ish controller and uses the kernel's
++ * generic allocator for the entire SRAM.  Using the USB core's
++ * usb_operations, we provide hcd_buffer_alloc/free.  Using the OHCI's
++ * ohci_ops, we provide memory management for OHCI's TDs and EDs.  We
++ * internally queue a URB's TDs until enough dma memory is available
++ * to enqueue them with the HC.
++ *
++ * Written from sparse documentation from Toshiba and Sharp's driver
++ * for the 2.4 kernel,
++ *    usb-ohci-tc6393.c (C) Copyright 2004 Lineo Solutions, Inc.
++ *
++ * 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/fs.h>
++#include <linux/mount.h>
++#include <linux/pagemap.h>
++#include <linux/init.h>
++#include <linux/namei.h>
++#include <linux/sched.h>
++
++#include <linux/genalloc.h>
++#include <asm/dma-mapping.h>          /* for consistent_sync()        */
++#include <asm/hardware/tmio.h>
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * USB Host Controller Configuration Register
++ */
++struct tmio_uhccr {
++      u8 x00[8];
++      u8      revid;  /* 0x08 Revision ID                             */
++      u8 x01[7];
++      u16     basel;  /* 0x10 USB Control Register Base Address Low   */
++      u16     baseh;  /* 0x12 USB Control Register Base Address High  */
++      u8 x02[0x2c];
++      u8      ilme;   /* 0x40 Internal Local Memory Enable            */
++      u8 x03[0x0b];
++      u16     pm;     /* 0x4c Power Management                        */
++      u8 x04[2];
++      u8      intc;   /* 0x50 INT Control                             */
++      u8 x05[3];
++      u16     lmw1l;  /* 0x54 Local Memory Window 1 LMADRS Low        */
++      u16     lmw1h;  /* 0x56 Local Memory Window 1 LMADRS High       */
++      u16     lmw1bl; /* 0x58 Local Memory Window 1 Base Address Low  */
++      u16     lmw1bh; /* 0x5A Local Memory Window 1 Base Address High */
++      u16     lmw2l;  /* 0x5C Local Memory Window 2 LMADRS Low        */
++      u16     lmw2h;  /* 0x5E Local Memory Window 2 LMADRS High       */
++      u16     lmw2bl; /* 0x60 Local Memory Window 2 Base Address Low  */
++      u16     lmw2bh; /* 0x62 Local Memory Window 2 Base Address High */
++      u8 x06[0x98];
++      u8      misc;   /* 0xFC MISC                                    */
++      u8 x07[3];
++} __attribute__ ((packed));
++
++union tmio_uhccr_pm {
++      u16             raw;
++struct {
++      unsigned        gcken:1;        /* D0 */
++      unsigned        ckrnen:1;       /* D1 */
++      unsigned        uspw1:1;        /* D2 USB Port 1 Power Disable  */
++      unsigned        uspw2:1;        /* D3 USB Port 2 Power Disable  */
++      unsigned        x00:4;
++      unsigned        pmee:1;         /* D8 */
++      unsigned        x01:6;
++      unsigned        pmes:1;         /* D15 */
++} __attribute__ ((packed));
++} __attribute__ ((packed));
++
++/*-------------------------------------------------------------------------*/
++
++struct tmio_dma_pool {
++      struct device*          dev;
++      unsigned int            size;
++};
++
++struct tmio_hcd {
++      struct gen_pool*        poolp;
++      struct usb_operations   ops;
++      struct tmio_dma_pool    td_pool;
++      struct tmio_dma_pool    ed_pool;
++
++      struct tmio_uhccr __iomem *ccr;
++      void __iomem *          sram;
++      size_t                  sram_len;
++};
++
++#define hcd_to_tmio(hcd)      ((struct tmio_hcd*)(hcd_to_ohci (hcd) + 1))
++
++struct tmio_td {
++      void*           data;           /* td's data buffer             */
++      void __iomem *  bounce;         /* dma bounce buffer            */
++      dma_addr_t      dma;            /* bounce buffer dma address    */
++      size_t          len;            /* bounce buffer length         */
++      u32             info;           /* parameter for td_fill        */
++};
++
++struct tmio_urb {
++      int             td_add;         /* next index to be added       */
++      int             td_queue;       /* next index to be HC enqueued */
++
++      struct tmio_td  td [0];         /* private td data              */
++};
++
++static inline struct tmio_urb *urb_to_turb (struct urb *urb)
++{
++      urb_priv_t* urb_priv = urb->hcpriv;
++      return (struct tmio_urb*)(urb_priv->td + urb_priv->length);
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* gen_pool_alloc page allocator callback */
++static unsigned long tmio_pool_callback(struct gen_pool *poolp)
++{
++      return 0;
++}
++
++static inline void tmio_pool_destroy(struct tmio_hcd *tmio)
++{
++      struct gen_pool *poolp = tmio->poolp;
++
++      if (!poolp)
++              return;
++      if (poolp->h)
++              kfree(poolp->h);
++      kfree(poolp);
++      tmio->poolp = NULL;
++}
++
++/*-------------------------------------------------------------------------*/
++
++#define BOUNDED_XYL(x,y,ylen) (((y) <= (x)) && ((x) < ((y)+(ylen))))
++#define BOUNDED_XYY(x,y1,y2)  (((y1) <= (x)) && ((x) < (y2)))
++
++static inline dma_addr_t tmio_virt_to_dma (struct usb_hcd *hcd, void *vaddr)
++{
++      struct resource* sram   = tmio_resource_mem (hcd->self.controller);
++      struct tmio_hcd* tmio   = hcd_to_tmio (hcd);
++
++      return BOUNDED_XYL (vaddr, tmio->sram, tmio->sram_len)
++                      ? sram->start + (vaddr - tmio->sram)
++                      : ~0;
++}
++
++static inline void* tmio_dma_to_virt (struct usb_hcd *hcd, dma_addr_t handle)
++{
++      struct resource* sram   = tmio_resource_mem (hcd->self.controller);
++      struct tmio_hcd* tmio   = hcd_to_tmio (hcd);
++
++      return BOUNDED_XYY (handle, sram->start, sram->end + 1)
++                      ? tmio->sram + handle - sram->start
++                      : NULL;
++}
++
++/*
++ * allocate dma-able memory in the device's internal sram
++ *
++ * The generic pool allocator's minimum chunk size is 32 bytes,
++ * which is the cache line size on the PXA255, so we don't need
++ * to do anything special for smaller requests.
++ */
++static inline void *tmio_dma_alloc (struct device *dev, size_t size,
++                              dma_addr_t *handle, gfp_t mem_flags)
++{
++      struct usb_hcd*  hcd    = dev_get_drvdata (dev);
++      struct tmio_hcd* tmio   = hcd_to_tmio (hcd);
++      void*            virt   = (void*) gen_pool_alloc (tmio->poolp, size);
++
++      return (*handle = tmio_virt_to_dma (hcd, virt)) == ~0 ? NULL : virt;
++}
++
++static inline void tmio_dma_free (struct device *dev, size_t size,
++                                      void *cpu_addr, dma_addr_t handle)
++{
++      struct usb_hcd*         hcd     = dev_get_drvdata (dev);
++      struct tmio_hcd*        tmio    = hcd_to_tmio (hcd);
++      dma_addr_t              dma     = tmio_virt_to_dma (hcd, cpu_addr);
++
++      if (unlikely (dma == ~0)) {
++              dev_err (dev, "trying to free bad address 0x%p\n", cpu_addr);
++              return;
++      }
++
++      if (unlikely (handle != dma))
++              dev_err (dev, "dma address mismatch for 0x%p: %08x != %08x\n",
++                              cpu_addr, handle, dma);
++
++      gen_pool_free (tmio->poolp, (unsigned long) cpu_addr, size);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static void *tmio_dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
++                                                      dma_addr_t *handle)
++{
++      struct tmio_dma_pool *tdp = (struct tmio_dma_pool*) pool;
++      return tmio_dma_alloc (tdp->dev, tdp->size, handle, mem_flags);
++}
++
++static void
++tmio_dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t addr)
++{
++      struct tmio_dma_pool *tdp = (struct tmio_dma_pool*) pool;
++      return tmio_dma_free (tdp->dev, tdp->size, vaddr, addr);
++}
++
++static void *tmio_buffer_alloc (struct usb_bus *bus, size_t size,
++                              gfp_t mem_flags, dma_addr_t *dma)
++{
++      return tmio_dma_alloc (bus->controller, size, dma, mem_flags);
++}
++
++static void tmio_buffer_free (struct usb_bus *bus, size_t size,
++                              void *addr, dma_addr_t dma)
++{
++      tmio_dma_free (bus->controller, size, addr, dma);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static void tmio_hc_stop (struct usb_hcd *hcd)
++{
++      struct device*                  dev     = hcd->self.controller;
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      struct tmio_hcd*                tmio    = hcd_to_tmio (hcd);
++      struct tmio_uhccr __iomem*      ccr     = tmio->ccr;
++      union tmio_uhccr_pm             pm      = {0};
++
++      pm.gcken        = 1;
++      pm.ckrnen       = 1;
++      pm.uspw1        = 1;
++      pm.uspw2        = 1;
++
++      iowrite8 (0,            &ccr->intc);
++      iowrite8 (0,            &ccr->ilme);
++      iowrite16(0,            &ccr->basel);
++      iowrite16(0,            &ccr->baseh);
++      iowrite16(pm.raw,       &ccr->pm);
++
++      tdev->ops->function (dev, 0);
++      tdev->ops->clock (dev, 0);
++}
++
++static void tmio_hc_start (struct usb_hcd *hcd)
++{
++      struct device*                  dev     = hcd->self.controller;
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      struct tmio_hcd*                tmio    = hcd_to_tmio (hcd);
++      struct tmio_uhccr __iomem*      ccr     = tmio->ccr;
++      union tmio_uhccr_pm             pm      = {0};
++
++      pm.pmes         = 1;
++      pm.pmee         = 1;
++      pm.ckrnen       = 1;
++      pm.gcken        = 1;
++
++      tdev->ops->clock (dev, 1);
++      tdev->ops->function (dev, 1);
++
++      iowrite16(pm.raw,                       &ccr->pm);
++      iowrite16(hcd->rsrc_start,              &ccr->basel);
++      iowrite16(hcd->rsrc_start >> 16,        &ccr->baseh);
++      iowrite8 (1,                            &ccr->ilme);
++      iowrite8 (2,                            &ccr->intc);
++
++      consistent_sync (tmio->sram, tmio->sram_len, DMA_BIDIRECTIONAL);
++
++      dev_info (dev, "revision %d @ 0x%08llx, irq %d\n",
++                      ioread8 (&ccr->revid), hcd->rsrc_start, hcd->irq);
++}
++
++static void tmio_stop (struct usb_hcd *hcd)
++{
++      struct ohci_hcd*        ohci    = hcd_to_ohci (hcd);
++
++      /* NULL these so ohci_stop() doesn't try to free them */
++      ohci->hcca      = NULL;
++      ohci->td_cache  = NULL;
++      ohci->ed_cache  = NULL;
++
++      ohci_stop (hcd);
++      tmio_hc_stop (hcd);
++      tmio_pool_destroy (hcd_to_tmio (hcd));
++
++      /* We don't free the hcca because tmio_hc_stop() turns off
++       * the sram and the memory allocation data is destroyed. */
++}
++
++static int tmio_start (struct usb_hcd *hcd)
++{
++      struct device*          dev     = hcd->self.controller;
++      struct ohci_hcd*        ohci    = hcd_to_ohci (hcd);
++      struct tmio_hcd*        tmio    = hcd_to_tmio (hcd);
++      int                     retval;
++
++      tmio_hc_start (hcd);
++
++      tmio->poolp = gen_pool_create(0, fls(tmio->sram_len) - 1,
++                                              tmio_pool_callback, 0);
++      if (!tmio->poolp) {
++              retval = -ENOMEM;
++              goto err_gen_pool_create;
++      }
++
++      gen_pool_free (tmio->poolp, (unsigned long)(tmio->sram),
++                                                      tmio->sram_len);
++
++      ohci->hcca = tmio_dma_alloc (dev, sizeof *ohci->hcca,
++                                      &ohci->hcca_dma, GFP_KERNEL);
++      if (!ohci->hcca) {
++              retval = -ENOMEM;
++              goto err_hcca_alloc;
++      }
++
++      /* for our dma_pool_alloc/free hooks */
++      ohci->td_cache = (struct dma_pool*) &tmio->td_pool;
++      ohci->ed_cache = (struct dma_pool*) &tmio->ed_pool;
++
++      if ((retval = ohci_init (ohci)) < 0)
++              goto err_ohci_init;
++
++      if ((retval = ohci_run (ohci)) < 0)
++              goto err_ohci_run;
++
++      return 0;
++
++err_ohci_run:
++      err ("can't start %s", hcd->self.bus_name);
++err_ohci_init:
++err_hcca_alloc:
++err_gen_pool_create:
++      tmio_stop (hcd);
++      return retval;
++}
++
++/*-------------------------------------------------------------------------*/
++
++static inline void *tmio_urb_dma_to_virt(struct urb *urb, dma_addr_t dma)
++{
++      if (BOUNDED_XYL(dma, urb->transfer_dma, urb->transfer_buffer_length))
++              return urb->transfer_buffer     + dma - urb->transfer_dma;
++
++      if (BOUNDED_XYL(dma, urb->setup_dma, sizeof (struct usb_ctrlrequest)))
++              return urb->setup_packet        + dma - urb->setup_dma;
++
++      return NULL;
++}
++
++static struct tmio_td* tmio_td_find (struct td *td, int *index)
++{
++      struct urb*             urb             = td->urb;
++      urb_priv_t*             urb_priv        = urb->hcpriv;
++      struct tmio_urb*        turb            = urb_to_turb (urb);
++      int                     i;
++
++      for (i=0; i < urb_priv->length; i++)
++              if (urb_priv->td[i] == td) {
++                      *index = i;
++                      return turb->td + i;
++              }
++
++      return NULL;
++}
++
++/*
++ * map the td's data to dma-able memory
++ *
++ * if this td transfers data,
++ *    sets tmtd->data         to the urb's data buffer
++ *    sets tmtd->dma          to dma-able memory
++ *    sets tmtd->bounce       to non-NULL if a bounce buffer is allocated
++ *    copies the urb's data buffer to the bounce buffer if necessary
++ */
++static int tmio_td_dma_map (struct ohci_hcd *ohci, struct urb *urb,
++                              struct tmio_td *tmtd, int idx)
++{
++      struct usb_hcd*         hcd     = ohci_to_hcd (ohci);
++      struct device*          dev     = hcd->self.controller;
++      dma_addr_t              dma;
++
++      if (!tmtd->len)
++              return 0;
++
++      if (tmio_dma_to_virt (hcd, tmtd->dma))
++              return 0;
++
++      tmtd->data = tmio_urb_dma_to_virt (urb, tmtd->dma);
++      if (unlikely (!tmtd->data)) {
++              dev_err (dev, "TD has bad dma address 0x%08x\n", tmtd->dma);
++              return 0;
++      }
++
++      tmtd->bounce = tmio_dma_alloc (dev, tmtd->len, &dma, GFP_ATOMIC);
++      if (!tmtd->bounce)
++              return -ENOMEM;
++
++      if ((usb_pipecontrol (urb->pipe) && !idx) || usb_pipeout (urb->pipe)) {
++              consistent_sync (tmtd->bounce, tmtd->len, DMA_TO_DEVICE);
++              memcpy (tmtd->bounce, tmtd->data, tmtd->len);
++      } else
++              consistent_sync (tmtd->bounce, tmtd->len, DMA_FROM_DEVICE);
++
++      tmtd->dma = dma;
++      return 0;
++}
++
++/*
++ * unmaps the td's data from dma-able memory
++ *
++ * if a bounce buffer has been allocated,
++ *    copy the bounce buffer to the urb's data buffer if necessary
++ *    free the bounce buffer
++ */
++static void tmio_td_dma_unmap (struct ohci_hcd *ohci, struct td *td)
++{
++      struct device*  dev     = (ohci_to_hcd (ohci))->self.controller;
++      struct urb*     urb     = td->urb;
++      int             idx;
++      struct tmio_td* tmtd    = tmio_td_find (td, &idx);
++
++      if (!tmtd->bounce)
++              return;
++
++      if (usb_pipein (urb->pipe) && (usb_pipecontrol (urb->pipe) ? idx : 1)) {
++              memcpy (tmtd->data, tmtd->bounce, tmtd->len);
++              consistent_sync (tmtd->data, tmtd->len, DMA_TO_DEVICE);
++      }
++
++      tmio_dma_free (dev, tmtd->len, tmtd->bounce, tmtd->dma);
++}
++
++static int tmio_urb_runqueue (struct ohci_hcd *ohci, struct urb *urb)
++{
++      struct tmio_urb*        turb    = urb_to_turb (urb);
++      urb_priv_t*             urb_priv= urb->hcpriv;
++      int                     start   = turb->td_queue;
++      int                     retval  = 0;
++      int                     i;
++
++      for (i = start; i < turb->td_add; i = ++turb->td_queue) {
++              struct tmio_td *tmtd = turb->td + i;
++
++              if ((retval = tmio_td_dma_map (ohci, urb, tmtd, i)))
++                      break;
++
++              td_fill (ohci, tmtd->info, tmtd->dma, tmtd->len, urb, i);
++      }
++
++      if (i <= start)
++              return retval;
++
++      /* kickstart the appropriate list */
++      wmb ();
++      switch (urb_priv->ed->type) {
++              case PIPE_BULK:
++                      ohci_writel (ohci, OHCI_BLF, &ohci->regs->cmdstatus);
++                      break;
++              case PIPE_CONTROL:
++                      ohci_writel (ohci, OHCI_CLF, &ohci->regs->cmdstatus);
++                      break;
++      }
++
++      return retval;
++}
++
++/*
++ * This needs to be called with ohci->lock held so the pending urb list
++ * isn't modified.
++ */
++static int tmio_ohci_runqueue (struct ohci_hcd *ohci)
++{
++      urb_priv_t*             priv;
++      int                     retval  = 0;
++
++      list_for_each_entry_reverse (priv, &ohci->pending, pending)
++              if ((retval = tmio_urb_runqueue (ohci, priv->td[0]->urb)))
++                      return retval;
++
++      return retval;
++}
++
++static void tmio_td_fill (struct ohci_hcd *ohci, u32 info,
++                      dma_addr_t data, int len, struct urb *urb, int index)
++{
++      struct tmio_urb*        turb    = urb_to_turb (urb);
++      struct tmio_td*         tmtd    = turb->td + index;
++
++      tmtd->data      = NULL;
++      tmtd->bounce    = NULL;
++      tmtd->dma       = data;
++      tmtd->len       = len;
++      tmtd->info      = info;
++      turb->td_add    = index + 1;
++}
++
++static void
++tmio_td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
++{
++      tmio_td_dma_unmap (ohci, td);
++      td_done (ohci, urb, td);
++}
++
++const static struct ohci_ops tmio_ops = {
++      .dma_pool_alloc = tmio_dma_pool_alloc,
++      .dma_pool_free  = tmio_dma_pool_free,
++      .td_fill        = tmio_td_fill,
++      .td_done        = tmio_td_done,
++};
++
++/*-------------------------------------------------------------------------*/
++
++static irqreturn_t tmio_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
++{
++      irqreturn_t             retval  = ohci_irq (hcd, ptregs);
++
++      if (retval == IRQ_HANDLED) {
++              struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++              unsigned long flags;
++
++              spin_lock_irqsave(&ohci->lock, flags);
++              tmio_ohci_runqueue (ohci);
++              spin_unlock_irqrestore (&ohci->lock, flags);
++      }
++
++      return retval;
++}
++
++/*
++ * This is ohci_urb_enqueue with:
++ *    dma address sanitization for tmio_urb_dma_to_virt()
++ *    allocate extra space in urb_priv for our private data
++ *    initialize urb_priv->td[0]->urb for tmio_ohci_runqueue()
++ *    call tmio_ohci_runqueue() after submitting TDs
++ */
++static int tmio_urb_enqueue (
++      struct usb_hcd  *hcd,
++      struct usb_host_endpoint *ep,
++      struct urb      *urb,
++      gfp_t           mem_flags
++) {
++      struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++      struct ed       *ed;
++      urb_priv_t      *urb_priv;
++      unsigned int    pipe = urb->pipe;
++      int             i, size = 0;
++      unsigned long   flags;
++      int             retval = 0;
++
++#ifdef OHCI_VERBOSE_DEBUG
++      urb_print (urb, "SUB", usb_pipein (pipe));
++#endif
++
++      /* make sure we can convert dma offsets back to virtual addresses */
++      if (!tmio_dma_to_virt (hcd, urb->setup_dma))
++              urb->setup_dma          = 0;
++
++      if (!tmio_dma_to_virt (hcd, urb->transfer_dma))
++              urb->transfer_dma       = sizeof (struct usb_ctrlrequest);
++
++      /* every endpoint has a ed, locate and maybe (re)initialize it */
++      if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval)))
++              return -ENOMEM;
++
++      /* for the private part of the URB we need the number of TDs (size) */
++      switch (ed->type) {
++              case PIPE_CONTROL:
++                      /* td_submit_urb() doesn't yet handle these */
++                      if (urb->transfer_buffer_length > 4096)
++                              return -EMSGSIZE;
++
++                      /* 1 TD for setup, 1 for ACK, plus ... */
++                      size = 2;
++                      /* FALLTHROUGH */
++              // case PIPE_INTERRUPT:
++              // case PIPE_BULK:
++              default:
++                      /* one TD for every 4096 Bytes (can be upto 8K) */
++                      size += urb->transfer_buffer_length / 4096;
++                      /* ... and for any remaining bytes ... */
++                      if ((urb->transfer_buffer_length % 4096) != 0)
++                              size++;
++                      /* ... and maybe a zero length packet to wrap it up */
++                      if (size == 0)
++                              size++;
++                      else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0
++                              && (urb->transfer_buffer_length
++                                      % usb_maxpacket (urb->dev, pipe,
++                                              usb_pipeout (pipe))) == 0)
++                              size++;
++                      break;
++              case PIPE_ISOCHRONOUS: /* number of packets from URB */
++                      size = urb->number_of_packets;
++                      break;
++      }
++
++      /* allocate the private part of the URB */
++      urb_priv = kzalloc (sizeof (urb_priv_t)
++                              + size * sizeof (struct td*)
++                              + sizeof (struct tmio_urb)
++                              + size * sizeof (struct tmio_td),
++                              mem_flags);
++      if (!urb_priv)
++              return -ENOMEM;
++      INIT_LIST_HEAD (&urb_priv->pending);
++      urb_priv->length = size;
++      urb_priv->ed = ed;
++
++      /* allocate the TDs (deferring hash chain updates) */
++      for (i = 0; i < size; i++) {
++              urb_priv->td [i] = td_alloc (ohci, mem_flags);
++              if (!urb_priv->td [i]) {
++                      urb_priv->length = i;
++                      urb_free_priv (ohci, urb_priv);
++                      return -ENOMEM;
++              }
++              urb_priv->td [i]->urb = urb;
++      }
++
++      spin_lock_irqsave (&ohci->lock, flags);
++
++      /* don't submit to a dead HC */
++      if (!HC_IS_RUNNING(hcd->state)) {
++              retval = -ENODEV;
++              goto fail;
++      }
++
++      /* in case of unlink-during-submit */
++      spin_lock (&urb->lock);
++      if (urb->status != -EINPROGRESS) {
++              spin_unlock (&urb->lock);
++              urb->hcpriv = urb_priv;
++              finish_urb (ohci, urb, NULL);
++              retval = 0;
++              goto fail;
++      }
++
++      /* schedule the ed if needed */
++      if (ed->state == ED_IDLE) {
++              retval = ed_schedule (ohci, ed);
++              if (retval < 0)
++                      goto fail0;
++              if (ed->type == PIPE_ISOCHRONOUS) {
++                      u16     frame = ohci_frame_no(ohci);
++
++                      /* delay a few frames before the first TD */
++                      frame += max_t (u16, 8, ed->interval);
++                      frame &= ~(ed->interval - 1);
++                      frame |= ed->branch;
++                      urb->start_frame = frame;
++
++                      /* yes, only URB_ISO_ASAP is supported, and
++                       * urb->start_frame is never used as input.
++                       */
++              }
++      } else if (ed->type == PIPE_ISOCHRONOUS)
++              urb->start_frame = ed->last_iso + ed->interval;
++
++      /* fill the TDs and link them to the ed; and
++       * enable that part of the schedule, if needed
++       * and update count of queued periodic urbs
++       */
++      urb->hcpriv = urb_priv;
++      td_submit_urb (ohci, urb);
++      tmio_ohci_runqueue (ohci);
++
++fail0:
++      spin_unlock (&urb->lock);
++fail:
++      if (retval)
++              urb_free_priv (ohci, urb_priv);
++      spin_unlock_irqrestore (&ohci->lock, flags);
++      return retval;
++}
++
++static const struct hc_driver tmio_hc_driver = {
++      .description =          hcd_name,
++      .product_desc =         "TMIO OHCI USB Host Controller",
++      .hcd_priv_size =        sizeof (struct ohci_hcd)
++                              + sizeof (struct tmio_hcd),
++
++      /* generic hardware linkage */
++      .irq =                  tmio_irq,
++      .flags =                HCD_USB11 | HCD_MEMORY,
++
++      /* basic lifecycle operations */
++      .start =                tmio_start,
++      .stop =                 tmio_stop,
++
++      /* managing i/o requests and associated device resources */
++      .urb_enqueue =          tmio_urb_enqueue,
++      .urb_dequeue =          ohci_urb_dequeue,
++      .endpoint_disable =     ohci_endpoint_disable,
++
++      /* scheduling support */
++      .get_frame_number =     ohci_get_frame,
++
++      /* root hub support */
++      .hub_status_data =      ohci_hub_status_data,
++      .hub_control =          ohci_hub_control,
++#ifdef        CONFIG_PM
++      .bus_suspend =          ohci_bus_suspend,
++      .bus_resume =           ohci_bus_resume,
++#endif
++      .start_port_reset =     ohci_start_port_reset,
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* configure so an HC device and id are always provided */
++/* always called with process context; sleeping is OK */
++
++/**
++ * tmio_probe - initialize TMIO-based HCDs
++ * Context: !in_interrupt()
++ *
++ * Allocates basic resources for this USB host controller, and
++ * then invokes the start() method for the HCD associated with it
++ * through the hotplug entry's driver_data.
++ */
++static int tmio_probe (struct device *dev)
++{
++      struct tmio_device*     tdev    = dev_to_tdev (dev);
++      struct resource*        config  = tmio_resource_config (dev);
++      struct resource*        regs    = tmio_resource_control (dev);
++      struct resource*        sram    = tmio_resource_mem (dev);
++      struct resource*        irq     = tmio_resource_irq (dev);
++      struct usb_operations*  ops;
++      struct tmio_hcd*        tmio;
++      struct ohci_hcd*        ohci;
++      struct usb_hcd*         hcd;
++      int                     retval;
++
++      if (usb_disabled ())
++              return -ENODEV;
++
++      if (dev->dma_mask || dev->coherent_dma_mask) {
++              dev_err (dev, "DMA not supported\n");
++              return -ENODEV;
++      }
++
++      hcd = usb_create_hcd (&tmio_hc_driver, dev, dev->bus_id);
++      if (!hcd) {
++              retval = -ENOMEM;
++              goto err_create_hcd;
++      }
++
++      tmio                    = hcd_to_tmio (hcd);
++      tmio->td_pool.dev       = dev;
++      tmio->ed_pool.dev       = dev;
++      tmio->td_pool.size      = sizeof (struct td);
++      tmio->ed_pool.size      = sizeof (struct ed);
++      ohci                    = hcd_to_ohci (hcd);
++      ohci_hcd_init (ohci);
++      ohci->ops               = &tmio_ops;
++
++      retval = request_resource (tdev->iomem, config);
++      if (retval)
++              goto err_request_config_resource;
++
++      retval = request_resource (tdev->iomem, regs);
++      if (retval)
++              goto err_request_regs_resource;
++
++      retval = request_resource (tdev->iomem, sram);
++      if (retval)
++              goto err_request_sram_resource;
++
++      hcd->rsrc_start = regs->start;
++      hcd->rsrc_len   = regs->end - regs->start + 1;
++      tmio->sram_len  = sram->end - sram->start + 1;
++
++      tmio->ccr = ioremap (config->start, config->end - config->start + 1);
++      if (!tmio->ccr) {
++              retval = -ENOMEM;
++              goto err_ioremap_ccr;
++      }
++
++      hcd->regs = ioremap (hcd->rsrc_start, hcd->rsrc_len);
++      if (!hcd->regs) {
++              retval = -ENOMEM;
++              goto err_ioremap_regs;
++      }
++
++      tmio->sram = ioremap (sram->start, tmio->sram_len);
++      if (!tmio->sram) {
++              retval = -ENOMEM;
++              goto err_ioremap_sram;
++      }
++
++      /* drivers should use our coherent buffer allocator */
++      ops                     = &tmio->ops;
++      memcpy (ops, hcd->self.op, sizeof *ops);
++      ops->buffer_alloc       = tmio_buffer_alloc;
++      ops->buffer_free        = tmio_buffer_free;
++      hcd->self.op            = ops;
++
++      retval = usb_add_hcd (hcd, irq->start, SA_INTERRUPT);
++      if (retval)
++              goto err_usb_add_hcd;
++
++      return 0;
++
++err_usb_add_hcd:
++      iounmap (tmio->sram);
++err_ioremap_sram:
++      iounmap (hcd->regs);
++err_ioremap_regs:
++      iounmap (tmio->ccr);
++err_ioremap_ccr:
++      release_resource (sram);
++err_request_sram_resource:
++      release_resource (regs);
++err_request_regs_resource:
++      release_resource (config);
++err_request_config_resource:
++      usb_put_hcd (hcd);
++err_create_hcd:
++      return retval;
++}
++
++/* may be called without controller electrically present */
++/* may be called with controller, bus, and devices active */
++
++/**
++ * tmio_remove - shutdown processing for TMIO-based HCDs
++ * @dev: USB Host Controller being removed
++ * Context: !in_interrupt()
++ *
++ * Reverses the effect of tmio_probe(), first invoking
++ * the HCD's stop() method.  It is always called from a thread
++ * context, normally "rmmod", "apmd", or something similar.
++ */
++static int tmio_remove (struct device *dev)
++{
++      struct usb_hcd*         hcd     = dev_get_drvdata (dev);
++      struct tmio_hcd*        tmio    = hcd_to_tmio (hcd);
++
++      usb_remove_hcd (hcd);
++      iounmap (tmio->sram);
++      iounmap (hcd->regs);
++      iounmap (tmio->ccr);
++      release_resource (tmio_resource_mem (dev));
++      release_resource (tmio_resource_control (dev));
++      release_resource (tmio_resource_config (dev));
++      usb_put_hcd (hcd);
++      return 0;
++}
++
++static struct device_driver tmio_ohci = {
++      .name           = TMIO_NAME_OHCI,
++      .bus            = &tmio_bus_type,
++      .probe          = tmio_probe,
++      .remove         = tmio_remove,
++};
++
++static int __init tmio_init (void)
++{
++      dbg (DRIVER_INFO " (%s)", TMIO_SOC_NAME);
++      dbg ("block sizes: ed %d td %d",
++                      sizeof (struct ed), sizeof (struct td));
++
++      return driver_register (&tmio_ohci);
++}
++
++static void __exit tmio_exit (void)
++{
++      driver_unregister (&tmio_ohci);
++}
++
++module_init (tmio_init);
++module_exit (tmio_exit);
+Index: git/drivers/usb/host/Kconfig
+===================================================================
+--- git.orig/drivers/usb/host/Kconfig  2006-11-07 21:46:32.000000000 +0000
++++ git/drivers/usb/host/Kconfig       2006-11-07 21:48:38.000000000 +0000
+@@ -84,6 +84,7 @@ config USB_OHCI_HCD
+       depends on USB && USB_ARCH_HAS_OHCI
+       select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+       select I2C if ARCH_PNX4008
++      select GENERIC_ALLOCATOR if TOSHIBA_TC6393XB
+       ---help---
+         The Open Host Controller Interface (OHCI) is a standard for accessing
+         USB 1.1 host controller hardware.  It does more in hardware than Intel's
+Index: git/drivers/usb/host/ohci-hcd.c
+===================================================================
+--- git.orig/drivers/usb/host/ohci-hcd.c       2006-11-07 21:46:32.000000000 +0000
++++ git/drivers/usb/host/ohci-hcd.c    2006-11-07 21:48:33.000000000 +0000
+@@ -944,6 +944,7 @@ MODULE_LICENSE ("GPL");
+       || defined(CONFIG_ARCH_OMAP) \
+       || defined (CONFIG_ARCH_LH7A404) \
+       || defined (CONFIG_PXA27x) \
++      || defined (CONFIG_TOSHIBA_TC6393XB) \
+       || defined (CONFIG_ARCH_EP93XX) \
+       || defined (CONFIG_SOC_AU1X00) \
+       || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/tmio-tc6393-r8.patch b/packages/linux/linux-openzaurus-2.6.18+git/tmio-tc6393-r8.patch
new file mode 100644 (file)
index 0000000..2f1b47d
--- /dev/null
@@ -0,0 +1,800 @@
+ arch/arm/common/Kconfig         |    3 
+ arch/arm/common/Makefile        |    1 
+ arch/arm/common/tc6393xb.c      |  668 ++++++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-pxa/Kconfig       |    1 
+ include/asm-arm/arch-pxa/irqs.h |   10 
+ include/asm-arm/hardware/tmio.h |   44 ++
+ 6 files changed, 727 insertions(+)
+
+Index: git/arch/arm/common/tc6393xb.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ git/arch/arm/common/tc6393xb.c     2006-11-07 22:14:49.000000000 +0000
+@@ -0,0 +1,668 @@
++/*
++ * Toshiba TC6393XB SoC support
++ *
++ * Maintainer: Chris Humbert <mahadri-kernel@drigon.com>
++ *
++ * Copyright (c) 2005-2006 Chris Humbert
++ * Copyright (c) 2005 Dirk Opfer
++ *
++ * Based on code written by Sharp/Lineo for 2.4 kernels
++ * Based on locomo.c
++ *
++ * 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/init.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/fb.h>
++
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/irqs.h>
++#include <asm/hardware/tmio.h>
++
++#ifndef TMIO_SOC_TC6393XB
++#error "TC6393XB SoC not configured"
++#endif
++
++/*--------------------------------------------------------------------------*/
++
++/* cell ids must be 0-based because they are used as array indexes. */
++#define       TC6393_CELL_NAND        0
++#define TC6393_CELL_SD                1
++#define       TC6393_CELL_OHCI        2
++#define TC6393_CELL_SERIAL    3
++#define TC6393_CELL_LCD               4
++#define TC6393_NUM_CELLS      5
++
++#define TC6393_RESOURCE(_name, _start, _end, _flags)  \
++      {                                               \
++              .name           = _name,                \
++              .start          = _start,               \
++              .end            = _end,                 \
++              .flags          = _flags,               \
++      }
++
++#define TC6393_MEM(name, start, size) \
++      TC6393_RESOURCE(name, start, (start) + (size) - 1, IORESOURCE_MEM)
++
++#define TC6393_IRQ(name, irq) \
++      TC6393_RESOURCE(name, irq, irq, IORESOURCE_IRQ)
++
++const static struct resource tc6393_NAND_resource[] = {
++      TC6393_MEM (TMIO_NAME_NAND,     0x000100,       0x100),
++      TC6393_MEM (TMIO_NAME_NAND,     0x001000,       0x008),
++      TC6393_MEM (TMIO_NAME_NAND,     0,              0),
++      TC6393_IRQ (TMIO_NAME_NAND,     IRQ_TC6393_NAND),
++};
++
++const static struct resource tc6393_SD_resource[] = {
++      TC6393_MEM (TMIO_NAME_SD,       0x000200,       0x100),
++      TC6393_MEM (TMIO_NAME_SD,       0x002000,       0x200),
++      TC6393_MEM (TMIO_NAME_SD,       0,              0),
++      TC6393_IRQ (TMIO_NAME_SD,       IRQ_TC6393_SD),
++};
++
++const static struct resource tc6393_OHCI_resource[] = {
++      TC6393_MEM (TMIO_NAME_OHCI,     0x000300,       0x100),
++      TC6393_MEM (TMIO_NAME_OHCI,     0x003000,       0x100),
++      TC6393_MEM (TMIO_NAME_OHCI,     0x010000,       32 * 1024),
++      TC6393_IRQ (TMIO_NAME_OHCI,     IRQ_TC6393_OHCI),
++};
++
++const static struct resource tc6393_SERIAL_resource[] = {
++      TC6393_MEM (TMIO_NAME_SERIAL,   0x000400,       0x100),
++      TC6393_MEM (TMIO_NAME_SERIAL,   0x004000,       0x100),
++      TC6393_MEM (TMIO_NAME_SERIAL,   0,              0),
++      TC6393_IRQ (TMIO_NAME_SERIAL,   IRQ_TC6393_SERIAL),
++};
++
++const static struct resource tc6393_LCD_resource[] = {
++      TC6393_MEM (TMIO_NAME_LCD,      0x000500,       0x100),
++      TC6393_MEM (TMIO_NAME_LCD,      0x005000,       0x200),
++      TC6393_MEM (TMIO_NAME_LCD,      0x100000,       1024 * 1024),
++      TC6393_IRQ (TMIO_NAME_LCD,      IRQ_TC6393_LCD),
++};
++
++#define TC6393_CELL(_NAME)                                            \
++      [TC6393_CELL_##_NAME] = {                                       \
++              .name           = TMIO_NAME_##_NAME,                    \
++              .id             = TC6393_CELL_##_NAME,                  \
++              .resource       = tc6393_##_NAME##_resource,            \
++              .num_resources  = ARRAY_SIZE (tc6393_##_NAME##_resource), \
++      }
++
++struct tc6393_cell {
++      const char*             name;
++      unsigned int            id;
++      const struct resource*  resource;
++      unsigned int            num_resources;
++};
++
++const static struct tc6393_cell tc6393_cell [TC6393_NUM_CELLS] = {
++      TC6393_CELL (NAND       ),
++      TC6393_CELL (SD         ),
++      TC6393_CELL (OHCI       ),
++      TC6393_CELL (SERIAL     ),
++      TC6393_CELL (LCD        ),
++};
++
++/*--------------------------------------------------------------------------*/
++
++/*
++ * TC6393 System Configuration Register
++ */
++struct tc6393_scr {
++      u8 x00[8];
++      u8      revid;          /* 0x08 Revision ID                     */
++      u8 x01[0x47];
++      u8      isr;            /* 0x50 Interrupt Status                */
++      u8 x02;
++      u8      imr;            /* 0x52 Interrupt Mask                  */
++      u8 x03;
++      u8      irr;            /* 0x54 Interrupt Routing               */
++      u8 x04[0x0b];
++      u16     gper;           /* 0x60 GP Enable                       */
++      u8 x05[2];
++      u16     gpi_sr[2];      /* 0x64 GPI Status                      */
++      u16     gpi_imr[2];     /* 0x68 GPI INT Mask                    */
++      u16     gpi_eder[2];    /* 0x6c GPI Edge Detect Enable          */
++      u16     gpi_lir[4];     /* 0x70 GPI Level Invert                */
++      u16     gpo_dsr[2];     /* 0x78 GPO Data Set                    */
++      u16     gpo_doecr[2];   /* 0x7c GPO Data OE Control             */
++      u16     gp_iarcr[2];    /* 0x80 GP Internal Active Reg Control  */
++      u16     gp_iarlcr[2];   /* 0x84 GP Internal Active Reg Level Con*/
++      u8      gpi_bcr[4];     /* 0x88 GPI Buffer Control              */
++      u16     gpa_iarcr;      /* 0x8c GPa Internal Active Reg Control */
++      u8 x06[2];
++      u16     gpa_iarlcr;     /* 0x90 GPa Internal Active Reg Level Co*/
++      u8 x07[2];
++      u16     gpa_bcr;        /* 0x94 GPa Buffer Control              */
++      u8 x08[2];
++      u16     ccr;            /* 0x98 Clock Control                   */
++      u16     pll2cr;         /* 0x9a PLL2 Control                    */
++      u16     pll1cr[2];      /* 0x9c PLL1 Control                    */
++      u8      diarcr;         /* 0xa0 Device Internal Active Reg Contr*/
++      u8      dbocr;          /* 0xa1 Device Buffer Off Control       */
++      u8 x09[0x3e];
++      u8      fer;            /* 0xe0 Function Enable                 */
++      u8 x10[3];
++      u16     mcr;            /* 0xe4 Mode Control                    */
++      u8 x11[0x14];
++      u8      config;         /* 0xfc Configuration Control           */
++      u8 x12[2];
++      u8      debug;          /* 0xff Debug                           */
++} __attribute__ ((packed));
++
++union tc6393_scr_fer {
++      u8              raw;
++struct {
++      unsigned        usben:1;        /* D0   USB enable              */
++      unsigned        lcdcven:1;      /* D1   polysylicon TFT enable  */
++      unsigned        slcden:1;       /* D2   SLCD enable             */
++} __attribute__ ((packed));
++} __attribute__ ((packed));
++
++union tc6393_scr_ccr {
++      u16             raw;
++struct {
++      unsigned        ck32ken:1;      /* D0   SD host clock enable    */
++      unsigned        usbcken:1;      /* D1   USB host clock enable   */
++      unsigned        x00:2;
++      unsigned        sharp:1;        /* D4   ??? set in Sharp's code */
++      unsigned        x01:3;
++      enum {                          disable = 0,
++                                      m12MHz  = 1,
++                                      m24MHz  = 2,
++                                      m48MHz  = 3,
++      }               mclksel:3;      /* D10-D8  LCD controller clock */
++      unsigned        x02:1;
++      enum {                          h24MHz  = 0,
++                                      h48MHz  = 1,
++      }               hclksel:2;      /* D13-D12 host bus clock       */
++      unsigned        x03:2;
++} __attribute__ ((packed));
++} __attribute__ ((packed));
++
++/*--------------------------------------------------------------------------*/
++
++struct tc6393 {
++      spinlock_t              lock;   /* read-modify-write lock       */
++      struct device*          dev;    /* TC6393 device                */
++      struct tc6393_scr __iomem *scr; /* system configuration reg     */
++
++      struct resource         rscr;   /* system config reg resource   */
++      struct resource*        iomem;  /* entire TC6393 iomem resource */
++      unsigned int            irq;    /* hardware cascade irq         */
++
++      struct tmio_device      tdev [TC6393_NUM_CELLS];
++};
++
++/*--------------------------------------------------------------------------*/
++
++static u32 tc6393_ioread32 (const void __iomem *addr)
++{
++      return ((u32) ioread16 (addr)) | (((u32) ioread16 (addr + 2)) << 16);
++}
++
++static u32 tc6393_iowrite32 (u32 val, const void __iomem *addr)
++{
++      iowrite16 (val,         addr);
++      iowrite16 (val >> 16,   addr + 2);
++      return val;
++}
++
++u32 get_tc6393_gpio (struct device *dev)
++{
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++
++      return tc6393_ioread32 (scr->gpo_dsr);
++}
++EXPORT_SYMBOL (get_tc6393_gpio);
++
++u32 set_tc6393_gpio (struct device *dev, u32 bits)
++{
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      unsigned long                   flags;
++      u32                             dsr;
++
++      spin_lock_irqsave (&tc6393->lock, flags);
++      dsr = tc6393_ioread32 (scr->gpo_dsr) | bits;
++      tc6393_iowrite32 (dsr, scr->gpo_dsr);
++      spin_unlock_irqrestore (&tc6393->lock, flags);
++
++      return dsr;
++}
++EXPORT_SYMBOL (set_tc6393_gpio);
++
++u32 reset_tc6393_gpio (struct device *dev, u32 bits)
++{
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      unsigned long                   flags;
++      u32                             dsr;
++
++      spin_lock_irqsave (&tc6393->lock, flags);
++      dsr = tc6393_ioread32 (scr->gpo_dsr) & ~bits;
++      tc6393_iowrite32 (dsr, scr->gpo_dsr);
++      spin_unlock_irqrestore (&tc6393->lock, flags);
++
++      return dsr;
++}
++EXPORT_SYMBOL (reset_tc6393_gpio);
++
++/*--------------------------------------------------------------------------*/
++
++static void
++tc6393_irq (unsigned int irq, struct irqdesc *desc)
++{
++      struct tc6393*                  tc6393  = get_irq_chipdata (irq);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      unsigned int                    isr;
++      unsigned int                    bit;
++      unsigned int                    i;
++
++      desc->chip->ack (irq);
++
++      while ((isr = ioread8(&scr->isr) & ~ioread8(&scr->imr)))
++              for (bit = 1, i = IRQ_TC6393_START; i <= IRQ_TC6393_LCD;
++                                                              bit <<= 1, i++)
++                      if (isr & bit)
++                              desc_handle_irq (i, irq_desc + i);
++}
++
++static void tc6393_irq_ack (unsigned int irq)
++{
++}
++
++static void tc6393_irq_mask (unsigned int irq)
++{
++      struct tc6393*                  tc6393  = get_irq_chipdata (irq);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      unsigned long                   flags;
++
++      spin_lock_irqsave (&tc6393->lock, flags);
++      iowrite8 (ioread8 (&scr->imr) | (1 << (irq - IRQ_TC6393_START)),
++                                                              &scr->imr);
++      spin_unlock_irqrestore (&tc6393->lock, flags);
++}
++
++static void tc6393_irq_unmask (unsigned int irq)
++{
++      struct tc6393*                  tc6393  = get_irq_chipdata (irq);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      unsigned long                   flags;
++
++      spin_lock_irqsave (&tc6393->lock, flags);
++      iowrite8 (ioread8 (&scr->imr) & ~(1 << (irq - IRQ_TC6393_START)),
++                                                              &scr->imr);
++      spin_unlock_irqrestore (&tc6393->lock, flags);
++}
++
++static struct irqchip tc6393_chip = {
++      .ack    = tc6393_irq_ack,
++      .mask   = tc6393_irq_mask,
++      .unmask = tc6393_irq_unmask,
++};
++
++static void tc6393_attach_irq (struct tc6393 *tc6393)
++{
++      unsigned int            irq;
++
++      for (irq = IRQ_TC6393_START; irq <= IRQ_TC6393_LCD; irq++) {
++              set_irq_chip    (irq, &tc6393_chip);
++              set_irq_chipdata(irq, tc6393);
++              set_irq_handler (irq, do_edge_IRQ);
++              set_irq_flags   (irq, IRQF_VALID | IRQF_PROBE);
++      }
++
++      set_irq_type            (tc6393->irq, IRQT_FALLING);
++      set_irq_chipdata        (tc6393->irq, tc6393);
++      set_irq_chained_handler (tc6393->irq, tc6393_irq);
++}
++
++static void tc6393_detach_irq (struct tc6393 *tc6393)
++{
++      unsigned int            irq;
++
++      set_irq_chained_handler (tc6393->irq, NULL);
++      set_irq_chipdata        (tc6393->irq, NULL);
++
++      for (irq = IRQ_TC6393_START; irq <= IRQ_TC6393_LCD; irq++) {
++              set_irq_flags   (irq, 0);
++              set_irq_chip    (irq, NULL);
++              set_irq_chipdata(irq, NULL);
++      }
++}
++
++/*--------------------------------------------------------------------------*/
++
++static int tc6393_bus_match (struct device *dev, struct device_driver *drv)
++{
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      const struct tc6393_cell*       cell    = tdev->soc_data;
++
++      return !strcmp (cell->name, drv->name);
++}
++
++static int tc6393_bus_suspend (struct device *dev, pm_message_t state)
++{
++      struct device_driver*   drv     = dev->driver;
++      return drv && drv->suspend ? drv->suspend (dev, state) : 0;
++}
++
++static int tc6393_bus_resume (struct device *dev)
++{
++      struct device_driver*   drv     = dev->driver;
++      return drv && drv->resume ? drv->resume (dev) : 0;
++}
++
++struct bus_type tc6393_bus_type = {
++      .name           = TMIO_NAME_BUS,
++      .match          = tc6393_bus_match,
++      .suspend        = tc6393_bus_suspend,
++      .resume         = tc6393_bus_resume,
++};
++EXPORT_SYMBOL (tc6393_bus_type);
++
++/*--------------------------------------------------------------------------*/
++
++static void tc6393_cell_clock (struct device *dev, int enable)
++{
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      const struct tc6393_cell*       cell    = tdev->soc_data;
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev->parent);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      union tc6393_scr_ccr            ccr;
++      unsigned long                   flags;
++
++      spin_lock_irqsave (&tc6393->lock, flags);
++      ccr.raw = ioread16 (&scr->ccr);
++
++      switch (cell->id) {
++              case TC6393_CELL_SD:    ccr.ck32ken     = enable;       break;
++              case TC6393_CELL_OHCI:  ccr.usbcken     = enable;       break;
++              case TC6393_CELL_LCD:
++                      ccr.mclksel = enable ? m48MHz : disable;
++                      break;
++      }
++
++      printk (KERN_DEBUG TMIO_NAME_CORE ": scr->ccr = %04x\n", ccr.raw);
++
++      iowrite16(ccr.raw, &scr->ccr);
++      spin_unlock_irqrestore (&tc6393->lock, flags);
++}
++
++static void tc6393_cell_function (struct device *dev, int enable)
++{
++      struct tmio_device*             tdev    = dev_to_tdev (dev);
++      const struct tc6393_cell*       cell    = tdev->soc_data;
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev->parent);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      union tc6393_scr_fer            fer;
++      unsigned long                   flags;
++
++      if (cell->id == TC6393_CELL_NAND) {
++              if (enable) {
++                      /* SMD buffer on */
++                      printk (KERN_DEBUG TMIO_NAME_CORE ": SMD buffer on\n");
++                      iowrite8 (0xff, scr->gpi_bcr + 1);
++              }
++              return;
++      }
++
++      spin_lock_irqsave (&tc6393->lock, flags);
++      fer.raw = ioread16 (&scr->fer);
++
++      switch (cell->id) {
++              case TC6393_CELL_OHCI:  fer.usben       = enable;       break;
++              case TC6393_CELL_LCD:   fer.slcden      = enable;       break;
++      }
++
++      printk (KERN_DEBUG TMIO_NAME_CORE ": scr->fer = %02x\n", fer.raw);
++
++      iowrite8 (fer.raw, &scr->fer);
++      spin_unlock_irqrestore (&tc6393->lock, flags);
++}
++
++static void
++tc6393_lcd_mode (struct device *dev, const struct fb_videomode *mode)
++{
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev->parent);
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++
++      iowrite16 (mode->pixclock,              scr->pll1cr + 0);
++      iowrite16 (mode->pixclock >> 16,        scr->pll1cr + 1);
++}
++
++static struct tmio_cell_ops tc6393_cell_ops = {
++      .clock          = tc6393_cell_clock,
++      .function       = tc6393_cell_function,
++      .lcd_mode       = tc6393_lcd_mode,
++};
++
++static void tc6393_device_release (struct device *dev)
++{
++}
++
++static int
++tc6393_device_register (struct tc6393 *tc6393, struct tmio_cell *tcell)
++{
++      const struct tc6393_cell*       cell;
++      struct tmio_device*             tdev;
++      struct device*                  dev;
++      int                             i;
++
++      for (i = 0; strcmp (tcell->name, tc6393_cell [i].name); )
++              if (++i >= ARRAY_SIZE(tc6393_cell))
++                      return -EINVAL;
++
++      cell                    = tc6393_cell  + i;
++      tdev                    = tc6393->tdev + i;
++      dev                     = &tdev->dev;
++
++      tdev->ops               = &tc6393_cell_ops;
++      tdev->iomem             = tc6393->iomem;
++      tdev->soc_data          = (void*) cell;
++
++      dev->parent             = tc6393->dev;
++      strncpy (dev->bus_id, cell->name, sizeof dev->bus_id);
++      dev->bus                = &tc6393_bus_type;
++      dev->dma_mask           = tc6393->dev->dma_mask;
++      dev->coherent_dma_mask  = tc6393->dev->coherent_dma_mask;
++      dev->release            = tc6393_device_release;
++      dev->platform_data      = tcell->platform_data;
++
++      for (i=0; i < cell->num_resources; i++) {
++              const struct resource*  cr      = cell->resource + i;
++              struct resource*        dr      = tdev->resource + i;
++
++              dr->name        = cr->name;
++              dr->start       = cr->start;
++              dr->end         = cr->end;
++              dr->flags       = cr->flags;
++
++              /* convert memory offsets to absolutes */
++              if (cr->flags & IORESOURCE_MEM) {
++                      dr->start       += tc6393->iomem->start;
++                      dr->end         += tc6393->iomem->start;
++              }
++      }
++
++      return device_register (dev);
++}
++
++/*--------------------------------------------------------------------------*/
++
++static void tc6393_hw_init (struct tc6393 *tc6393)
++{
++      struct tc6393_scr __iomem *     scr     = tc6393->scr;
++      struct tc6393_platform_data*    tcpd    = tc6393->dev->platform_data;
++
++      tcpd->enable (tc6393->dev);
++
++      iowrite8 (0,                            &scr->fer);
++      iowrite16(tcpd->scr_pll2cr,             &scr->pll2cr);
++      iowrite16(tcpd->scr_ccr,                &scr->ccr);
++      iowrite16(tcpd->scr_mcr,                &scr->mcr);
++      iowrite16(tcpd->scr_gper,               &scr->gper);
++      iowrite8 (0,                            &scr->irr);
++      iowrite8 (0xbf,                         &scr->imr);
++      iowrite16(tcpd->scr_gpo_dsr,            scr->gpo_dsr + 0);
++      iowrite16(tcpd->scr_gpo_dsr >> 16,      scr->gpo_dsr + 1);
++      iowrite16(tcpd->scr_gpo_doecr,          scr->gpo_doecr + 0);
++      iowrite16(tcpd->scr_gpo_doecr >> 16,    scr->gpo_doecr + 1);
++}
++
++static int tc6393_probe (struct device *dev)
++{
++      struct platform_device*         pdev    = to_platform_device (dev);
++      struct tc6393_platform_data*    tcpd    = dev->platform_data;
++      struct tc6393*                  tc6393;
++      struct resource*                iomem;
++      struct resource*                rscr;
++      int                             retval;
++      int                             i;
++
++      iomem = platform_get_resource (pdev, IORESOURCE_MEM, 0);
++      if (!iomem)
++              return -EINVAL;
++
++      tc6393 = kzalloc (sizeof *tc6393, GFP_KERNEL);
++      if (!tc6393) {
++              retval = -ENOMEM;
++              goto err_kzalloc;
++      }
++
++      dev_set_drvdata (dev, tc6393);
++      spin_lock_init (&tc6393->lock);
++      tc6393->dev     = dev;
++      tc6393->iomem   = iomem;
++      tc6393->irq     = platform_get_irq (pdev, 0);
++
++      rscr            = &tc6393->rscr;
++      rscr->name      = TMIO_NAME_CORE;
++      rscr->start     = iomem->start;
++      rscr->end       = iomem->start + 0xff;
++      rscr->flags     = IORESOURCE_MEM;
++
++      retval = request_resource (iomem, rscr);
++      if (retval)
++              goto err_request_scr;
++
++      tc6393->scr     = ioremap (rscr->start, rscr->end - rscr->start + 1);
++      if (!tc6393->scr) {
++              retval = -ENOMEM;
++              goto err_ioremap;
++      }
++
++      tc6393_hw_init (tc6393);
++
++      printk (KERN_INFO "Toshiba %s revision %d at 0x%08lx, irq %d\n",
++                      TMIO_SOC_NAME, ioread8 (&tc6393->scr->revid),
++                      iomem->start, tc6393->irq);
++
++      if (tc6393->irq)
++              tc6393_attach_irq (tc6393);
++
++      for (i = 0; i < tcpd->num_cells; i++)
++              tc6393_device_register (tc6393, tcpd->cell + i);
++
++      return 0;
++
++err_ioremap:
++      release_resource (rscr);
++err_request_scr:
++      kfree(tc6393);
++err_kzalloc:
++      release_resource (iomem);
++      return retval;
++}
++
++static int tc6393_dev_remove (struct device *dev, void *data)
++{
++      device_unregister (dev);
++      return 0;
++}
++
++static int tc6393_remove (struct device *dev)
++{
++      struct tc6393*          tc6393  = dev_get_drvdata (dev);
++
++      device_for_each_child (dev, tc6393, tc6393_dev_remove);
++
++      if (tc6393->irq)
++              tc6393_detach_irq (tc6393);
++
++      iounmap (tc6393->scr);
++      release_resource (&tc6393->rscr);
++      release_resource (tc6393->iomem);
++      kfree (tc6393);
++      return 0;
++}
++
++#ifdef CONFIG_PM
++static int tc6393_suspend (struct device *dev, pm_message_t state)
++{
++      struct tc6393_platform_data*    tcpd    = dev->platform_data;
++      tcpd->disable (dev);
++      return 0;
++}
++
++static int tc6393_resume (struct device *dev)
++{
++      struct tc6393*                  tc6393  = dev_get_drvdata (dev);
++      tc6393_hw_init (tc6393);
++      return 0;
++}
++#endif
++
++static struct device_driver tc6393_device_driver = {
++      .name           = TMIO_SOC_NAME,
++      .bus            = &platform_bus_type,
++      .probe          = tc6393_probe,
++      .remove         = tc6393_remove,
++#ifdef CONFIG_PM
++      .suspend        = tc6393_suspend,
++      .resume         = tc6393_resume,
++#endif
++};
++
++/*--------------------------------------------------------------------------*/
++
++static int __init tc6393_init (void)
++{
++      int retval = bus_register (&tc6393_bus_type);
++      if (retval)
++              return retval;
++
++      return driver_register (&tc6393_device_driver);
++}
++
++static void __exit tc6393_exit (void)
++{
++      driver_unregister (&tc6393_device_driver);
++      bus_unregister (&tc6393_bus_type);
++}
++
++module_init (tc6393_init);
++module_exit (tc6393_exit);
++
++MODULE_DESCRIPTION ("TC6393 SoC bus driver");
++MODULE_AUTHOR ("Chris Humbert, Dirk Opfer");
++MODULE_LICENSE ("GPL");
+Index: git/arch/arm/common/Kconfig
+===================================================================
+--- git.orig/arch/arm/common/Kconfig   2006-10-31 16:08:28.000000000 +0000
++++ git/arch/arm/common/Kconfig        2006-11-07 22:13:09.000000000 +0000
+@@ -31,3 +31,6 @@ config SHARPSL_PM
+ config SHARP_SCOOP
+       bool
++
++config TOSHIBA_TC6393XB
++      bool
+Index: git/arch/arm/mach-pxa/Kconfig
+===================================================================
+--- git.orig/arch/arm/mach-pxa/Kconfig 2006-11-07 22:13:06.000000000 +0000
++++ git/arch/arm/mach-pxa/Kconfig      2006-11-07 23:30:34.000000000 +0000
+@@ -128,6 +128,7 @@ config MACH_BORZOI
+ config MACH_TOSA
+       bool "Enable Sharp SL-6000x (Tosa) Support"
+       depends PXA_SHARPSL_25x
++      select TOSHIBA_TC6393XB
+ config PXA25x
+       bool
+Index: git/arch/arm/common/Makefile
+===================================================================
+--- git.orig/arch/arm/common/Makefile  2006-10-31 16:08:28.000000000 +0000
++++ git/arch/arm/common/Makefile       2006-11-07 22:13:09.000000000 +0000
+@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM)     += sharpsl_pm.o
+ obj-$(CONFIG_SHARP_SCOOP)     += scoop.o
+ obj-$(CONFIG_ARCH_IXP2000)    += uengine.o
+ obj-$(CONFIG_ARCH_IXP23XX)    += uengine.o
++obj-$(CONFIG_TOSHIBA_TC6393XB)        += tc6393xb.o
+Index: git/include/asm-arm/hardware/tmio.h
+===================================================================
+--- git.orig/include/asm-arm/hardware/tmio.h   2006-11-07 22:13:09.000000000 +0000
++++ git/include/asm-arm/hardware/tmio.h        2006-11-07 22:13:09.000000000 +0000
+@@ -91,6 +91,50 @@ struct tmio_device {
+ /*--------------------------------------------------------------------------*/
++/*
++ * TC6393XB SoC
++ */
++#ifdef CONFIG_TOSHIBA_TC6393XB
++#define TMIO_SOC_TC6393XB
++#define TMIO_SOC_NAME                 "TC6393XB"
++#define TMIO_NAME_BUS                 "tc6393-bus"
++#define TMIO_NAME_CORE                        "tc6393-core"
++#define TMIO_NAME_NAND                        "tc6393-nand"
++#define TMIO_NAME_SD                  "tc6393-sd"
++#define TMIO_NAME_OHCI                        "tc6393-ohci"
++#define TMIO_NAME_SERIAL              "tc6393-serial"
++#define TMIO_NAME_LCD                 "tc6393-lcd"
++#define tmio_bus_type                 tc6393_bus_type
++
++#define TC6393_GPIO(x)                        (1 << (x))
++
++extern struct bus_type tc6393_bus_type;
++
++struct tc6393_platform_data {
++      u16     scr_pll2cr;             /* PLL2 Control                 */
++      u16     scr_ccr;                /* Clock Control                */
++      u16     scr_mcr;                /* Mode Control                 */
++      u16     scr_gper;               /* GP Enable                    */
++      u32     scr_gpo_doecr;          /* GPO Data OE Control          */
++      u32     scr_gpo_dsr;            /* GPO Data Set                 */
++
++      /* cells to register as devices */
++      struct tmio_cell*               cell;
++      unsigned int                    num_cells;
++
++      /* callbacks to enable and disable the TC6393XB's power and clock */
++      void (*enable)  (struct device *dev);
++      void (*disable) (struct device *dev);
++};
++
++u32   get_tc6393_gpio         (struct device *dev);
++u32   set_tc6393_gpio         (struct device *dev, u32 bits);
++u32   reset_tc6393_gpio       (struct device *dev, u32 bits);
++
++/*--------------------------------------------------------------------------*/
++
++#else
+ #error "no TMIO SoC configured"
++#endif
+ #endif
+Index: git/include/asm-arm/arch-pxa/irqs.h
+===================================================================
+--- git.orig/include/asm-arm/arch-pxa/irqs.h   2006-10-31 16:09:33.000000000 +0000
++++ git/include/asm-arm/arch-pxa/irqs.h        2006-11-07 22:13:09.000000000 +0000
+@@ -163,17 +163,27 @@
+ #define IRQ_LOCOMO_SPI_OVRN   (IRQ_BOARD_END + 20)
+ #define IRQ_LOCOMO_SPI_TEND   (IRQ_BOARD_END + 21)
++#define IRQ_TC6393_START      (IRQ_BOARD_END)
++#define IRQ_TC6393_NAND               (IRQ_BOARD_END + 0)
++#define IRQ_TC6393_SD         (IRQ_BOARD_END + 1)
++#define IRQ_TC6393_OHCI               (IRQ_BOARD_END + 2)
++#define IRQ_TC6393_SERIAL     (IRQ_BOARD_END + 3)
++#define IRQ_TC6393_LCD                (IRQ_BOARD_END + 4)
++
+ /*
+  * Figure out the MAX IRQ number.
+  *
+  * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
+  * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
++ * If we have an TC6393XB, the max IRQ is IRQ_TC6393_LCD+1
+  * Otherwise, we have the standard IRQs only.
+  */
+ #ifdef CONFIG_SA1111
+ #define NR_IRQS                       (IRQ_S1_BVD1_STSCHG + 1)
+ #elif defined(CONFIG_SHARP_LOCOMO)
+ #define NR_IRQS                       (IRQ_LOCOMO_SPI_TEND + 1)
++#elif defined(CONFIG_TOSHIBA_TC6393XB)
++#define NR_IRQS                       (IRQ_TC6393_LCD + 1)
+ #elif defined(CONFIG_ARCH_LUBBOCK) || \
+       defined(CONFIG_MACH_LOGICPD_PXA270) || \
+       defined(CONFIG_MACH_MAINSTONE)
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/tosa-keyboard-r18.patch b/packages/linux/linux-openzaurus-2.6.18+git/tosa-keyboard-r18.patch
new file mode 100644 (file)
index 0000000..00bac40
--- /dev/null
@@ -0,0 +1,515 @@
+ drivers/input/keyboard/Kconfig   |   12 -
+ drivers/input/keyboard/Makefile  |    1 
+ drivers/input/keyboard/tosakbd.c |  467 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 479 insertions(+), 1 deletion(-)
+
+Index: git/drivers/input/keyboard/Kconfig
+===================================================================
+--- git.orig/drivers/input/keyboard/Kconfig    2006-10-31 16:08:57.000000000 +0000
++++ git/drivers/input/keyboard/Kconfig 2006-11-07 22:13:10.000000000 +0000
+@@ -148,12 +148,22 @@ config KEYBOARD_SPITZ
+       depends on PXA_SHARPSL
+       default y
+       help
+-        Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
++        Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
+         SL-C3000 and Sl-C3100 series of PDAs.
+         To compile this driver as a module, choose M here: the
+         module will be called spitzkbd.
++config KEYBOARD_TOSA
++      tristate "Tosa keyboard"
++      depends on PXA_SHARPSL
++      default y
++      help
++        Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
++
++        To compile this driver as a module, choose M here: the
++        module will be called tosakbd.
++
+ config KEYBOARD_AMIGA
+       tristate "Amiga keyboard"
+       depends on AMIGA
+Index: git/drivers/input/keyboard/Makefile
+===================================================================
+--- git.orig/drivers/input/keyboard/Makefile   2006-10-31 16:08:57.000000000 +0000
++++ git/drivers/input/keyboard/Makefile        2006-11-07 22:13:10.000000000 +0000
+@@ -17,4 +17,5 @@ obj-$(CONFIG_KEYBOARD_SPITZ)         += spitzkb
+ obj-$(CONFIG_KEYBOARD_HIL)            += hil_kbd.o
+ obj-$(CONFIG_KEYBOARD_HIL_OLD)                += hilkbd.o
+ obj-$(CONFIG_KEYBOARD_OMAP)             += omap-keypad.o
++obj-$(CONFIG_KEYBOARD_TOSA)           += tosakbd.o
+Index: git/drivers/input/keyboard/tosakbd.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ git/drivers/input/keyboard/tosakbd.c       2006-11-07 23:27:19.000000000 +0000
+@@ -0,0 +1,467 @@
++/*
++ *  Keyboard driver for Sharp Tosa models (SL-6000x)
++ *
++ *  Copyright (c) 2005 Dirk Opfer
++ *
++ *  Based on xtkbd.c/locomkbd.c/corgikbd.c
++ *
++ *  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/delay.h>
++#include <linux/platform_device.h>
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/interrupt.h>
++#include <linux/jiffies.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++
++#include <asm/arch/tosa.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++
++#define TOSA_KEY_STROBE_NUM   (11)
++#define TOSA_KEY_SENSE_NUM    (7)
++
++#define KEYMASK_ON            (0x1<<0)
++#define KEYMASK_REC           (0x1<<1)
++#define KEYMASK_SYNC          (0x1<<2)
++
++#define KB_ROWS                       7
++#define KB_COLS                       11
++#define KB_ROWMASK(r)         (1 << (r))
++#define SCANCODE(r,c)         ( ((r)<<4) + (c) + 1 )
++#define       NR_SCANCODES            (SCANCODE(KB_ROWS-1,KB_COLS)+1+1) 
++
++#define SCAN_INTERVAL         (HZ/10)
++#define HP_SCAN_INTERVAL      (150) /* ms */
++#define HP_STABLE_COUNT               2
++
++#define TOSA_KEY_CALENDER       KEY_F1
++#define TOSA_KEY_ADDRESS        KEY_F2
++#define TOSA_KEY_FN             KEY_F3
++#define TOSA_KEY_CANCEL               KEY_F4
++#define TOSA_KEY_OFF            KEY_SUSPEND
++#define TOSA_KEY_CENTER         KEY_F5
++#define TOSA_KEY_REC            KEY_F6
++#define TOSA_KEY_LIGHT          KEY_F7
++#define TOSA_KEY_RECORD         KEY_F8
++#define TOSA_KEY_HOME           KEY_F9
++#define TOSA_KEY_MAIL           KEY_F10
++#define TOSA_KEY_OK             KEY_F11
++#define TOSA_KEY_MENU           KEY_F12
++#define TOSA_KEY_SYNC           KEY_F13
++
++#define GET_ROWS_STATUS(c)    ((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT)
++#define KB_DISCHARGE_DELAY    10
++#define KB_ACTIVATE_DELAY     10
++
++
++static unsigned char tosakbd_keycode[NR_SCANCODES] = {
++      0,                                                                                                                      /* 0 */
++      0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P, 0, 0, 0, TOSA_KEY_OFF, 0, 0, 0, 0,                                      /*1 - 16*/
++      KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA, 0, 0, 0, TOSA_KEY_RECORD, 0, 0, 0, 0,                           /*17 - 32*/
++      KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT, 0, 0, 0, TOSA_KEY_SYNC, 0, 0, 0, 0,                           /*33 - 48*/
++      KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESS, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK, KEY_LEFTSHIFT, 0 , 0,0 , 0, 0, 0, 0,       /*49 - 64*/
++      KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDER, TOSA_KEY_HOME, TOSA_KEY_REC, TOSA_KEY_LIGHT, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,        /*65 - 80*/
++      KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0, 0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0,                        /*81 - 96*/
++      KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0,                   /*97 - 109*/
++};
++
++struct tosakbd {
++      unsigned char keycode[ARRAY_SIZE(tosakbd_keycode)];
++      struct input_dev *input;
++
++      spinlock_t lock;
++      struct timer_list timer;
++      struct timer_list hptimer;
++
++      int hp_state;
++      int hp_count;
++
++      unsigned int suspended;
++      unsigned long suspend_jiffies;
++};
++
++/* Helper functions for reading the keyboard matrix 
++ * Note: We should really be using pxa_gpio_mode to alter GPDR but it 
++ *       requires a function call per GPIO bit which is excessive
++ *       when we need to access 12 bits at once, multiple times.
++ * These functions must be called within local_irq_save()/local_irq_restore()
++ * or similar. 
++ */
++static inline void tosakbd_discharge_all(void)
++{
++      /* STROBE All HiZ */
++      GPCR1  = TOSA_GPIO_HIGH_STROBE_BIT;
++      GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT;
++      GPCR2  = TOSA_GPIO_LOW_STROBE_BIT;
++      GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT;
++}
++
++static inline void tosakbd_activate_all(void)
++{
++      /* STROBE ALL -> High */
++      GPSR1  = TOSA_GPIO_HIGH_STROBE_BIT;
++      GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT;
++      GPSR2  = TOSA_GPIO_LOW_STROBE_BIT;
++      GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT;
++
++      udelay(KB_DISCHARGE_DELAY);
++
++      /* STATE CLEAR */
++      GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT; 
++}
++
++static inline void tosakbd_activate_col(int col)
++{
++      if (col<=5) {
++              /* STROBE col -> High, not col -> HiZ */
++              GPSR1 = TOSA_GPIO_STROBE_BIT(col);
++              GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++      } else {
++              /* STROBE col -> High, not col -> HiZ */
++              GPSR2 = TOSA_GPIO_STROBE_BIT(col);
++              GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++      } 
++}
++
++static inline void tosakbd_reset_col(int col)
++{
++      if (col<=5) {
++              /* STROBE col -> Low */
++              GPCR1 = TOSA_GPIO_STROBE_BIT(col);
++              /* STROBE col -> out, not col -> HiZ */
++              GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++      } else {
++              /* STROBE col -> Low */
++              GPCR2 = TOSA_GPIO_STROBE_BIT(col);
++              /* STROBE col -> out, not col -> HiZ */
++              GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++      } 
++}
++
++/*
++ * Read the GPIOs for POWER, RECORD and SYNC
++ */
++static int read_port_key_status_raw(void)
++{
++      int val=0;
++
++      /* Power key */
++      if ((GPLR0 & GPIO_bit(TOSA_GPIO_ON_KEY))==0)
++              val |= KEYMASK_ON;
++      /* Record key */
++      if ((GPLR0 & GPIO_bit(TOSA_GPIO_RECORD_BTN))==0)
++              val |= KEYMASK_REC;
++      /* Sync key */
++      if ((GPLR0 & GPIO_bit(TOSA_GPIO_SYNC))==0)
++              val |= KEYMASK_SYNC;
++      return val;
++}
++
++
++/*
++ * The tosa keyboard only generates interrupts when a key is pressed.
++ * So when a key is pressed, we enable a timer.  This timer scans the
++ * keyboard, and this is how we detect when the key is released.
++ */
++
++/* Scan the hardware keyboard and push any changes up through the input layer */
++static void tosakbd_scankeyboard(struct tosakbd *tosakbd_data) 
++{
++      unsigned int row, col, rowd;
++      unsigned long flags;
++      unsigned int num_pressed = 0;
++
++      if (tosakbd_data->suspended)
++              return;
++
++      spin_lock_irqsave(&tosakbd_data->lock, flags);
++
++      for (col = 0; col < KB_COLS; col++) {
++              /*
++               * Discharge the output driver capacitatance
++               * in the keyboard matrix. (Yes it is significant..)
++               */
++              tosakbd_discharge_all();
++              udelay(KB_DISCHARGE_DELAY);
++
++              tosakbd_activate_col( col);
++              udelay(KB_ACTIVATE_DELAY);
++              
++              rowd = GET_ROWS_STATUS(col);
++
++              for (row = 0; row < KB_ROWS; row++) {
++                      unsigned int scancode, pressed;
++                      scancode = SCANCODE(row, col);
++                      pressed = rowd & KB_ROWMASK(row);
++                      input_report_key(tosakbd_data->input, tosakbd_data->keycode[scancode], pressed);
++                      if (pressed)
++                              num_pressed++;
++              }
++
++              tosakbd_reset_col(col);
++      }
++
++      tosakbd_activate_all();
++
++      rowd = read_port_key_status_raw();
++
++      for (row = 0; row < 3; row++ ) {
++              unsigned int scancode, pressed;
++              scancode = SCANCODE(row, KB_COLS);
++              pressed = rowd & KB_ROWMASK(row);
++              input_report_key(tosakbd_data->input, tosakbd_data->keycode[scancode], pressed);
++              if (pressed)
++                      num_pressed++;
++
++              if (pressed && (tosakbd_data->keycode[scancode] == TOSA_KEY_OFF)
++                                                              && time_after(jiffies, tosakbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
++                      input_event(tosakbd_data->input, EV_PWR, TOSA_KEY_OFF, 1);
++                      tosakbd_data->suspend_jiffies = jiffies;
++              }
++      }
++      
++      input_sync(tosakbd_data->input);
++
++      /* if any keys are pressed, enable the timer */
++      if (num_pressed)
++              mod_timer(&tosakbd_data->timer, jiffies + SCAN_INTERVAL);
++
++      spin_unlock_irqrestore(&tosakbd_data->lock, flags);
++}
++
++/* 
++ * tosa keyboard interrupt handler.
++ */
++static irqreturn_t tosakbd_interrupt(int irq, void *dev_id)
++{
++      struct tosakbd *tosakbd_data = dev_id;
++
++      if (!timer_pending(&tosakbd_data->timer)) 
++      {
++              /** wait chattering delay **/
++              udelay(20);
++              tosakbd_scankeyboard(tosakbd_data);
++      }
++
++      return IRQ_HANDLED;
++}
++
++/*
++ * tosa timer checking for released keys
++ */
++static void tosakbd_timer_callback(unsigned long data)
++{
++      struct tosakbd *tosakbd_data = (struct tosakbd *) data;
++      tosakbd_scankeyboard(tosakbd_data);
++}
++
++/*
++ * The headphone generates an interrupt.
++ * We debounce the switche and pass them to the input system.
++ */
++
++static irqreturn_t tosakbd_hp_isr(int irq, void *dev_id)
++{
++      struct tosakbd *tosakbd_data = dev_id;
++
++      if (!timer_pending(&tosakbd_data->hptimer))
++              mod_timer(&tosakbd_data->hptimer, jiffies + msecs_to_jiffies(HP_SCAN_INTERVAL));
++
++      return IRQ_HANDLED;
++}
++
++static void tosakbd_hp_timer(unsigned long data)
++{
++      struct tosakbd *tosakbd_data = (struct tosakbd *) data;
++      unsigned long state;
++      unsigned long flags;
++
++      state = (GPLR(TOSA_GPIO_EAR_IN) & GPIO_bit(TOSA_GPIO_EAR_IN));
++      if (state != tosakbd_data->hp_state) {
++              tosakbd_data->hp_count = 0;
++              tosakbd_data->hp_state = state;
++      } else if (tosakbd_data->hp_count < HP_STABLE_COUNT) {
++              tosakbd_data->hp_count++;
++      }
++
++      if (tosakbd_data->hp_count >= HP_STABLE_COUNT) {
++              spin_lock_irqsave(&tosakbd_data->lock, flags);
++
++              input_report_switch(tosakbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(TOSA_GPIO_EAR_IN) & GPIO_bit(TOSA_GPIO_EAR_IN)) == 0));
++              input_sync(tosakbd_data->input);
++
++              spin_unlock_irqrestore(&tosakbd_data->lock, flags);
++      } else {
++              mod_timer(&tosakbd_data->hptimer, jiffies + msecs_to_jiffies(HP_SCAN_INTERVAL));
++      }
++}
++
++#ifdef CONFIG_PM
++static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
++{
++      struct tosakbd *tosakbd = platform_get_drvdata(dev);
++
++      tosakbd->suspended = 1;
++
++      return 0;
++}
++
++static int tosakbd_resume(struct platform_device *dev)
++{
++      struct tosakbd *tosakbd = platform_get_drvdata(dev);
++
++      /* Upon resume, ignore the suspend key for a short while */
++      tosakbd->suspend_jiffies = jiffies;
++      tosakbd->suspended = 0;
++
++      return 0;
++}
++#else
++#define tosakbd_suspend               NULL
++#define tosakbd_resume                NULL
++#endif
++
++static int __init tosakbd_probe(struct platform_device *pdev) {
++
++      int i;
++      struct tosakbd *tosakbd;
++      struct input_dev *input_dev;
++
++      tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL);
++      if (!tosakbd)
++              return -ENOMEM;
++
++      input_dev = input_allocate_device();
++      if (!input_dev) {
++              kfree(tosakbd);
++              return -ENOMEM;
++      }
++
++      platform_set_drvdata(pdev,tosakbd);
++
++      spin_lock_init(&tosakbd->lock);
++
++      /* Init Keyboard rescan timer */
++      init_timer(&tosakbd->timer);
++      tosakbd->timer.function = tosakbd_timer_callback;
++      tosakbd->timer.data = (unsigned long) tosakbd;
++
++      /* Init Headphone Timer */
++      init_timer(&tosakbd->hptimer);
++      tosakbd->hptimer.function = tosakbd_hp_timer;
++      tosakbd->hptimer.data = (unsigned long) tosakbd;
++
++      tosakbd->suspend_jiffies = jiffies;
++
++      tosakbd->input = input_dev;
++
++      input_dev->private = tosakbd;
++      input_dev->name = "Tosa Keyboard";
++      input_dev->phys = "tosakbd/input0";
++      input_dev->cdev.dev = &pdev->dev;
++
++      input_dev->id.bustype = BUS_HOST;
++      input_dev->id.vendor = 0x0001;
++      input_dev->id.product = 0x0001;
++      input_dev->id.version = 0x0100;
++
++      input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
++      input_dev->keycode = tosakbd->keycode;
++      input_dev->keycodesize = sizeof(unsigned char);
++      input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);
++
++      memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd->keycode));
++      for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
++              set_bit(tosakbd->keycode[i], input_dev->keybit);
++      clear_bit(0, input_dev->keybit);
++      set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
++
++      input_register_device(tosakbd->input);
++
++      /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
++      for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
++              pxa_gpio_mode( TOSA_GPIO_KEY_SENSE(i) | GPIO_IN);       
++              if (request_irq(TOSA_IRQ_GPIO_KEY_SENSE(i), tosakbd_interrupt,
++                                              SA_INTERRUPT | SA_TRIGGER_RISING, "tosakbd", tosakbd)) {
++                      printk("tosakbd: Can't get IRQ: %d !\n", i);
++              }
++      }
++      
++      /* Set Strobe lines as outputs - set high */
++      for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) {
++              pxa_gpio_mode( TOSA_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);    
++      }
++
++      // Power&Rec Button
++      pxa_gpio_mode( TOSA_GPIO_ON_KEY | GPIO_IN);     
++      pxa_gpio_mode( TOSA_GPIO_RECORD_BTN | GPIO_IN); 
++      pxa_gpio_mode( TOSA_GPIO_SYNC | GPIO_IN);
++      pxa_gpio_mode( TOSA_GPIO_EAR_IN | GPIO_IN);
++
++      if (request_irq(TOSA_IRQ_GPIO_ON_KEY, tosakbd_interrupt, SA_INTERRUPT | SA_TRIGGER_FALLING, "On key", tosakbd) ||
++          request_irq(TOSA_IRQ_GPIO_RECORD_BTN, tosakbd_interrupt, SA_INTERRUPT | SA_TRIGGER_FALLING, "Record key", tosakbd) ||
++          request_irq(TOSA_IRQ_GPIO_SYNC, tosakbd_interrupt, SA_INTERRUPT | SA_TRIGGER_FALLING, "Sync key", tosakbd) ||
++          request_irq(TOSA_IRQ_GPIO_EAR_IN, tosakbd_hp_isr, SA_INTERRUPT | SA_TRIGGER_FALLING, "HP in", tosakbd)) {
++              printk("Could not allocate KEYBD IRQ!\n");
++      }
++
++      printk(KERN_INFO "input: Tosa Keyboard Registered\n");
++
++      return 0;
++}
++
++static int tosakbd_remove(struct platform_device *dev) {
++      
++      int i;
++      struct tosakbd *tosakbd = platform_get_drvdata(dev);
++      
++      for (i = 0; i < TOSA_KEY_SENSE_NUM; i++)
++              free_irq(TOSA_IRQ_GPIO_KEY_SENSE(i),tosakbd); 
++      
++      free_irq(TOSA_IRQ_GPIO_ON_KEY,tosakbd); 
++      free_irq(TOSA_IRQ_GPIO_RECORD_BTN,tosakbd); 
++      free_irq(TOSA_IRQ_GPIO_SYNC,tosakbd); 
++
++      del_timer_sync(&tosakbd->timer);
++
++      input_unregister_device(tosakbd->input);
++      
++      kfree(tosakbd);
++      
++      return 0;
++}
++
++static struct platform_driver tosakbd_driver = {
++      .probe          = tosakbd_probe,
++      .remove         = tosakbd_remove,
++      .suspend        = tosakbd_suspend,
++      .resume         = tosakbd_resume,
++      .driver         = {
++              .name   = "tosa-keyboard",
++      },
++};
++
++static int __devinit tosakbd_init(void)
++{
++      return platform_driver_register(&tosakbd_driver);
++}
++
++static void __exit tosakbd_exit(void)
++{
++      platform_driver_unregister(&tosakbd_driver);
++}
++
++module_init(tosakbd_init);
++module_exit(tosakbd_exit);
++
++MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
++MODULE_DESCRIPTION("Tosa Keyboard Driver");
++MODULE_LICENSE("GPLv2");
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/tosa-lcdnoise-r1.patch b/packages/linux/linux-openzaurus-2.6.18+git/tosa-lcdnoise-r1.patch
new file mode 100644 (file)
index 0000000..624098b
--- /dev/null
@@ -0,0 +1,157 @@
+Index: linux-2.6.18/arch/arm/mach-pxa/tosa.c
+===================================================================
+--- linux-2.6.18.orig/arch/arm/mach-pxa/tosa.c 2006-09-20 17:14:14.000000000 +0200
++++ linux-2.6.18/arch/arm/mach-pxa/tosa.c      2006-09-20 17:14:43.000000000 +0200
+@@ -2,6 +2,7 @@
+  *  Support for Sharp SL-C6000x PDAs
+  *  Model: (Tosa)
+  *
++ *  Copyright (c) 2006 Wolfson Microelectronics PLC.
+  *  Copyright (c) 2005 Dirk Opfer
+  *
+  *    Based on code written by Sharp/Lineo for 2.4 kernels
+@@ -47,6 +48,8 @@
+ #include <asm/hardware/tmio.h>
+ #include <asm/mach/sharpsl_param.h>
++#include <linux/wm97xx.h>
++
+ #include "generic.h"
+ /*
+@@ -429,6 +432,16 @@
+     },
+ };
++
++/*
++ * Tosa Touchscreen device
++ */
++
++static struct wm97xx_machinfo tosa_ts_machinfo = {
++    .get_hsync_time   = tosa_get_hsync_time,
++    .wait_hsync       = tosa_wait_hsync,
++};
++
+ /*
+  * Tosa Blueooth
+  */
+@@ -458,6 +471,7 @@
+       GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
+       mdelay(1000);
++      wm97xx_unset_machinfo();
+       arm_machine_restart('h');
+ }
+@@ -503,6 +517,8 @@
+       platform_scoop_config = &tosa_pcmcia_config;
+       platform_add_devices(devices, ARRAY_SIZE(devices));
++
++    wm97xx_set_machinfo(&tosa_ts_machinfo);
+ }
+ static void __init fixup_tosa(struct machine_desc *desc,
+Index: linux-2.6.18/arch/arm/mach-pxa/tosa_lcd.c
+===================================================================
+--- linux-2.6.18.orig/arch/arm/mach-pxa/tosa_lcd.c     2006-09-20 17:14:14.000000000 +0200
++++ linux-2.6.18/arch/arm/mach-pxa/tosa_lcd.c  2006-09-20 17:14:15.000000000 +0200
+@@ -1,6 +1,7 @@
+ /*
+  *  LCD / Backlight control code for Sharp SL-6000x (tosa)
+  *
++ *  Copyright (c) 2006      Wolfson Microelectronics PLC.
+  *  Copyright (c) 2005                Dirk Opfer
+  *
+  *  This program is free software; you can redistribute it and/or modify
+@@ -59,6 +60,8 @@
+ static struct ssp_dev tosa_nssp_dev;
+ static struct ssp_state tosa_nssp_state;
+ static spinlock_t tosa_nssp_lock;
++static int blanked;
++static unsigned long hsync_time;
+ static unsigned short normal_i2c[] = {
+       DAC_BASE,
+@@ -130,6 +133,17 @@
+       pxa_nssp_output(TG_GPOSR,0x02);         /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
+ }
++static unsigned long calc_hsync_time(const struct fb_videomode *mode) {
++    /* The 25 and 44 'magic numbers' are from Sharp's 2.4 patches */
++    if (mode->yres == 640) {
++        return 25;
++    }
++    if (mode->yres == 320) {
++        return 44;
++    }
++    return 0;
++}
++
+ static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode)
+ {
+       const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
+@@ -154,6 +168,8 @@
+               /* set common voltage */
+               i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH1, comadj);
++    blanked = 0;
++    hsync_time = calc_hsync_time(mode);
+ }
+ static void tosa_lcd_tg_off(struct device *dev)
+@@ -172,6 +188,8 @@
+       
+       /* L3V Off */
+       reset_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON); 
++
++    blanked = 1;
+ }
+ static int tosa_detect_client(struct i2c_adapter* adapter, int address, int kind) {
+@@ -238,6 +256,23 @@
+       return 0;
+ }
++unsigned long tosa_get_hsync_time(void)
++{
++/* This method should eventually contain the correct algorithm for calculating
++   the hsync_time */
++    if (blanked)
++        return 0;
++    else
++        return hsync_time;
++}
++
++void tosa_wait_hsync(void)
++{
++    /* Waits for a rising edge on the VGA line */
++    while((GPLR(TOSA_GPIO_VGA_LINE) & GPIO_bit(TOSA_GPIO_VGA_LINE)) == 0);
++    while((GPLR(TOSA_GPIO_VGA_LINE) & GPIO_bit(TOSA_GPIO_VGA_LINE)) != 0);
++}
++
+ static struct i2c_driver tosa_driver={
+       .id             = TOSA_LCD_I2C_DEVICEID,
+       .attach_adapter = tosa_attach_adapter,
+Index: linux-2.6.18/include/asm-arm/arch-pxa/tosa.h
+===================================================================
+--- linux-2.6.18.orig/include/asm-arm/arch-pxa/tosa.h  2006-09-20 17:14:13.000000000 +0200
++++ linux-2.6.18/include/asm-arm/arch-pxa/tosa.h       2006-09-20 17:14:15.000000000 +0200
+@@ -1,6 +1,7 @@
+ /*
+  * Hardware specific definitions for Sharp SL-C6000x series of PDAs
+  *
++ * Copyright (c) 2006 Wolfson Microelectronics PLC.
+  * Copyright (c) 2005 Dirk Opfer
+  *
+  * Based on Sharp's 2.4 kernel patches
+@@ -187,4 +188,8 @@
+ extern struct platform_device tosascoop_jc_device;
+ extern struct platform_device tosascoop_device;
+ extern struct platform_device tc6393_device;
++
++unsigned long tosa_get_hsync_time(void);
++void tosa_wait_hsync(void);
++
+ #endif /* _ASM_ARCH_TOSA_H_ */
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/tosa-tmio-lcd-r10.patch b/packages/linux/linux-openzaurus-2.6.18+git/tosa-tmio-lcd-r10.patch
new file mode 100644 (file)
index 0000000..aef3a04
--- /dev/null
@@ -0,0 +1,472 @@
+ arch/arm/mach-pxa/Kconfig    |    5 
+ arch/arm/mach-pxa/Makefile   |    2 
+ arch/arm/mach-pxa/tosa.c     |   49 +++++-
+ arch/arm/mach-pxa/tosa_lcd.c |  344 +++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 396 insertions(+), 4 deletions(-)
+
+Index: git/arch/arm/mach-pxa/Makefile
+===================================================================
+--- git.orig/arch/arm/mach-pxa/Makefile        2006-11-07 22:13:10.000000000 +0000
++++ git/arch/arm/mach-pxa/Makefile     2006-11-07 23:29:38.000000000 +0000
+@@ -17,7 +17,7 @@ obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o 
+ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
+ obj-$(CONFIG_MACH_AKITA)      += akita-ioexp.o
+ obj-$(CONFIG_MACH_POODLE)     += poodle.o corgi_ssp.o sharpsl_pm.o poodle_pm.o
+-obj-$(CONFIG_MACH_TOSA)         += tosa.o sharpsl_pm.o tosa_pm.o
++obj-$(CONFIG_MACH_TOSA)         += tosa.o sharpsl_pm.o tosa_pm.o tosa_lcd.o
+ obj-$(CONFIG_MACH_HX2750)     += hx2750.o hx2750_test.o
+ # Support for blinky lights
+Index: git/arch/arm/mach-pxa/tosa_lcd.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ git/arch/arm/mach-pxa/tosa_lcd.c   2006-11-07 23:29:25.000000000 +0000
+@@ -0,0 +1,344 @@
++/*
++ *  LCD / Backlight control code for Sharp SL-6000x (tosa)
++ *
++ *  Copyright (c) 2005                Dirk Opfer
++ *
++ *  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/init.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/i2c.h>
++#include <linux/fb.h>
++
++#include <asm/mach/sharpsl_param.h>
++#include <asm/hardware.h>
++#include <asm/hardware/scoop.h>
++#include <asm/hardware/tmio.h>
++#include <asm/arch/ssp.h>
++#include <asm/arch/sharpsl.h>
++#include <asm/arch/tosa.h>
++#include <asm/arch/pxa-regs.h>
++
++#define       DAC_BASE        0x4e
++#define DAC_CH1               0
++#define DAC_CH2               1
++
++#define TG_REG0_VQV   0x0001
++#define TG_REG0_COLOR 0x0002
++#define TG_REG0_UD    0x0004
++#define TG_REG0_LR    0x0008
++#define COMADJ_DEFAULT        97
++#define TOSA_LCD_I2C_DEVICEID 0x4711                  // Fixme: new value
++
++static void tosa_lcd_tg_init(struct device *dev);
++static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode);
++static void tosa_lcd_tg_off(struct device *dev);
++static void tosa_set_backlight(int intensity);
++
++const static struct tmio_lcd_ops tosa_tc6393_lcd_ops = {
++      .init = tosa_lcd_tg_init,
++      .tg_on = tosa_lcd_tg_on,
++      .tg_off = tosa_lcd_tg_off,
++};
++
++static struct platform_device *tosabl_device;
++static struct i2c_driver tosa_driver;
++static struct i2c_client* tosa_i2c_dac;
++static int initialised;
++static int comadj;
++static int bl_intensity;
++static struct ssp_dev tosa_nssp_dev;
++static struct ssp_state tosa_nssp_state;
++static spinlock_t tosa_nssp_lock;
++
++static unsigned short normal_i2c[] = {
++      DAC_BASE,
++      I2C_CLIENT_END 
++};
++I2C_CLIENT_INSMOD;
++
++static struct corgibl_machinfo tosa_bl_machinfo = {
++      .max_intensity = 255,
++      .default_intensity = 68,
++      .limit_mask = 0x0b,
++      .set_bl_intensity = tosa_set_backlight,
++};
++
++int tosa_bl_intensity(void)
++{
++      return bl_intensity;
++}
++
++static void pxa_nssp_output(unsigned char reg, unsigned char data)
++{
++      unsigned long flag, dummy;
++      u32 dat = ( ((reg << 5) & 0xe0) | (data & 0x1f) );
++      spin_lock_irqsave(&tosa_nssp_lock, flag);
++
++      ssp_config(&tosa_nssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(128));
++      ssp_enable(&tosa_nssp_dev);
++
++      ssp_write_word(&tosa_nssp_dev,dat);
++
++      /* Read null data back from device to prevent SSP overflow */
++      ssp_read_word(&tosa_nssp_dev, &dummy);
++      ssp_disable(&tosa_nssp_dev);
++      spin_unlock_irqrestore(&tosa_nssp_lock, flag);
++
++}
++
++static void tosa_set_backlight(int intensity)
++{
++      if (!tosa_i2c_dac)
++              return;
++
++      bl_intensity = intensity;
++      /* SetBacklightDuty */
++      i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH2, (unsigned char)intensity);
++
++      /* SetBacklightVR */
++      if (intensity)
++              set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BL_C20MA);
++      else
++              reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BL_C20MA);
++
++      /* bl_enable GP04=1 otherwise GP04=0*/
++      pxa_nssp_output(TG_GPODR2, intensity ? 0x01 : 0x00);    
++}
++
++static void tosa_lcd_tg_init(struct device *dev)
++{
++      /* L3V On */
++      set_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON); 
++      mdelay(60);
++
++      /* TG On */
++      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_TG_ON);
++      mdelay(60);
++
++      pxa_nssp_output(TG_TPOSCTL,0x00);       /* delayed 0clk TCTL signal for VGA */
++      pxa_nssp_output(TG_GPOSR,0x02);         /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
++}
++
++static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode)
++{
++      const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
++      pxa_nssp_output(TG_PNLCTL, value | (mode->yres == 320 ? 0 :  TG_REG0_VQV));
++
++      /* TG LCD pannel power up */
++      pxa_nssp_output(TG_PINICTL,0x4);
++      mdelay(50);
++
++      /* TG LCD GVSS */
++      pxa_nssp_output(TG_PINICTL,0x0);
++
++      if (!initialised)
++      {
++              /* after the pannel is powered up the first time, we can access the i2c bus */
++              /* so probe for the DAC */
++              i2c_add_driver(&tosa_driver);
++              initialised = 1;
++              mdelay(50);
++      }
++      if (tosa_i2c_dac)
++              /* set common voltage */
++              i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH1, comadj);
++
++}
++
++static void tosa_lcd_tg_off(struct device *dev)
++{
++      /* TG LCD VHSA off */
++      pxa_nssp_output(TG_PINICTL,0x4);
++      mdelay(50);
++      
++      /* TG LCD signal off */
++      pxa_nssp_output(TG_PINICTL,0x6);
++      mdelay(50);
++      
++      /* TG Off */
++      set_tc6393_gpio(&tc6393_device.dev, TOSA_TC6393_TG_ON);
++      mdelay(100);
++      
++      /* L3V Off */
++      reset_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON); 
++}
++
++static int tosa_detect_client(struct i2c_adapter* adapter, int address, int kind) {
++      int err = 0;
++
++      printk("Tosa-LCD: DAC detected address:0x%2.2x\n",address);
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA ))
++              goto ERROR0;
++
++      if (!(tosa_i2c_dac = (struct i2c_client*)kzalloc(sizeof(*tosa_i2c_dac), GFP_KERNEL))) {
++              err = -ENOMEM;
++              goto ERROR0;
++      }
++
++      //i2c_set_clientdata(tosa_i2c_dac, data);
++      tosa_i2c_dac->addr = address;
++      tosa_i2c_dac->adapter = adapter;
++      tosa_i2c_dac->driver = &tosa_driver;
++      tosa_i2c_dac->dev.parent = &tc6393_device.dev;
++      strcpy(tosa_i2c_dac->name, "tosa lcd");
++      if ((err = i2c_attach_client(tosa_i2c_dac)))
++              goto ERROR3;
++
++      /* Now i2c is ready, allocate the backlight device*/
++      tosabl_device = platform_device_alloc("corgi-bl", -1);
++      if (!tosabl_device) {
++              err = -ENOMEM;
++              goto ERROR4;
++      }
++
++      /* set parent device */
++      tosabl_device->dev.parent = &tosa_i2c_dac->dev;
++      tosabl_device->dev.platform_data  = &tosa_bl_machinfo;
++
++      err = platform_device_add(tosabl_device);
++
++      if (err)
++              platform_device_put(tosabl_device);
++
++      /* set common voltage */
++      i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH1, comadj);
++
++      return 0;
++ERROR4:
++      i2c_detach_client(tosa_i2c_dac);
++ERROR3:
++      kfree(tosa_i2c_dac);
++ERROR0:
++      return err;
++}
++
++static int tosa_attach_adapter(struct i2c_adapter* adapter) {
++      return i2c_probe(adapter, &addr_data, &tosa_detect_client);
++}
++
++static int tosa_detach_client(struct i2c_client* client) {
++      int err;
++
++      if ((err = i2c_detach_client(client))) {
++              printk(KERN_ERR "tosa: Cannot deregister client\n");
++              return err;
++      }
++      kfree(client);
++      return 0;
++}
++
++static struct i2c_driver tosa_driver={
++      .id             = TOSA_LCD_I2C_DEVICEID,
++      .attach_adapter = tosa_attach_adapter,
++      .detach_client  = tosa_detach_client,
++};
++
++static int __init tosa_lcd_probe(struct platform_device *pdev)
++{
++      int ret;
++      spin_lock_init(&tosa_nssp_lock);
++
++      if (!pdev->dev.platform_data)
++              return -EINVAL;
++
++      /* Set Common Voltage */
++      comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
++
++      ret=ssp_init(&tosa_nssp_dev,2,0);
++
++      /* initialize SSP */
++      pxa_gpio_mode(GPIO83_NSSP_TX);
++      pxa_gpio_mode(GPIO81_NSSP_CLK_OUT);
++      pxa_gpio_mode(GPIO82_NSSP_FRM_OUT);
++
++      if (ret) 
++              printk(KERN_ERR "Unable to register NSSP handler!\n");
++      else {
++              struct tmio_lcd_ops* *tmio_ops = pdev->dev.platform_data;
++              ssp_disable(&tosa_nssp_dev);
++              initialised = 0;
++
++              /* Set the lcd functions */
++              *tmio_ops = (struct tmio_lcd_ops*) &tosa_tc6393_lcd_ops;
++      }
++
++      return ret;
++}
++
++static int tosa_lcd_remove(struct platform_device *pdev)
++{
++      /* delete the lcd functions */
++      struct tmio_lcd_ops* *tmio_ops = pdev->dev.platform_data;
++      *tmio_ops = NULL;
++      
++      ssp_exit(&tosa_nssp_dev);
++      
++      if (tosa_i2c_dac) {
++              i2c_detach_client(tosa_i2c_dac);
++              kfree(tosa_i2c_dac);
++      }
++
++      return 0;
++}
++
++#ifdef CONFIG_PM 
++
++static int tosa_lcd_suspend(struct platform_device *pdev, pm_message_t state)
++{
++      ssp_flush(&tosa_nssp_dev);
++      ssp_save_state(&tosa_nssp_dev,&tosa_nssp_state);
++      return 0;
++}
++
++static int tosa_lcd_resume(struct platform_device *pdev)
++{
++      printk("tosa_lcd_resume\n");
++      ssp_restore_state(&tosa_nssp_dev,&tosa_nssp_state);
++      ssp_enable(&tosa_nssp_dev);
++      printk("tosa_lcd_resume ok\n"); 
++      return 0;
++}
++#else
++
++#define tosa_lcd_suspend NULL
++#define tosa_lcd_resume NULL
++
++#endif
++
++
++static struct platform_driver tosalcd_driver = {
++      .probe          = tosa_lcd_probe,
++      .remove         = tosa_lcd_remove,
++      .suspend        = tosa_lcd_suspend,
++      .resume         = tosa_lcd_resume,
++      .driver         = {
++              .name           = "tosa-lcd",
++      },
++};
++
++static int __init tosa_lcd_init(void)
++{
++      return platform_driver_register(&tosalcd_driver);
++}
++
++static void __exit tosa_lcd_cleanup (void)
++{
++      platform_driver_unregister (&tosalcd_driver);
++}
++
++device_initcall(tosa_lcd_init);
++module_exit (tosa_lcd_cleanup);
++
++MODULE_DESCRIPTION ("Tosa LCD device");
++MODULE_AUTHOR ("Dirk Opfer");
++MODULE_LICENSE ("GPL v2");
+Index: git/arch/arm/mach-pxa/tosa.c
+===================================================================
+--- git.orig/arch/arm/mach-pxa/tosa.c  2006-11-07 22:13:10.000000000 +0000
++++ git/arch/arm/mach-pxa/tosa.c       2006-11-07 23:29:38.000000000 +0000
+@@ -24,6 +24,7 @@
+ #include <linux/mtd/partitions.h>
+ #include <linux/pm.h>
+ #include <linux/delay.h>
++#include <linux/fb.h>
+ #include <asm/setup.h>
+ #include <asm/memory.h>
+@@ -48,7 +49,6 @@
+ #include "generic.h"
+-
+ /*
+  * SCOOP Device
+  */
+@@ -345,7 +345,38 @@ static struct tmio_nand_platform_data to
+       .badblock_pattern = &tosa_tc6393_nand_bbt,
+ };
+-extern struct tmio_lcd_platform_data tosa_tc6393_lcd_platform_data;
++static struct fb_videomode tosa_tc6393_lcd_mode[] = {
++    {
++        .xres = 480,
++        .yres = 640,
++        .pixclock = 0x002cdf00,/* PLL divisor */
++        .left_margin = 0x004c,
++        .right_margin = 0x005b,
++        .upper_margin = 0x0001,
++        .lower_margin = 0x000d,
++        .hsync_len = 0x0002,
++        .vsync_len = 0x0001,
++        .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++        .vmode = FB_VMODE_NONINTERLACED,
++    },{
++      .xres = 240,
++      .yres = 320,
++      .pixclock = 0x00e7f203,/* PLL divisor */
++      .left_margin = 0x0024,
++      .right_margin = 0x002f,
++      .upper_margin = 0x0001,
++      .lower_margin = 0x000d,
++      .hsync_len = 0x0002,
++      .vsync_len = 0x0001,
++      .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++      .vmode = FB_VMODE_NONINTERLACED,
++}};
++
++struct tmio_lcd_platform_data tosa_tc6393_lcd_platform_data = {
++    .ops = NULL,
++    .modelist = tosa_tc6393_lcd_mode,
++    .num_modes = ARRAY_SIZE(tosa_tc6393_lcd_mode),
++};
+ static struct tmio_cell tosa_tc6393_cells[] = {
+       {
+@@ -384,6 +415,19 @@ struct platform_device tc6393_device = {
+       .num_resources  = ARRAY_SIZE(tc6393_resources),
+       .resource       = tc6393_resources,
+ };
++EXPORT_SYMBOL (tc6393_device);
++
++/*
++ * Tosa LCD / Backlight stuff
++ */
++static struct platform_device tosalcd_device = {
++    .name     = "tosa-lcd",
++    .id               = -1,
++    .dev      = {
++      .parent = &tc6393_device.dev,
++      .platform_data = &tosa_tc6393_lcd_platform_data.ops,
++    },
++};
+ static struct platform_device *devices[] __initdata = {
+       &tosascoop_device,
+@@ -391,6 +435,7 @@ static struct platform_device *devices[]
+       &tosakbd_device,
+       &tosaled_device,
+       &tc6393_device,
++      &tosalcd_device,
+ };
+ static void tosa_poweroff(void)
+Index: git/arch/arm/mach-pxa/Kconfig
+===================================================================
+--- git.orig/arch/arm/mach-pxa/Kconfig 2006-11-07 22:13:10.000000000 +0000
++++ git/arch/arm/mach-pxa/Kconfig      2006-11-07 22:13:10.000000000 +0000
+@@ -129,7 +129,10 @@ config MACH_TOSA
+       bool "Enable Sharp SL-6000x (Tosa) Support"
+       depends PXA_SHARPSL_25x
+       select TOSHIBA_TC6393XB
+-      select SHARPSL_PM       
++      select I2C
++      select I2C_PXA
++      select SHARPSL_PM
++      select PXA_SSP
+ config PXA25x
+       bool
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/wm9712-reset-loop-r2.patch b/packages/linux/linux-openzaurus-2.6.18+git/wm9712-reset-loop-r2.patch
new file mode 100644 (file)
index 0000000..78e81ea
--- /dev/null
@@ -0,0 +1,44 @@
+ sound/soc/codecs/wm9712.c |   28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+Index: git/sound/soc/codecs/wm9712.c
+===================================================================
+--- git.orig/sound/soc/codecs/wm9712.c 2006-11-07 22:10:01.000000000 +0000
++++ git/sound/soc/codecs/wm9712.c      2006-11-07 22:11:50.000000000 +0000
+@@ -618,18 +618,26 @@ static int wm9712_dapm_event(struct snd_
+ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
+ {
+-      if (try_warm && soc_ac97_ops.warm_reset) {
+-              soc_ac97_ops.warm_reset(codec->ac97);
+-              if (!(ac97_read(codec, 0) & 0x8000))
+-                      return 1;
+-      }
++      int retry = 3;
+-      soc_ac97_ops.reset(codec->ac97);
+-      if (ac97_read(codec, 0) & 0x8000)
+-              goto err;
+-      return 0;
++      while (retry--)
++      {
++              if(try_warm && soc_ac97_ops.warm_reset) {
++                      soc_ac97_ops.warm_reset(codec->ac97);
++                      if(ac97_read(codec, 0) & 0x8000)
++                              continue;
++                      else
++                              return 1;
++              }
++
++              soc_ac97_ops.reset(codec->ac97);
++              if(ac97_read(codec, 0) & 0x8000)
++                      continue;
++              else
++                      return 0;
++
++      }
+-err:
+       printk(KERN_ERR "WM9712 AC97 reset failed\n");
+       return -EIO;
+ }
diff --git a/packages/linux/linux-openzaurus-2.6.18+git/wm9712-suspend-cold-res-r2.patch b/packages/linux/linux-openzaurus-2.6.18+git/wm9712-suspend-cold-res-r2.patch
new file mode 100644 (file)
index 0000000..5179b47
--- /dev/null
@@ -0,0 +1,16 @@
+ sound/soc/codecs/wm9712.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: git/sound/soc/codecs/wm9712.c
+===================================================================
+--- git.orig/sound/soc/codecs/wm9712.c 2006-11-07 21:57:34.000000000 +0000
++++ git/sound/soc/codecs/wm9712.c      2006-11-07 21:59:30.000000000 +0000
+@@ -651,7 +651,7 @@ static int wm9712_soc_resume(struct plat
+       int i, ret;
+       u16 *cache = codec->reg_cache;
+-      ret = wm9712_reset(codec, 1);
++      ret = wm9712_reset(codec, 0);
+       if (ret < 0){
+               printk(KERN_ERR "could not reset AC97 codec\n");
+               return ret;
index c81d67e..6232c9b 100644 (file)
@@ -82,22 +82,22 @@ SRC_URI_append_collie = "\
 SRC_URI_append_tosa = "\
            ${CHSRC}/usb-ohci-hooks-r1.patch;patch=1 \
            ${CHSRC}/tmio-core-r4.patch;patch=1 \
-           file://tmio-tc6393-r7.patch;patch=1 \
-           file://tmio-nand-r6.patch;patch=1 \
-           file://tmio-ohci-r5.patch;patch=1 \
+           file://tmio-tc6393-r8.patch;patch=1 \
+           file://tmio-nand-r7.patch;patch=1 \
+           file://tmio-ohci-r6.patch;patch=1 \
            ${CHSRC}/tmio-fb-r6.patch;patch=1 \
-           ${DOSRC}/tosa-keyboard-r17.patch;patch=1 \
+           file://tosa-keyboard-r18.patch;patch=1 \
            ${DOSRC}/tosa-pxaac97-r6.patch;patch=1 \
            ${DOSRC}/tosa-tmio-r6.patch;patch=1 \
            ${DOSRC}/tosa-power-r17.patch;patch=1 \
-           file://tosa-tmio-lcd-r9.patch;patch=1 \
+           file://tosa-tmio-lcd-r10.patch;patch=1 \
            ${DOSRC}/tosa-bluetooth-r8.patch;patch=1 \
            ${DOSRC}/wm97xx-lg7-r0.patch;patch=1 \
-           ${DOSRC}/wm9712-suspend-cold-res-r1.patch;patch=1 \
-           ${DOSRC}/sharpsl-pm-postresume-r0.patch;patch=1 \
+           file://wm9712-suspend-cold-res-r2.patch;patch=1 \
+           file://sharpsl-pm-postresume-r1.patch;patch=1 \
            ${DOSRC}/wm97xx-dig-restore-r0.patch;patch=1 \
            ${DOSRC}/wm97xx-miscdevs-resume-r0.patch;patch=1 \
-           ${DOSRC}/wm9712-reset-loop-r1.patch;patch=1 \
+           file://wm9712-reset-loop-r2.patch;patch=1 \
            file://tosa-lcdnoise-r1.patch;patch=1 \
            file://wm97xx-lcdnoise-r0.patch;patch=1 "
 #          ${DOSRC}/tosa-asoc-r1.patch;patch=1 "