linux-rp: cleaned Tosa patches (my fault)
authorMarcin Juszkiewicz <hrw@openembedded.org>
Wed, 31 Oct 2007 10:44:22 +0000 (10:44 +0000)
committerMarcin Juszkiewicz <hrw@openembedded.org>
Wed, 31 Oct 2007 10:44:22 +0000 (10:44 +0000)
19 files changed:
packages/linux/linux-rp-2.6.22/wm97xx-lcdnoise-r0.patch [deleted file]
packages/linux/linux-rp-2.6.23/sharpsl-pm-postresume-r1.patch
packages/linux/linux-rp-2.6.23/tmio-fb-r6-fix-r0.patch
packages/linux/linux-rp-2.6.23/tmio-nand-r8.patch
packages/linux/linux-rp-2.6.23/tmio-tc6393-r8.patch
packages/linux/linux-rp-2.6.23/tosa-bluetooth-r8.patch
packages/linux/linux-rp-2.6.23/tosa-keyboard-r19.patch
packages/linux/linux-rp-2.6.23/tosa-lcdnoise-r1-fix-r0.patch
packages/linux/linux-rp-2.6.23/tosa-lcdnoise-r1.patch
packages/linux/linux-rp-2.6.23/tosa-power-r18-fix-r0.patch
packages/linux/linux-rp-2.6.23/tosa-power-r18.patch
packages/linux/linux-rp-2.6.23/tosa-pxaac97-r6-fix-r0.patch
packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10-fix-r0.patch
packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch
packages/linux/linux-rp-2.6.23/wm9712-reset-loop-r2.patch
packages/linux/linux-rp-2.6.23/wm9712-suspend-cold-res-r2.patch
packages/linux/linux-rp-2.6.23/wm97xx-lcdnoise-r0.patch [deleted file]
packages/linux/linux-rp-2.6.23/wm97xx-lg13-r0-fix-r0.patch
packages/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch

diff --git a/packages/linux/linux-rp-2.6.22/wm97xx-lcdnoise-r0.patch b/packages/linux/linux-rp-2.6.22/wm97xx-lcdnoise-r0.patch
deleted file mode 100644 (file)
index 191de3a..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-Index: linux-tosa/drivers/input/touchscreen/wm9712.c
-===================================================================
---- linux-tosa.orig/drivers/input/touchscreen/wm9712.c 2006-08-29 16:52:36.008543280 +0100
-+++ linux-tosa/drivers/input/touchscreen/wm9712.c      2006-08-29 16:52:50.923275896 +0100
-@@ -1,7 +1,7 @@
- /*
-  * wm9712.c  --  Codec driver for Wolfson WM9712 AC97 Codecs.
-  *
-- * Copyright 2003, 2004, 2005 Wolfson Microelectronics PLC.
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-  * Author: Liam Girdwood
-  *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-  * Parts Copyright : Ian Molton <spyro@f2s.com>
-@@ -13,6 +13,12 @@
-  *  Free Software Foundation;  either version 2 of the  License, or (at your
-  *  option) any later version.
-  *
-+ *  Revision history
-+ *     4th Jul 2005  Initial version.
-+ *    29th Aug 2006  Mike Arthur <mike@mikearthur.co.uk>
-+ *                   Added fixes for Sharp SL-6000 (Tosa) LCD noise causing
-+ *                   touchscreen interference.
-+ *
-  */
- #include <linux/module.h>
-@@ -28,6 +34,10 @@
- #define WM9705_VERSION                "0.60"
- #define DEFAULT_PRESSURE      0xb0c0
-+#define CCNT(a)     asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
-+#define CCNT_ON()   asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
-+#define CCNT_OFF()  asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
-+
- /*
-  * Debug
-  */
-@@ -243,6 +253,36 @@
-       return wm->dig[2] & WM9712_PDEN;
- }
-+
-+#ifdef CONFIG_MACH_TOSA
-+/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
-+ * before sampling the Y axis of the touchscreen */
-+static inline void wm9712_lcd_sync_on(struct wm97xx* wm, int adcsel) {
-+    unsigned long timer1 = 0, timer2 = 0, wait_time = 0;
-+    if (adcsel == WM97XX_ADCSEL_Y) {
-+        wait_time = wm97xx_calc_lcd_waittime(wm);
-+
-+        CCNT_ON();
-+
-+        if (wait_time) {
-+            /* wait for LCD rising edge */
-+            wm_machinfo->wait_hsync();
-+            /* get clock */
-+            CCNT(timer1);
-+            CCNT(timer2);
-+
-+            while ((timer2 - timer1) < wait_time) {
-+                CCNT(timer2);
-+            }
-+        }
-+    }
-+}
-+
-+static inline void wm9712_lcd_sync_off(void) {
-+    CCNT_OFF();
-+}
-+#endif
-+
- /*
-  * Read a sample from the WM9712 adc in polling mode.
-  */
-@@ -260,6 +300,9 @@
-       /* set up digitiser */
-       if (adcsel & 0x8000)
-               adcsel = ((adcsel & 0x7fff) + 3) << 12;
-+    #ifdef CONFIG_MACH_TOSA
-+    wm9712_lcd_sync_on(wm, adcsel);
-+    #endif
-       wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
-       
-       /* wait 3 AC97 time slots + delay for conversion */
-@@ -282,6 +325,10 @@
-       
-       *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-       
-+    #ifdef CONFIG_MACH_TOSA
-+    wm9712_lcd_sync_off();
-+    #endif
-+
-       /* check we have correct sample */
-       if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
-               dbg ("adc wrong sample, read %x got %x", adcsel,
-@@ -303,11 +350,12 @@
- static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
- {
-       int rc;
--      
-       if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
-               return rc;
-+
-       if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
-               return rc;
-+
-       if (pil && !five_wire) {
-               if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
-                       return rc;
-Index: linux-tosa/drivers/input/touchscreen/wm97xx-core.c
-===================================================================
---- linux-tosa.orig/drivers/input/touchscreen/wm97xx-core.c    2006-08-29 16:52:36.008543280 +0100
-+++ linux-tosa/drivers/input/touchscreen/wm97xx-core.c 2006-08-29 16:52:50.924275744 +0100
-@@ -2,7 +2,7 @@
-  * wm97xx-core.c  --  Touch screen driver core for Wolfson WM9705, WM9712
-  *                           and WM9713 AC97 Codecs.
-  *
-- * Copyright 2003, 2004, 2005 Wolfson Microelectronics PLC.
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-  * Author: Liam Girdwood
-  *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-  * Parts Copyright : Ian Molton <spyro@f2s.com>
-@@ -67,6 +67,9 @@
-  *                   GPIOs) and 2.6 power management. 
-  *    29th Nov 2004  Added WM9713 support.
-  *     4th Jul 2005  Moved codec specific code out to seperate files.
-+ *    29th Aug 2006  Mike Arthur <mike@mikearthur.co.uk>
-+ *                   Added fixes for Sharp SL-6000 (Tosa) LCD noise causing
-+ *                   touchscreen interference.
-  */  
-     
- #include <linux/module.h>
-@@ -94,6 +97,7 @@
- static DECLARE_MUTEX(gpio_sem);
- static LIST_HEAD(wm97xx_misc_list);
- static struct wm97xx* wm_codec = NULL;
-+struct wm97xx_machinfo *wm_machinfo;
- /*
-  * WM97xx - enable/disable AUX ADC sysfs 
-@@ -832,6 +836,23 @@
-               mdev->remove(wm_codec);
- }
-+#ifdef CONFIG_MACH_TOSA
-+/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
-+ * before sampling the Y axis of the touchscreen */
-+unsigned long wm97xx_calc_lcd_waittime(struct wm97xx *wm) {
-+    unsigned long hsync_time = wm_machinfo->get_hsync_time();
-+    return hsync_time;
-+}
-+
-+void wm97xx_set_machinfo(struct wm97xx_machinfo *machinfo) {
-+    wm_machinfo = machinfo;
-+}
-+
-+void wm97xx_unset_machinfo() {
-+    wm_machinfo = NULL;
-+}
-+#endif
-+
- static struct device_driver wm97xx_driver = {
-       .name =         "ac97", 
-       .bus =          &ac97_bus_type, 
-@@ -861,6 +882,9 @@
- EXPORT_SYMBOL_GPL(wm97xx_reg_write);
- EXPORT_SYMBOL_GPL(wm97xx_register_misc_dev);
- EXPORT_SYMBOL_GPL(wm97xx_unregister_misc_dev);
-+EXPORT_SYMBOL_GPL(wm97xx_calc_lcd_waittime);
-+EXPORT_SYMBOL_GPL(wm97xx_set_machinfo);
-+EXPORT_SYMBOL_GPL(wm97xx_unset_machinfo);
- module_init(wm97xx_init); 
- module_exit(wm97xx_exit);
-Index: linux-tosa/include/linux/wm97xx.h
-===================================================================
---- linux-tosa.orig/include/linux/wm97xx.h     2006-08-29 16:52:36.008543280 +0100
-+++ linux-tosa/include/linux/wm97xx.h  2006-08-29 16:52:50.924275744 +0100
-@@ -207,6 +207,7 @@
- struct wm97xx;
- extern struct wm97xx_codec_drv wm97xx_codec;
-+extern struct wm97xx_machinfo *wm_machinfo;
- /*
-  * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs
-@@ -253,6 +254,11 @@
-       struct list_head list;
- };
-+struct wm97xx_machinfo {
-+    unsigned long (*get_hsync_time)(void);
-+    void (*wait_hsync)(void);
-+};
-+
- int wm97xx_register_misc_dev(struct wm97xx_misc_dev* mdev);
- void wm97xx_unregister_misc_dev(struct wm97xx_misc_dev* mdev);
-@@ -281,4 +287,9 @@
- int wm97xx_acc_startup(struct wm97xx* wm);
- void wm97xx_acc_shutdown(struct wm97xx* wm);
-+
-+unsigned long wm97xx_calc_lcd_waittime(struct wm97xx *wm);
-+void wm97xx_set_machinfo(struct wm97xx_machinfo *machinfo);
-+void wm97xx_unset_machinfo(void);
-+
- #endif
index e1491d6..409daf0 100644 (file)
@@ -22,36 +22,6 @@ Index: git/arch/arm/common/sharpsl_pm.c
        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;
- 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();
 +      
index 523edec..eab57c5 100644 (file)
@@ -43,48 +43,3 @@ index 10b0105..72eb76c 100644
 -- 
 1.4.4.4
 
-From 302745ce6f3bab7b1a97de32339405ae3fd8eacb Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Fri, 19 Oct 2007 00:05:54 +0400
-Subject: [PATCH] tmio-fb-r6.patch fixes
-
----
- drivers/video/tmiofb.c |    8 ++++----
- 1 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
-index 10b0105..72eb76c 100644
---- a/drivers/video/tmiofb.c
-+++ b/drivers/video/tmiofb.c
-@@ -463,8 +463,8 @@ static int tmiofb_vblank (struct fb_info *fbi, struct fb_vblank *vblank)
- #define FBIO_TMIO_ACC_WRITE   0x7C639300
- #define FBIO_TMIO_ACC_SYNC    0x7C639301
--static int tmiofb_ioctl (struct inode *inode, struct file *file,
--              unsigned int cmd, unsigned long arg, struct fb_info *fbi)
-+static int tmiofb_ioctl (struct fb_info *fbi,
-+              unsigned int cmd, unsigned long arg)
- {
-       switch (cmd) {
-               case FBIOGET_VBLANK: {
-@@ -677,7 +677,7 @@ static struct fb_ops tmiofb_ops_acc = {
-  *    2000            0002    display start
-  *    2000            0004    line number match (0x1ff mask???)
-  */
--static irqreturn_t tmiofb_irq (int irq, void *__fbi, struct pt_regs *r)
-+static irqreturn_t tmiofb_irq (int irq, void *__fbi)
- {
-       struct fb_info*                 fbi     = __fbi;
-       struct tmiofb_par*              par     = fbi->par;
-@@ -762,7 +762,7 @@ static int __init tmiofb_probe (struct device *dev)
-       }
-       fbi->screen_base = par->sram;
--      retval = request_irq (irq->start, &tmiofb_irq, SA_INTERRUPT,
-+      retval = request_irq (irq->start, &tmiofb_irq, IRQF_DISABLED,
-                                                       TMIO_NAME_LCD, fbi);
-       if (retval)
-               goto err_request_irq;
--- 
-1.4.4.4
-
index 3a30c2f..a71fd11 100644 (file)
@@ -592,597 +592,3 @@ index 0000000..d196553
 +MODULE_LICENSE ("GPL");
 +MODULE_AUTHOR ("Dirk Opfer, Chris Humbert");
 +MODULE_DESCRIPTION ("NAND flash driver on Toshiba Mobile IO controller");
- drivers/mtd/nand/Kconfig  |    7 +
- drivers/mtd/nand/Makefile |    1 +
- drivers/mtd/nand/tmio.c   |  554 +++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 562 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
-index f1d60b6..b9c8796 100644
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -69,6 +69,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 && BROKEN
-diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
-index edba1db..64f24e1 100644
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -27,5 +27,6 @@ obj-$(CONFIG_MTD_NAND_AT91)          += at91_nand.o
- obj-$(CONFIG_MTD_NAND_CM_X270)                += cmx270_nand.o
- obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)  += excite_nandflash.o
- obj-$(CONFIG_MTD_NAND_PLATFORM)               += plat_nand.o
-+obj-$(CONFIG_MTD_NAND_TMIO)           += tmio.o
- nand-objs := nand_base.o nand_bbt.o
-diff --git a/drivers/mtd/nand/tmio.c b/drivers/mtd/nand/tmio.c
-new file mode 100644
-index 0000000..d196553
---- /dev/null
-+++ b/drivers/mtd/nand/tmio.c
-@@ -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,
-+                                      IRQF_DISABLED, 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 500fa83..1bfdc23 100644 (file)
@@ -774,806 +774,6 @@ Index: git/include/asm-arm/arch-pxa/irqs.h
  #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)
- 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 irq_desc *desc)
-+{
-+      struct tc6393*                  tc6393  = get_irq_chip_data (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_chip_data (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_chip_data (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 irq_chip 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_chip_data(irq, tc6393);
-+              set_irq_handler (irq, handle_edge_irq);
-+              set_irq_flags   (irq, IRQF_VALID | IRQF_PROBE);
-+      }
-+
-+      set_irq_type            (tc6393->irq, IRQT_FALLING);
-+      set_irq_chip_data       (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_chip_data       (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_chip_data(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/     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 on 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)
index 9976549..7873cff 100644 (file)
@@ -192,197 +192,3 @@ Index: linux-2.6.17/arch/arm/mach-pxa/tosa.c
  };
  
  static void tosa_poweroff(void)
-Index: linux-2.6.17/arch/arm/mach-pxa/Makefile
-===================================================================
---- linux-2.6.17.orig/arch/arm/mach-pxa/Makefile       2006-06-20 11:45:51.252467944 +0200
-+++ linux-2.6.17/arch/arm/mach-pxa/Makefile    2006-06-20 11:46:33.619027248 +0200
-@@ -16,7 +16,7 @@
- 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 tosa_lcd.o
-+obj-$(CONFIG_MACH_TOSA)         += tosa.o sharpsl_pm.o tosa_pm.o tosa_lcd.o tosa_bt.o
- obj-$(CONFIG_MACH_EM_X270) += em-x270.o
- obj-$(CONFIG_MACH_HX2750)     += hx2750.o hx2750_test.o
-Index: linux-2.6.17/arch/arm/mach-pxa/tosa_bt.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/arch/arm/mach-pxa/tosa_bt.c   2006-06-20 11:46:08.107905528 +0200
-@@ -0,0 +1,128 @@
-+/*
-+ *  Bluetooth 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 <asm/hardware.h>
-+
-+#include <asm/hardware/scoop.h>
-+#include <asm/arch/tosa.h>
-+#include <asm/arch/pxa-regs.h>
-+
-+
-+static int tosa_bluetooth_power(int on)
-+{
-+      
-+      if (!on) { //off
-+
-+              set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_RESET);
-+              pxa_gpio_mode(GPIO42_BTRXD|GPIO_IN);
-+              pxa_gpio_mode(GPIO43_BTTXD|GPIO_IN);
-+              pxa_gpio_mode(GPIO44_BTCTS|GPIO_IN);
-+              pxa_gpio_mode(GPIO45_BTRTS|GPIO_IN);
-+              mdelay(10); // wait 10ms
-+              reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_RESET);
-+              reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_PWR_EN);
-+              reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_BT_LED); // turn off BT LED
-+
-+      } else { // on
-+              
-+              reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_RESET);
-+              set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_PWR_EN);
-+              pxa_gpio_mode(GPIO42_HWRXD_MD);
-+              pxa_gpio_mode(GPIO43_HWTXD_MD);
-+              pxa_gpio_mode(GPIO44_HWCTS_MD);
-+              pxa_gpio_mode(GPIO45_HWRTS_MD);
-+
-+              set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_RESET);
-+              mdelay(20); // wait 20ms
-+              reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_RESET);
-+              set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_BT_LED); // turn BT LED on
-+      }
-+      return 0;
-+}
-+
-+/*
-+ *  Support Routines
-+ */
-+int __init tosa_bluetooth_probe(struct platform_device *dev)
-+{
-+      int ret = 0;
-+      pxa_gpio_mode(GPIO42_BTRXD|GPIO_IN);
-+      pxa_gpio_mode(GPIO43_BTTXD|GPIO_IN);
-+      pxa_gpio_mode(GPIO44_BTCTS|GPIO_IN);
-+      pxa_gpio_mode(GPIO45_BTRTS|GPIO_IN);
-+      set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_PWR_EN);
-+      mdelay(5);
-+
-+      if ( (GPLR(GPIO42_BTRXD) & GPIO_bit(GPIO42_BTRXD))==0 &&
-+           (GPLR(GPIO44_BTCTS) & GPIO_bit(GPIO44_BTCTS))==0) {
-+              printk(KERN_INFO "No Bluetooth Device found!\n");
-+              ret = ENODEV; // no bluetooth
-+      } else {
-+              printk(KERN_INFO "Tosa Bluetooth Device found on ttyS3!\n");
-+      }
-+      reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_BT_PWR_EN);
-+      
-+      tosa_bluetooth_power(1);                // Power on
-+      return ret;
-+}
-+
-+static int tosa_bluetooth_remove(struct platform_device *dev)
-+{
-+      tosa_bluetooth_power(0);                // Power off
-+      return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int tosa_bluetooth_suspend(struct platform_device *dev, pm_message_t state)
-+{
-+      tosa_bluetooth_power(0);        // Power off
-+      return 0;
-+}
-+
-+static int tosa_bluetooth_resume(struct platform_device *dev)
-+{
-+      tosa_bluetooth_power(1);        // Power on
-+      return 0;
-+}
-+#else
-+#define tosa_bluetooth_suspend NULL
-+#define tosa_bluetooth_resume NULL
-+#endif
-+
-+static struct platform_driver tosa_bluetooth_driver = {
-+      .probe          = tosa_bluetooth_probe,
-+      .remove         = tosa_bluetooth_remove,
-+      .suspend        = tosa_bluetooth_suspend,
-+      .resume         = tosa_bluetooth_resume,
-+        .driver         = {
-+                          .name   = "tosa-bluetooth",
-+      },
-+};
-+
-+int __init tosa_bluetooth_init(void)
-+{
-+      return platform_driver_register(&tosa_bluetooth_driver);
-+}
-+
-+void __exit tosa_bluetooth_cleanup(void)
-+{
-+      platform_driver_unregister(&tosa_bluetooth_driver);
-+}
-+
-+module_init(tosa_bluetooth_init);
-+module_exit(tosa_bluetooth_cleanup);
-Index: linux-2.6.17/arch/arm/mach-pxa/tosa.c
-===================================================================
---- linux-2.6.17.orig/arch/arm/mach-pxa/tosa.c 2006-06-20 11:45:51.254467640 +0200
-+++ linux-2.6.17/arch/arm/mach-pxa/tosa.c      2006-06-20 11:46:08.112904768 +0200
-@@ -288,7 +288,7 @@
- static void tosa_tc6393_enable(struct device *dev)
- {
--
-+      printk("!!tosa_tc6393_enable!!\n");
-       reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON);
-       reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393_SUSPEND);
-       reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_TC6393_REST_IN);      //#PCLR
-@@ -303,7 +303,7 @@
- static void tosa_tc6393_disable(struct device *dev)
- {
--
-+      printk("!!tosa_tc6393_disable!!\n");
-       reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON);
-       reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393_SUSPEND);
-       reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_TC6393_REST_IN);      //#PCLR
-@@ -428,6 +428,17 @@
-     },
- };
-+/*
-+ * Tosa Blueooth
-+ */
-+static struct platform_device tosa_bluetooth_device = {
-+      .name           = "tosa-bluetooth",
-+      .id             = -1,
-+      .dev            = {
-+              .parent         = &tosascoop_jc_device.dev,
-+      },
-+};
-+
- static struct platform_device *devices[] __initdata = {
-       &tosascoop_device,
-       &tosascoop_jc_device,
-@@ -435,6 +446,7 @@
-       &tosaled_device,
-       &tc6393_device,
-       &tosalcd_device,
-+      &tosa_bluetooth_device,
- };
- static void tosa_poweroff(void)
index 5d94f25..948c27f 100644 (file)
@@ -512,517 +512,3 @@ Index: git/drivers/input/keyboard/tosakbd.c
 +MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
 +MODULE_DESCRIPTION("Tosa Keyboard Driver");
 +MODULE_LICENSE("GPLv2");
- 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,3 +17,4 @@ obj-$(CONFIG_KEYBOARD_SPITZ)         += spitzkb
- obj-$(CONFIG_KEYBOARD_AAED2000)               += aaed2000_kbd.o
- obj-$(CONFIG_KEYBOARD_GPIO)           += gpio_keys.o
- obj-$(CONFIG_KEYBOARD_ASIC3)          += asic3_keys.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,
-+                                              IRQF_DISABLED | IRQF_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, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "On key", tosakbd) ||
-+          request_irq(TOSA_IRQ_GPIO_RECORD_BTN, tosakbd_interrupt, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Record key", tosakbd) ||
-+          request_irq(TOSA_IRQ_GPIO_SYNC, tosakbd_interrupt, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Sync key", tosakbd) ||
-+          request_irq(TOSA_IRQ_GPIO_EAR_IN, tosakbd_hp_isr, IRQF_DISABLED | IRQF_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");
index 02dd6a7..93a9c18 100644 (file)
@@ -133,138 +133,3 @@ index ce7322d..7f446fd 100644
 -- 
 1.4.4.4
 
-From eada869814636157956641ba1503f0d6cc04e2b7 Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Fri, 19 Oct 2007 17:43:51 +0400
-Subject: [PATCH] tosa-lcdnoise-r1.patch fixes
-
----
- arch/arm/mach-pxa/tosa_lcd.c        |   34 ++++++++++++++++++++++++++++++++++
- drivers/input/touchscreen/tosa_ts.c |    9 +--------
- include/asm-arm/arch-pxa/tosa.h     |    5 +++++
- 3 files changed, 40 insertions(+), 8 deletions(-)
-
-diff --git a/arch/arm/mach-pxa/tosa_lcd.c b/arch/arm/mach-pxa/tosa_lcd.c
-index d52f63f..447ca86 100644
---- a/arch/arm/mach-pxa/tosa_lcd.c
-+++ b/arch/arm/mach-pxa/tosa_lcd.c
-@@ -59,6 +59,8 @@ 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 int blanked;
-+static unsigned long hsync_time;
- static unsigned short normal_i2c[] = {
-       DAC_BASE,
-@@ -130,6 +132,17 @@ static void tosa_lcd_tg_init(struct device *dev)
-       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 +167,8 @@ static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode)
-               /* 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 +187,8 @@ static void tosa_lcd_tg_off(struct device *dev)
-       
-       /* 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 +255,23 @@ static int tosa_detach_client(struct i2c_client* client) {
-       return 0;
- }
-+unsigned long tosa_lcd_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_lcd_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,
-diff --git a/drivers/input/touchscreen/tosa_ts.c b/drivers/input/touchscreen/tosa_ts.c
-index bc733e9..134f8ce 100644
---- a/drivers/input/touchscreen/tosa_ts.c
-+++ b/drivers/input/touchscreen/tosa_ts.c
-@@ -25,13 +25,6 @@
- #define CCNT_ON()   asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
- #define CCNT_OFF()  asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
--static inline void tosa_lcd_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);
--}
--
- /* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
-  * before sampling the Y axis of the touchscreen */
- void tosa_lcd_sync_on(int adcsel) {
-@@ -54,7 +47,7 @@ void tosa_lcd_sync_on(int adcsel) {
-       }
- }
--void tosa_lcd_sync_off(void) {
-+void tosa_lcd_sync_off(int adcsel) {
-       CCNT_OFF();
- }
-diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
-index ce7322d..7f446fd 100644
---- a/include/asm-arm/arch-pxa/tosa.h
-+++ b/include/asm-arm/arch-pxa/tosa.h
-@@ -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_lcd_get_hsync_time(void);
-+void tosa_lcd_wait_hsync(void);
-+
- #endif /* _ASM_ARCH_TOSA_H_ */
--- 
-1.4.4.4
-
index 910b727..21f3cf6 100644 (file)
@@ -156,161 +156,3 @@ index 0000000..bc733e9
 -- 
 1.4.4.4
 
-From 564b757ba44b517ac6d693b94a177708bb5d3887 Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Fri, 19 Oct 2007 17:30:30 +0400
-Subject: [PATCH] tosa-lcdnoise-r1.patch
-
----
- drivers/input/touchscreen/Kconfig   |   13 +++++
- drivers/input/touchscreen/Makefile  |    1 +
- drivers/input/touchscreen/tosa_ts.c |  102 +++++++++++++++++++++++++++++++++++
- 3 files changed, 116 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
-index 3ac01b4..6862e8f 100644
---- a/drivers/input/touchscreen/Kconfig
-+++ b/drivers/input/touchscreen/Kconfig
-@@ -219,6 +219,19 @@ config TOUCHSCREEN_USB_DMC_TSC10
-       bool "DMC TSC-10/25 device support" if EMBEDDED
-       depends on TOUCHSCREEN_USB_COMPOSITE
-+config TOUCHSCREEN_TOSA
-+    tristate "Sharp Tosa touchscreen driver"
-+    depends on TOUCHSCREEN_WM97XX && MACH_TOSA
-+    default n
-+    help
-+      Say Y here to enable the driver for the touchscreen on the
-+      Sharp Tosa PDA.
-+      depends on TOUCHSCREEN_WM97XX && MACH_TOSA
-+      If unsure, say N.
-+
-+      To compile this driver as a module, choose M here: the
-+      module will be called tosa_ts.
-+
- config TOUCHSCREEN_TSC2101
-       tristate "TI TSC2101 touchscreen input driver"
-       depends on MACH_HX2750 && INPUT && INPUT_TOUCHSCREEN
-diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
-index f64d1a5..4fc0e17 100644
---- a/drivers/input/touchscreen/Makefile
-+++ b/drivers/input/touchscreen/Makefile
-@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_UCB1400)    += ucb1400_ts.o
- obj-$(CONFIG_TOUCHSCREEN_TSC2101)     += tsc2101_ts.o
- obj-$(CONFIG_TOUCHSCREEN_WM97XX)      += wm97xx-ts.o
- obj-$(CONFIG_TOUCHSCREEN_WM97XX_PXA)    += pxa-wm97xx.o
-+obj-$(CONFIG_TOUCHSCREEN_TOSA)                += tosa_ts.o
- ifeq ($(CONFIG_TOUCHSCREEN_WM9713),y)
- wm97xx-ts-objs += wm9713.o
-diff --git a/drivers/input/touchscreen/tosa_ts.c b/drivers/input/touchscreen/tosa_ts.c
-new file mode 100644
-index 0000000..bc733e9
---- /dev/null
-+++ b/drivers/input/touchscreen/tosa_ts.c
-@@ -0,0 +1,102 @@
-+/*
-+ * tosa_ts.c  --  Touchscreen driver for Sharp SL-6000 (Tosa).
-+ *
-+ * Copyright 2006 Wolfson Microelectronics PLC.
-+ * Author: Mike Arthur
-+ *         linux@wolfsonmicro.com
-+ *
-+ *  This program is free software; you can redistribute  it and/or modify it
-+ *  under  the terms of  the GNU General  Public License as published by the
-+ *  Free Software Foundation;  either version 2 of the  License, or (at your
-+ *  option) any later version.
-+ *
-+ *  Revision history
-+ *     1st Sep 2006  Initial version.
-+ *
-+ */
-+
-+#include <linux/wm97xx.h>
-+#include <asm/arch/tosa.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/pxa-regs.h>
-+
-+/* Taken from the Sharp 2.4 kernel code */
-+#define CCNT(a)     asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
-+#define CCNT_ON()   asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
-+#define CCNT_OFF()  asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
-+
-+static inline void tosa_lcd_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);
-+}
-+
-+/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
-+ * before sampling the Y axis of the touchscreen */
-+void tosa_lcd_sync_on(int adcsel) {
-+      unsigned long timer1 = 0, timer2 = 0, wait_time = 0;
-+      if (adcsel == WM97XX_ADCSEL_Y) {
-+              wait_time = tosa_lcd_get_hsync_time();
-+              CCNT_ON();
-+
-+              if (wait_time) {
-+                      /* wait for LCD rising edge */
-+                      tosa_lcd_wait_hsync();
-+                      /* get clock */
-+                      CCNT(timer1);
-+                      CCNT(timer2);
-+
-+                      while ((timer2 - timer1) < wait_time) {
-+                              CCNT(timer2);
-+                      }
-+              }
-+      }
-+}
-+
-+void tosa_lcd_sync_off(void) {
-+      CCNT_OFF();
-+}
-+
-+static struct wm97xx_mach_ops tosa_mach_ops = {
-+      .pre_sample =  tosa_lcd_sync_on,
-+      .post_sample = tosa_lcd_sync_off,
-+};
-+
-+int tosa_ts_probe(struct device *dev) {
-+      struct wm97xx *wm = dev->driver_data;
-+      return wm97xx_register_mach_ops (wm, &tosa_mach_ops);
-+}
-+
-+
-+int tosa_ts_remove(struct device *dev) {
-+      struct wm97xx *wm = dev->driver_data;
-+      wm97xx_unregister_mach_ops (wm);
-+      return 0;
-+}
-+
-+static struct device_driver tosa_ts_driver = {
-+      .name = "wm97xx-touchscreen",
-+      .bus = &wm97xx_bus_type,
-+      .owner = THIS_MODULE,
-+      .probe = tosa_ts_probe,
-+      .remove = tosa_ts_remove,
-+};
-+
-+static int __init tosa_ts_init(void)
-+{
-+      return driver_register(&tosa_ts_driver);
-+}
-+
-+static void __exit tosa_ts_exit(void)
-+{
-+      driver_unregister(&tosa_ts_driver);
-+}
-+
-+module_init(tosa_ts_init);
-+module_exit(tosa_ts_exit);
-+
-+/* Module information */
-+MODULE_AUTHOR("Mike Arthur, mike@mikearthur.co.uk, www.wolfsonmicro.com");
-+MODULE_DESCRIPTION("Sharp SL6000 Tosa Touch Screen Driver");
-+MODULE_LICENSE("GPL");
--- 
-1.4.4.4
-
index fdfbea8..8899ae2 100644 (file)
@@ -57,62 +57,3 @@ index 1eab1af..2df75f0 100644
 -- 
 1.4.4.4
 
-From 24813da9b0aac0e92635d7307837d89a9f4a1ee7 Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Fri, 19 Oct 2007 16:47:15 +0400
-Subject: [PATCH] tosa-power-r18.patch fixes
-
----
- arch/arm/mach-pxa/tosa_pm.c |    9 +++++----
- 1 files changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/arch/arm/mach-pxa/tosa_pm.c b/arch/arm/mach-pxa/tosa_pm.c
-index 1eab1af..2df75f0 100644
---- a/arch/arm/mach-pxa/tosa_pm.c
-+++ b/arch/arm/mach-pxa/tosa_pm.c
-@@ -17,9 +17,9 @@
- #include <linux/interrupt.h>
- #include <linux/platform_device.h>
- #include <linux/pm.h>
-+#include <linux/apm-emulation.h>
- #include <linux/wm97xx.h>
--#include <asm/apm.h>
- #include <asm/irq.h>
- #include <asm/mach-types.h>
- #include <asm/hardware.h>
-@@ -144,7 +144,7 @@ static int tosa_ac97_init(void)
-       pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
-       pxa_gpio_mode(GPIO20_DREQ0_MD);
-       
--      pxa_set_cken(CKEN2_AC97, 1);
-+      pxa_set_cken(CKEN_AC97, 1);
-       /* AC97 power on sequense */
-       while ( 1 ) {
-               GCR = 0;
-@@ -184,11 +184,12 @@ static int tosa_ac97_init(void)
-       pxa_gpio_mode(GPIO32_SDATA_IN1_AC97_MD);
-       ad_polling = 1;
-       printk("tosa_ac97_init\n");
-+      return 0;
- }
- void tosa_ac97_exit(void)
- {
--      if (!(CKEN & CKEN2_AC97))
-+      if (!(CKEN & CKEN_AC97))
-               return;
-       
-       // power down the whole chip
-@@ -197,7 +198,7 @@ void tosa_ac97_exit(void)
- //       GCR &= ~(GCR_CDONE_IE | GCR_SDONE_IE | GCR_SECRDY_IEN | GCR_PRIRDY_IEN | GCR_SECRES_IEN | GCR_PRIRES_IEN);
- //        GSR = GSR;
- //    GCR = GCR_ACLINK_OFF;
--      pxa_set_cken(CKEN2_AC97, 0);
-+      pxa_set_cken(CKEN_AC97, 0);
-       /* switch back to irq driver */
-       ad_polling = 0;
-       printk("tosa_ac97_exit\n");
--- 
-1.4.4.4
-
index a099717..ca703cb 100644 (file)
@@ -689,694 +689,3 @@ Index: linux-2.6.17/arch/arm/mach-pxa/Kconfig
  
  config PXA25x
        bool
-Index: linux-2.6.17/arch/arm/mach-pxa/Makefile
-===================================================================
---- linux-2.6.17.orig/arch/arm/mach-pxa/Makefile       2006-09-19 20:51:33.984424500 +0200
-+++ linux-2.6.17/arch/arm/mach-pxa/Makefile    2006-09-19 21:08:04.922354250 +0200
-@@ -16,7 +16,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
-+obj-$(CONFIG_MACH_TOSA)         += tosa.o sharpsl_pm.o tosa_pm.o
- obj-$(CONFIG_MACH_EM_X270) += em-x270.o
- obj-$(CONFIG_MACH_HX2750)     += hx2750.o hx2750_test.o
-Index: linux-2.6.17/arch/arm/mach-pxa/tosa_pm.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/arch/arm/mach-pxa/tosa_pm.c   2006-09-19 21:08:34.476201250 +0200
-@@ -0,0 +1,661 @@
-+/*
-+ * Battery and Power Management code for the Sharp SL-6000x
-+ *
-+ * 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/stat.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm.h>
-+#include <linux/wm97xx.h>
-+
-+#include <asm/apm.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/hardware/scoop.h>
-+#include <asm/hardware/tmio.h>
-+
-+#include <asm/arch/sharpsl.h>
-+#include <asm/arch/tosa.h>
-+#include <asm/arch/pxa-regs.h>
-+#include <sound/soc.h>
-+#include <sound/ac97_codec.h>
-+#include "sharpsl.h"
-+
-+extern int tosa_bl_intensity(void);
-+volatile static int ad_polling;
-+static int tosa_pm_driver_probe(struct device *dev);
-+static int tosa_pm_driver_remove(struct device *dev);
-+static struct wm97xx *wm9712;
-+
-+/************************************************************
-+ * AC97 functions
-+ ************************************************************/
-+#define AC97_TIMEOUT_VAL      0x1000000
-+
-+#define AC97_MISC_MODEM_STAT  0x0056
-+#define AC97_GPIO_CONFIG      0x004C
-+
-+static u16 tosa_ac97_read(unsigned short reg)
-+{
-+      volatile u32 *reg_addr;
-+      volatile int timeout;
-+      unsigned short data;
-+
-+      if (CAR & CAR_CAIP) {
-+              printk(KERN_CRIT ": CAR_CAIP already set\n");
-+              return 0;       
-+      }
-+
-+      if (reg == AC97_GPIO_STATUS)
-+              reg_addr = &PMC_REG_BASE;
-+      else
-+              reg_addr = &PAC_REG_BASE;
-+
-+      reg_addr += (reg >> 1);
-+
-+      data=0;
-+      GSR = GSR_CDONE | GSR_SDONE;
-+
-+      data = *reg_addr;
-+      timeout = 0;
-+
-+      while(((GSR & GSR_SDONE)) == 0 && (timeout++ < AC97_TIMEOUT_VAL));
-+
-+      if ((timeout >= AC97_TIMEOUT_VAL)) {
-+              GSR = GSR;
-+              printk(KERN_CRIT ": AC97 is busy1.\n");
-+              return data;
-+      }
-+
-+      // actual read
-+      GSR = GSR_CDONE | GSR_SDONE;
-+      data = *reg_addr;
-+
-+      timeout = 0;
-+      while(((GSR & GSR_SDONE) == 0) && (timeout++<AC97_TIMEOUT_VAL));
-+      if ((timeout >= AC97_TIMEOUT_VAL)) {
-+              GSR = GSR;
-+              printk(KERN_CRIT ": AC97 is busy2.\n");
-+              return data;
-+      }
-+
-+      return data;
-+}
-+
-+static void tosa_ac97_write(unsigned short reg, unsigned short val)
-+{
-+      volatile u32 *reg_addr;
-+      volatile int timeout=0;
-+
-+      if (CAR & CAR_CAIP) {
-+              printk(KERN_CRIT ": CAR_CAIP already set\n");
-+              return; 
-+      }
-+
-+      GSR = GSR_CDONE | GSR_SDONE;
-+      if (reg == AC97_GPIO_STATUS)
-+              reg_addr = &PMC_REG_BASE;
-+      else
-+              reg_addr = &PAC_REG_BASE;
-+
-+      reg_addr += (reg >> 1);
-+
-+      *reg_addr = val;
-+      while(((GSR & GSR_CDONE) == 0) && (timeout++ < AC97_TIMEOUT_VAL));
-+      if (timeout >= AC97_TIMEOUT_VAL) {
-+              printk(KERN_CRIT ": AC97 is busy.\n");
-+      }
-+}
-+
-+static void tosa_ac97_bit_clear(u8 reg, u16 val)
-+{
-+      unsigned short dat = tosa_ac97_read(reg);
-+      dat &= ~val;
-+      tosa_ac97_write(reg, dat);
-+}
-+
-+static void tosa_ac97_bit_set(u8 reg, u16 val)
-+{
-+      unsigned short dat = tosa_ac97_read(reg);
-+      dat |= val;
-+      tosa_ac97_write(reg, dat);
-+}
-+
-+
-+static int tosa_ac97_init(void)
-+{
-+      int timeo;
-+      
-+      pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
-+      pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
-+      pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
-+      pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
-+      pxa_gpio_mode(GPIO20_DREQ0_MD);
-+      
-+      pxa_set_cken(CKEN2_AC97, 1);
-+      /* AC97 power on sequense */
-+      while ( 1 ) {
-+              GCR = 0;
-+              udelay(100);
-+              GCR |= GCR_COLD_RST;
-+              udelay(5);
-+              GCR |= GCR_WARM_RST;
-+              udelay(5);
-+              for ( timeo = 0x10000; timeo > 0; timeo-- ) {
-+                      if ( GSR & GSR_PCR ) break;
-+                      mdelay(5);
-+              }
-+              if( timeo > 0 ) break;
-+              printk(KERN_WARNING "AC97 power on retry!!\n");
-+      }
-+
-+      tosa_ac97_write(AC97_EXTENDED_STATUS, 1);
-+      /*
-+      * Setting AC97 GPIO
-+      *       i/o     function
-+      *       GPIO1:   input   EAR_IN signal
-+      *       GPIO2:   output  IRQ signal
-+      *       GPIO3:   output  PENDOWN signal
-+      *       GPIO4:   input   MASK signal
-+      *       GPIO5:   input   DETECT MIC signal
-+      */                      
-+      //     AC97_GPIO_FUNC AC97_MISC_MODEM_STAT
-+
-+      tosa_ac97_bit_clear(AC97_MISC_MODEM_STAT,
-+                      ((1<<2)|(1<<3)|(1<<4)|(1<<5)));
-+      tosa_ac97_bit_clear(AC97_GPIO_CONFIG,(1<<2)|(1<<3));
-+      tosa_ac97_bit_set(AC97_GPIO_CONFIG, (1<<1)|(1<<4)|(1<<5));
-+
-+      tosa_ac97_write(AC97_WM97XX_DIGITISER2, 0xc009);
-+      tosa_ac97_write(AC97_WM97XX_DIGITISER1, 0x0030 | WM97XX_DELAY(4));
-+
-+      pxa_gpio_mode(GPIO32_SDATA_IN1_AC97_MD);
-+      ad_polling = 1;
-+      printk("tosa_ac97_init\n");
-+}
-+
-+void tosa_ac97_exit(void)
-+{
-+      if (!(CKEN & CKEN2_AC97))
-+              return;
-+      
-+      // power down the whole chip
-+      tosa_ac97_write(AC97_POWERDOWN, 0x7fff);
-+
-+//       GCR &= ~(GCR_CDONE_IE | GCR_SDONE_IE | GCR_SECRDY_IEN | GCR_PRIRDY_IEN | GCR_SECRES_IEN | GCR_PRIRES_IEN);
-+//        GSR = GSR;
-+//    GCR = GCR_ACLINK_OFF;
-+      pxa_set_cken(CKEN2_AC97, 0);
-+      /* switch back to irq driver */
-+      ad_polling = 0;
-+      printk("tosa_ac97_exit\n");
-+}
-+
-+int ac97_ad_input(u16 adcsel)
-+{
-+      unsigned short val = 0;
-+      unsigned long timeout;
-+
-+      // prepare
-+      tosa_ac97_read(AC97_WM97XX_DIGITISER_RD);
-+      
-+      if (adcsel & 0x8000)
-+              adcsel = ((adcsel & 0x7fff) + 3) << 12;
-+              
-+      /* Conversion start */
-+      tosa_ac97_write(AC97_WM97XX_DIGITISER1, (adcsel | WM97XX_POLL |  WM97XX_DELAY(4)));
-+      timeout = 0x1000;
-+      /* wait for POLL to go low */
-+      while ((tosa_ac97_read(AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
-+              udelay(100);
-+              timeout--;
-+      }
-+
-+      val = tosa_ac97_read(AC97_WM97XX_DIGITISER_RD);
-+      
-+      val &= 0xFFF ;
-+  
-+      return val;
-+}
-+
-+
-+int tosa_read_aux_adc(u16 adcsel)  
-+{
-+      if (ad_polling)
-+              return (ac97_ad_input(adcsel));
-+      else
-+              return (wm97xx_read_aux_adc(wm9712, adcsel));
-+}
-+
-+static struct device_driver tosa_pm_driver = {
-+    .name = "wm97xx-battery",
-+    .bus = &wm97xx_bus_type,
-+    .owner = THIS_MODULE,
-+    .probe = tosa_pm_driver_probe,
-+    .remove = tosa_pm_driver_remove,
-+};
-+
-+#if 0
-+#define TOSA_TEMP_READ_WAIT_TIME              (5)    // 5msec [Fix]
-+int tosa_read_battery(struct wm97xx* wm, int channel)
-+{
-+      //return sprintf(buf, "%d\n", wm97xx_read_aux_adc(wm, input));
-+
-+      int wm_aux,i;
-+      int value = 0;
-+      int clear_mux;
-+
-+      switch(channel) {
-+
-+              case 0: // Main
-+
-+                      set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON);
-+                      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_V_ON | TOSA_TC6393_BAT_SW_ON);
-+                      wm_aux = WM97XX_AUX_ID3;
-+                      break;
-+
-+              case 1: // Jacket
-+
-+                      set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_V_ON);
-+                      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON | TOSA_TC6393_BAT_SW_ON);
-+                      wm_aux = WM97XX_AUX_ID3;
-+                      break;
-+
-+              case 2:  // BU
-+                      set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BU_CHRG_ON);
-+                      wm_aux = WM97XX_AUX_ID4;
-+                      break;
-+
-+              case 3:  // Main Temp
-+                      set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_TH_ON);
-+                      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_TH_ON);
-+                      wm_aux = WM97XX_AUX_ID2;
-+                      break;
-+
-+              case 4:  // Jacket Temp
-+                      set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_TH_ON);
-+                      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_TH_ON);
-+                      wm_aux = WM97XX_AUX_ID2;
-+                      break;
-+
-+              default:
-+                      return -1;
-+      }
-+      
-+      mdelay(TOSA_TEMP_READ_WAIT_TIME);
-+      for(i=0;i<4;i++)
-+      {
-+              if (wm9712)
-+                      value += wm97xx_read_aux_adc(wm, wm_aux);
-+              else
-+                      value += ac97_ad_input(wm, wm_aux);
-+      }
-+
-+      value>>=2;
-+      // reset the multiplexer
-+      clear_mux = TOSA_TC6393_BAT0_V_ON  | TOSA_TC6393_BAT1_V_ON | TOSA_TC6393_BAT_SW_ON | TOSA_TC6393_BAT0_TH_ON | TOSA_TC6393_BAT1_TH_ON | TOSA_TC6393_BU_CHRG_ON;
-+
-+      return value;
-+
-+}
-+#endif
-+
-+/* BL 5-3 */
-+struct battery_thresh tosa_battery_levels_bl[] = {
-+      { 1663, 100 },
-+      { 1605,  75 },
-+      { 1564,  50 },
-+      { 1510,  25 },
-+      { 1435,   5 },
-+      {   0,    0 },
-+};
-+
-+/* BL 2-0 */
-+struct battery_thresh tosa_battery_levels[] = {
-+      { 1679, 100 },
-+      { 1617,  75 },
-+      { 1576,  50 },
-+      { 1530,  25 },
-+      { 1448,   5 },
-+      {   0,    0 },
-+};
-+
-+struct pm_devices {
-+      const char * name;
-+      struct bus_type *bus;
-+      struct device_driver *driver;
-+      struct device * dev;
-+      int (*resume)(struct device *dev, void * data); //      int (*resume)(struct device *dev);
-+      int (*suspend)(struct device *dev, void * data);//      int (*suspend)(struct device *dev, pm_message_t state);
-+};
-+
-+/* Ugly
-+   We need the following devices to measure the battery and control the charger:
-+   Also we need access to these before we sleep and immediatly after we resume so we can't
-+   control their pm via the kernel device manager. To access their pm functions we will backup
-+   the suspend and resume handler and clear these pointers.
-+   After that we can suspend and resume these devices.
-+
-+   Don't change the order of this table!!!!!
-+*/
-+static struct pm_devices dev_table[] = {
-+      [0] = {
-+              .name   = TMIO_SOC_NAME,
-+              .bus    = &platform_bus_type,
-+      },
-+};
-+
-+static int tosa_pm_driver_probe(struct device *dev)
-+{
-+      wm9712 = dev->driver_data;
-+      ad_polling = 0;
-+      return 0;
-+}
-+
-+static int tosa_pm_driver_remove(struct device *dev)
-+{
-+    wm9712 = NULL;
-+    return 0;
-+}
-+
-+
-+static void tosa_charger_init(void)
-+{
-+    int i;
-+
-+    /* If this driver doesn't register, bad things will happen, Tosa won't boot,
-+       and the world will possibly explode */
-+    i = driver_register(&tosa_pm_driver);
-+    if (i < 0)
-+        panic("Cannot register the tosa_pm driver on the wm97xx bus. Halting.");
-+
-+      for(i=0;i<ARRAY_SIZE(dev_table);i++)
-+      {
-+              dev_table[i].driver = driver_find(dev_table[i].name, dev_table[i].bus);
-+              if (dev_table[i].driver)
-+              {
-+                      dev_table[i].resume = dev_table[i].driver->resume;
-+                      dev_table[i].suspend = dev_table[i].driver->suspend;
-+                      dev_table[i].driver->resume = NULL;
-+                      dev_table[i].driver->suspend = NULL;
-+              }
-+      }
-+      
-+      pxa_gpio_mode(TOSA_GPIO_AC_IN | GPIO_IN);
-+      pxa_gpio_mode(TOSA_GPIO_BAT0_CRG | GPIO_IN);
-+      pxa_gpio_mode(TOSA_GPIO_BAT1_CRG | GPIO_IN);
-+      pxa_gpio_mode(TOSA_GPIO_BAT0_LOW | GPIO_IN);
-+      pxa_gpio_mode(TOSA_GPIO_BAT1_LOW | GPIO_IN);
-+
-+      pxa_gpio_mode(TOSA_GPIO_JACKET_DETECT | GPIO_IN);
-+      pxa_gpio_mode(TOSA_GPIO_POWERON | GPIO_IN);
-+      sharpsl_pm_pxa_init();
-+}
-+
-+
-+static void tosa_measure_temp(int on)
-+{
-+      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_TH_ON | TOSA_TC6393_BAT1_TH_ON);
-+
-+      if (on)
-+              set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_TH_ON);
-+
-+}
-+
-+static void tosa_charge(int on)
-+{
-+      if(on)
-+              reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_CHARGE_OFF);
-+      else
-+              set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_CHARGE_OFF);
-+}
-+
-+static void tosa_discharge1(int on)
-+{
-+}
-+
-+static void tosa_discharge(int on)
-+{
-+}
-+
-+
-+static void tosa_presuspend(void)
-+{
-+      int i;
-+      unsigned long wakeup_mask;
-+      
-+      // put remaining devices into sleep
-+      for(i=0;i<ARRAY_SIZE(dev_table);i++)
-+      {
-+              if(dev_table[i].suspend)
-+                      driver_for_each_device(dev_table[i].driver, NULL, 
-+                         (void*)&PMSG_SUSPEND, dev_table[i].suspend);
-+      }
-+      
-+      tosa_ac97_exit();
-+      
-+      wakeup_mask = GPIO_bit(TOSA_GPIO_POWERON) | GPIO_bit(TOSA_GPIO_ON_KEY) | GPIO_bit(TOSA_GPIO_AC_IN);
-+
-+      wakeup_mask |= GPIO_bit(TOSA_GPIO_BAT0_LOW);
-+      PWER = wakeup_mask | PWER_RTC;
-+
-+      PRER = wakeup_mask;
-+      PFER = wakeup_mask;
-+
-+      for (i = 0; i <=15; i++) {
-+              if (PRER & PFER & GPIO_bit(i)) {
-+                      if (GPLR0 & GPIO_bit(i) )
-+                              PRER &= ~GPIO_bit(i);
-+                      else
-+                              PFER &= ~GPIO_bit(i);
-+              }
-+      }
-+      
-+      /* Clear reset status */
-+      RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-+
-+      /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
-+      PCFR = PCFR_OPDE;
-+      
-+      /* Resume on keyboard power key */
-+      PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT);
-+      PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT); 
-+      
-+      GPDR0 = 0xC3810940;
-+      GPDR1 = 0xFCFFAB82;
-+      GPDR2 = 0x000F501f;
-+//    write_scoop_reg(&tosascoop_device.dev,SCOOP_GPWR,0);
-+// only debug
-+reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_NOTE_LED);
-+}
-+
-+void tosa_postsuspend(void)
-+{
-+      int i;
-+// only debug
-+set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_NOTE_LED);
-+
-+      for(i=ARRAY_SIZE(dev_table);i;i--)
-+      {
-+              if(dev_table[i-1].resume)
-+                      driver_for_each_device(dev_table[i-1].driver, NULL, 
-+                         NULL, dev_table[i-1].resume);
-+      }
-+      tosa_ac97_init();
-+      PMCR = 0x01;
-+}
-+
-+void tosa_postresume(void)
-+{
-+      tosa_ac97_exit();
-+}
-+
-+/*
-+ * Check what brought us out of the suspend.
-+ * Return: 0 to sleep, otherwise wake
-+ */
-+static int tosa_should_wakeup(unsigned int resume_on_alarm)
-+{
-+      int is_resume = 0;
-+
-+      dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
-+
-+      if ((PEDR & GPIO_bit(TOSA_GPIO_AC_IN))) {
-+              if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
-+                      /* charge on */
-+                      dev_dbg(sharpsl_pm.dev, "ac insert\n");
-+                      sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
-+              } else {
-+                      /* charge off */
-+                      dev_dbg(sharpsl_pm.dev, "ac remove\n");
-+                      sharpsl_pm_led(SHARPSL_LED_OFF);
-+                      sharpsl_pm.machinfo->charge(0);
-+                      sharpsl_pm.charge_mode = CHRG_OFF;
-+              }
-+      }
-+
-+      if ((PEDR & GPIO_bit(GPIO_bit(TOSA_GPIO_BAT0_CRG))))
-+              dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
-+
-+      if (PEDR & GPIO_bit(TOSA_GPIO_POWERON))
-+              is_resume |= GPIO_bit(TOSA_GPIO_POWERON);
-+
-+      if (PEDR & GPIO_bit(TOSA_GPIO_ON_KEY))
-+              is_resume |= GPIO_bit(TOSA_GPIO_ON_KEY);
-+
-+      if (resume_on_alarm && (PEDR & PWER_RTC))
-+              is_resume |= PWER_RTC;
-+
-+      return is_resume;
-+}
-+
-+static unsigned long tosa_charger_wakeup(void)
-+{
-+//    return ~GPLR0 & ( GPIO_bit(TOSA_GPIO_AC_IN) | GPIO_bit(TOSA_GPIO_POWERON) | GPIO_bit(TOSA_GPIO_ON_KEY) );
-+      return (~GPLR0 & ( GPIO_bit(TOSA_GPIO_POWERON) | GPIO_bit(TOSA_GPIO_ON_KEY) )) | (GPLR0 & GPIO_bit(TOSA_GPIO_AC_IN));
-+}
-+
-+unsigned long tosa_read_bat(void)
-+{
-+      unsigned long value;
-+      reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON | TOSA_TC6393_BAT1_V_ON | TOSA_TC6393_BAT_SW_ON);
-+      mdelay(5);
-+      value = tosa_read_aux_adc(WM97XX_AUX_ID3);
-+      set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON);
-+      return value;
-+}
-+
-+unsigned long tosapm_read_devdata(int type)
-+{
-+      switch(type) {
-+      case SHARPSL_STATUS_ACIN:
-+              return ((GPLR(TOSA_GPIO_AC_IN) & GPIO_bit(TOSA_GPIO_AC_IN)) == 0);              
-+      case SHARPSL_STATUS_LOCK:
-+              return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock);
-+      case SHARPSL_STATUS_CHRGFULL:
-+              return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull);
-+      case SHARPSL_STATUS_FATAL:
-+              return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal);
-+      case SHARPSL_ACIN_VOLT:
-+              return 1000;    // not used on tosa
-+      case SHARPSL_BATT_TEMP:
-+              return tosa_read_aux_adc(WM97XX_AUX_ID2);
-+      case SHARPSL_BATT_VOLT:
-+              return tosa_read_bat();
-+      default:
-+              return tosa_read_bat();
-+      }
-+}
-+
-+static struct sharpsl_charger_machinfo tosa_pm_machinfo = {
-+      .init            = tosa_charger_init,
-+      .exit            = sharpsl_pm_pxa_remove,
-+      .gpio_batlock    = TOSA_GPIO_BAT_LOCKED,
-+      .gpio_acin       = TOSA_GPIO_AC_IN,
-+      .gpio_batfull    = TOSA_GPIO_BAT0_CRG,
-+      .batfull_irq     = 0,
-+      .discharge       = tosa_discharge,
-+      .discharge1      = tosa_discharge1,
-+      .charge          = tosa_charge,
-+      .measure_temp    = tosa_measure_temp,
-+      .presuspend      = tosa_presuspend,
-+      .postsuspend     = tosa_postsuspend,
-+      .postresume      = tosa_postresume,
-+      .read_devdata    = tosapm_read_devdata,
-+      .charger_wakeup  = tosa_charger_wakeup,
-+      .should_wakeup   = tosa_should_wakeup,
-+        .backlight_limit = corgibl_limit_intensity,
-+      .backlight_get_status= tosa_bl_intensity,
-+      .bat_levels      = 6,
-+      .bat_levels_noac = tosa_battery_levels,
-+      .bat_levels_acin = tosa_battery_levels,
-+      .bat_levels_noac_bl = tosa_battery_levels_bl,
-+      .bat_levels_acin_bl = tosa_battery_levels_bl,
-+      .charge_on_volt   = 1200,       // 2.9V TOSA_MAIN_BATTERY_ERR_THRESH voltage < 1200 -> error
-+      .charge_on_temp   = 3600,       // --   TOSA_MAIN_BATTERY_EXIST_THRESH temp > 3600 -> error, no battery
-+      .charge_acin_high = 1500,       // not used default value
-+      .charge_acin_low  = 500,        // not used default value
-+      .fatal_acin_volt  = 1572,       // 3.8V
-+      .fatal_noacin_volt= 1551,       // 3.75V
-+      .status_high_acin = 1564,       // 3.78V
-+      .status_low_acin  = 1510,       // 3.65V
-+      .status_high_noac = 1564,       // 3.78V
-+      .status_low_noac  = 1510,       // 3.65V
-+};
-+
-+static struct platform_device *tosapm_device;
-+
-+static int __devinit tosapm_init(void)
-+{
-+      int ret;
-+
-+      tosapm_device = platform_device_alloc("sharpsl-pm", -1);
-+      if (!tosapm_device)
-+              return -ENOMEM;
-+
-+      tosapm_device->dev.platform_data = &tosa_pm_machinfo;
-+      ret = platform_device_add(tosapm_device);
-+
-+      if (ret)
-+              platform_device_put(tosapm_device);
-+
-+      return ret;
-+}
-+
-+static void tosapm_exit(void)
-+{
-+      int i;
-+
-+      // restore the resume / suspend handler
-+      for(i=0;i<ARRAY_SIZE(dev_table);i++)
-+      {
-+              if (dev_table[i].driver)
-+              {
-+                      dev_table[i].driver->resume = dev_table[i].resume;
-+                      dev_table[i].driver->suspend = dev_table[i].suspend;
-+                      dev_table[i].resume = NULL;
-+                      dev_table[i].suspend = NULL;
-+                      put_driver(dev_table[i].driver);
-+              }
-+      }
-+
-+      if (wm9712)
-+              driver_unregister(&tosa_pm_driver);
-+
-+      platform_device_unregister(tosapm_device);
-+}
-+
-+module_init(tosapm_init);
-+module_exit(tosapm_exit);
-Index: linux-2.6.17/arch/arm/mach-pxa/Kconfig
-===================================================================
---- linux-2.6.17.orig/arch/arm/mach-pxa/Kconfig        2006-09-19 20:51:40.160810500 +0200
-+++ linux-2.6.17/arch/arm/mach-pxa/Kconfig     2006-09-19 21:08:04.926354500 +0200
-@@ -110,6 +110,7 @@ config MACH_TOSA
-       bool "Enable Sharp SL-6000x (Tosa) Support"
-       depends PXA_SHARPSL_25x
-       select TOSHIBA_TC6393XB
-+      select SHARPSL_PM       
- config PXA25x
-       bool
index 6f6f540..9c18aae 100644 (file)
@@ -27,32 +27,3 @@ index 059fa07..61536d4 100644
 -- 
 1.4.4.4
 
-From 005693333f4b3e0495bb80cc3cfd812e3e6f0a30 Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Fri, 19 Oct 2007 00:48:42 +0400
-Subject: [PATCH] tosa-pxaac97-r6.patch fixes
-
----
- arch/arm/mach-pxa/tosa.c |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
-index 059fa07..61536d4 100644
---- a/arch/arm/mach-pxa/tosa.c
-+++ b/arch/arm/mach-pxa/tosa.c
-@@ -310,10 +310,10 @@ static void __init tosa_init(void)
-       PMCR = 0x01;
-         // AC97 Disable all IRQ's
--        pxa_set_cken(CKEN2_AC97, 1);
-+        pxa_set_cken(CKEN_AC97, 1);
-         GCR &= ~(GCR_CDONE_IE | GCR_SDONE_IE | GCR_SECRDY_IEN | GCR_PRIRDY_IEN | GCR_SECRES_IEN | GCR_PRIRES_IEN);
-         GSR = GSR;
--      pxa_set_cken(CKEN2_AC97, 0);
-+      pxa_set_cken(CKEN_AC97, 0);
-                                                                       
-       pxa_set_mci_info(&tosa_mci_platform_data);
-       pxa_set_udc_info(&udc_info);
--- 
-1.4.4.4
-
index 73913bc..a2e2bee 100644 (file)
@@ -33,38 +33,3 @@ index eeeee3e..d52f63f 100644
 -- 
 1.4.4.4
 
-From bb3ed6577c592d86f0976a92978c9454bbdfbe59 Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Fri, 19 Oct 2007 02:01:23 +0400
-Subject: [PATCH] tosa-tmio-lcd-r10.patch fixes
-
----
- arch/arm/mach-pxa/tosa_lcd.c |    5 +++--
- 1 files changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm/mach-pxa/tosa_lcd.c b/arch/arm/mach-pxa/tosa_lcd.c
-index eeeee3e..d52f63f 100644
---- a/arch/arm/mach-pxa/tosa_lcd.c
-+++ b/arch/arm/mach-pxa/tosa_lcd.c
-@@ -66,7 +66,7 @@ static unsigned short normal_i2c[] = {
- };
- I2C_CLIENT_INSMOD;
--static struct corgibl_machinfo tosa_bl_machinfo = {
-+static struct generic_bl_info tosa_bl_machinfo = {
-       .max_intensity = 255,
-       .default_intensity = 68,
-       .limit_mask = 0x0b,
-@@ -80,7 +80,8 @@ int tosa_bl_intensity(void)
- static void pxa_nssp_output(unsigned char reg, unsigned char data)
- {
--      unsigned long flag, dummy;
-+      unsigned long flag;
-+      u32 dummy;
-       u32 dat = ( ((reg << 5) & 0xe0) | (data & 0x1f) );
-       spin_lock_irqsave(&tosa_nssp_lock, flag);
--- 
-1.4.4.4
-
index cd24cc6..fe5c45d 100644 (file)
@@ -382,470 +382,6 @@ Index: git/arch/arm/mach-pxa/tosa.c
        .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
- 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_EM_X270) += em-x270.o
- obj-$(CONFIG_MACH_HX2750)     += hx2750.o hx2750_test.o
-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>
-@@ -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[] = {
 +    {
index 0e32a62..78e81ea 100644 (file)
@@ -38,50 +38,6 @@ Index: git/sound/soc/codecs/wm9712.c
 +
 +      }
  
--err:
-       printk(KERN_ERR "WM9712 AC97 reset failed\n");
-       return -EIO;
- }
- 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;
index cbf854d..5179b47 100644 (file)
@@ -9,22 +9,6 @@ Index: git/sound/soc/codecs/wm9712.c
        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;
- 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){
diff --git a/packages/linux/linux-rp-2.6.23/wm97xx-lcdnoise-r0.patch b/packages/linux/linux-rp-2.6.23/wm97xx-lcdnoise-r0.patch
deleted file mode 100644 (file)
index 191de3a..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-Index: linux-tosa/drivers/input/touchscreen/wm9712.c
-===================================================================
---- linux-tosa.orig/drivers/input/touchscreen/wm9712.c 2006-08-29 16:52:36.008543280 +0100
-+++ linux-tosa/drivers/input/touchscreen/wm9712.c      2006-08-29 16:52:50.923275896 +0100
-@@ -1,7 +1,7 @@
- /*
-  * wm9712.c  --  Codec driver for Wolfson WM9712 AC97 Codecs.
-  *
-- * Copyright 2003, 2004, 2005 Wolfson Microelectronics PLC.
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-  * Author: Liam Girdwood
-  *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-  * Parts Copyright : Ian Molton <spyro@f2s.com>
-@@ -13,6 +13,12 @@
-  *  Free Software Foundation;  either version 2 of the  License, or (at your
-  *  option) any later version.
-  *
-+ *  Revision history
-+ *     4th Jul 2005  Initial version.
-+ *    29th Aug 2006  Mike Arthur <mike@mikearthur.co.uk>
-+ *                   Added fixes for Sharp SL-6000 (Tosa) LCD noise causing
-+ *                   touchscreen interference.
-+ *
-  */
- #include <linux/module.h>
-@@ -28,6 +34,10 @@
- #define WM9705_VERSION                "0.60"
- #define DEFAULT_PRESSURE      0xb0c0
-+#define CCNT(a)     asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
-+#define CCNT_ON()   asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
-+#define CCNT_OFF()  asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
-+
- /*
-  * Debug
-  */
-@@ -243,6 +253,36 @@
-       return wm->dig[2] & WM9712_PDEN;
- }
-+
-+#ifdef CONFIG_MACH_TOSA
-+/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
-+ * before sampling the Y axis of the touchscreen */
-+static inline void wm9712_lcd_sync_on(struct wm97xx* wm, int adcsel) {
-+    unsigned long timer1 = 0, timer2 = 0, wait_time = 0;
-+    if (adcsel == WM97XX_ADCSEL_Y) {
-+        wait_time = wm97xx_calc_lcd_waittime(wm);
-+
-+        CCNT_ON();
-+
-+        if (wait_time) {
-+            /* wait for LCD rising edge */
-+            wm_machinfo->wait_hsync();
-+            /* get clock */
-+            CCNT(timer1);
-+            CCNT(timer2);
-+
-+            while ((timer2 - timer1) < wait_time) {
-+                CCNT(timer2);
-+            }
-+        }
-+    }
-+}
-+
-+static inline void wm9712_lcd_sync_off(void) {
-+    CCNT_OFF();
-+}
-+#endif
-+
- /*
-  * Read a sample from the WM9712 adc in polling mode.
-  */
-@@ -260,6 +300,9 @@
-       /* set up digitiser */
-       if (adcsel & 0x8000)
-               adcsel = ((adcsel & 0x7fff) + 3) << 12;
-+    #ifdef CONFIG_MACH_TOSA
-+    wm9712_lcd_sync_on(wm, adcsel);
-+    #endif
-       wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
-       
-       /* wait 3 AC97 time slots + delay for conversion */
-@@ -282,6 +325,10 @@
-       
-       *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-       
-+    #ifdef CONFIG_MACH_TOSA
-+    wm9712_lcd_sync_off();
-+    #endif
-+
-       /* check we have correct sample */
-       if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
-               dbg ("adc wrong sample, read %x got %x", adcsel,
-@@ -303,11 +350,12 @@
- static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
- {
-       int rc;
--      
-       if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
-               return rc;
-+
-       if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
-               return rc;
-+
-       if (pil && !five_wire) {
-               if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
-                       return rc;
-Index: linux-tosa/drivers/input/touchscreen/wm97xx-core.c
-===================================================================
---- linux-tosa.orig/drivers/input/touchscreen/wm97xx-core.c    2006-08-29 16:52:36.008543280 +0100
-+++ linux-tosa/drivers/input/touchscreen/wm97xx-core.c 2006-08-29 16:52:50.924275744 +0100
-@@ -2,7 +2,7 @@
-  * wm97xx-core.c  --  Touch screen driver core for Wolfson WM9705, WM9712
-  *                           and WM9713 AC97 Codecs.
-  *
-- * Copyright 2003, 2004, 2005 Wolfson Microelectronics PLC.
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-  * Author: Liam Girdwood
-  *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-  * Parts Copyright : Ian Molton <spyro@f2s.com>
-@@ -67,6 +67,9 @@
-  *                   GPIOs) and 2.6 power management. 
-  *    29th Nov 2004  Added WM9713 support.
-  *     4th Jul 2005  Moved codec specific code out to seperate files.
-+ *    29th Aug 2006  Mike Arthur <mike@mikearthur.co.uk>
-+ *                   Added fixes for Sharp SL-6000 (Tosa) LCD noise causing
-+ *                   touchscreen interference.
-  */  
-     
- #include <linux/module.h>
-@@ -94,6 +97,7 @@
- static DECLARE_MUTEX(gpio_sem);
- static LIST_HEAD(wm97xx_misc_list);
- static struct wm97xx* wm_codec = NULL;
-+struct wm97xx_machinfo *wm_machinfo;
- /*
-  * WM97xx - enable/disable AUX ADC sysfs 
-@@ -832,6 +836,23 @@
-               mdev->remove(wm_codec);
- }
-+#ifdef CONFIG_MACH_TOSA
-+/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
-+ * before sampling the Y axis of the touchscreen */
-+unsigned long wm97xx_calc_lcd_waittime(struct wm97xx *wm) {
-+    unsigned long hsync_time = wm_machinfo->get_hsync_time();
-+    return hsync_time;
-+}
-+
-+void wm97xx_set_machinfo(struct wm97xx_machinfo *machinfo) {
-+    wm_machinfo = machinfo;
-+}
-+
-+void wm97xx_unset_machinfo() {
-+    wm_machinfo = NULL;
-+}
-+#endif
-+
- static struct device_driver wm97xx_driver = {
-       .name =         "ac97", 
-       .bus =          &ac97_bus_type, 
-@@ -861,6 +882,9 @@
- EXPORT_SYMBOL_GPL(wm97xx_reg_write);
- EXPORT_SYMBOL_GPL(wm97xx_register_misc_dev);
- EXPORT_SYMBOL_GPL(wm97xx_unregister_misc_dev);
-+EXPORT_SYMBOL_GPL(wm97xx_calc_lcd_waittime);
-+EXPORT_SYMBOL_GPL(wm97xx_set_machinfo);
-+EXPORT_SYMBOL_GPL(wm97xx_unset_machinfo);
- module_init(wm97xx_init); 
- module_exit(wm97xx_exit);
-Index: linux-tosa/include/linux/wm97xx.h
-===================================================================
---- linux-tosa.orig/include/linux/wm97xx.h     2006-08-29 16:52:36.008543280 +0100
-+++ linux-tosa/include/linux/wm97xx.h  2006-08-29 16:52:50.924275744 +0100
-@@ -207,6 +207,7 @@
- struct wm97xx;
- extern struct wm97xx_codec_drv wm97xx_codec;
-+extern struct wm97xx_machinfo *wm_machinfo;
- /*
-  * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs
-@@ -253,6 +254,11 @@
-       struct list_head list;
- };
-+struct wm97xx_machinfo {
-+    unsigned long (*get_hsync_time)(void);
-+    void (*wait_hsync)(void);
-+};
-+
- int wm97xx_register_misc_dev(struct wm97xx_misc_dev* mdev);
- void wm97xx_unregister_misc_dev(struct wm97xx_misc_dev* mdev);
-@@ -281,4 +287,9 @@
- int wm97xx_acc_startup(struct wm97xx* wm);
- void wm97xx_acc_shutdown(struct wm97xx* wm);
-+
-+unsigned long wm97xx_calc_lcd_waittime(struct wm97xx *wm);
-+void wm97xx_set_machinfo(struct wm97xx_machinfo *machinfo);
-+void wm97xx_unset_machinfo(void);
-+
- #endif
index f246fbf..5ad0d87 100644 (file)
@@ -108,134 +108,6 @@ index 9b2710e..d3ce3f3 100644
                return -EINVAL;
        }
  
--      if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) {
-+      if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, "wm97xx-pen", wm)) {
-               err("could not register codec pen down interrupt, will poll for pen down");
-               destroy_workqueue(wm->pen_irq_workq);
-               wm->pen_irq = 0;
-diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h
-index b1c1740..a9bd57e 100644
---- a/include/linux/wm97xx.h
-+++ b/include/linux/wm97xx.h
-@@ -243,7 +243,7 @@ struct wm97xx {
-       u16 dig_save[3];                /* saved during aux reading */
-       struct wm97xx_codec_drv *codec; /* attached codec driver*/
-       struct input_dev* input_dev;    /* touchscreen input device */
--      ac97_t *ac97;                   /* ALSA codec access */
-+      struct snd_ac97 *ac97;                  /* ALSA codec access */
-       struct device *dev;             /* ALSA device */
-     struct device *battery_dev;
-     struct device *touch_dev;
- drivers/input/power.c                   |    2 +-
- drivers/input/touchscreen/Kconfig       |    2 +-
- drivers/input/touchscreen/wm97xx-core.c |   35 ++++++++++++++++---------------
- include/linux/wm97xx.h                  |    2 +-
- 4 files changed, 21 insertions(+), 20 deletions(-)
-
-diff --git a/drivers/input/power.c b/drivers/input/power.c
-index 4443e34..7aac875 100644
---- a/drivers/input/power.c
-+++ b/drivers/input/power.c
-@@ -156,7 +156,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
-       }
- }
--static struct input_handle *power_connect(struct input_handler *handler,
-+static int power_connect(struct input_handler *handler,
-                                         struct input_dev *dev,
-                                         const struct input_device_id *id)
- {
-diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
-index 6862e8f..9b532e9 100644
---- a/drivers/input/touchscreen/Kconfig
-+++ b/drivers/input/touchscreen/Kconfig
-@@ -247,7 +247,7 @@ config TOUCHSCREEN_TSC2101
- config TOUCHSCREEN_WM97XX
-       tristate "Support for WM97xx AC97 touchscreen controllers"
--      depends SND_AC97_BUS
-+      depends AC97_BUS
- choice
-       prompt "WM97xx codec type"
-diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
-index 9b2710e..d3ce3f3 100644
---- a/drivers/input/touchscreen/wm97xx-core.c
-+++ b/drivers/input/touchscreen/wm97xx-core.c
-@@ -84,6 +84,7 @@
- #include <linux/bitops.h>
- #include <linux/workqueue.h>
- #include <linux/device.h>
-+#include <linux/freezer.h>
- #include <linux/wm97xx.h>
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -241,14 +242,15 @@ WM97XX_STATUS_ATTR(gpio);
- static int wm97xx_sys_add(struct device *dev)
- {
-+      int err;
-       if (aux_sys) {
--              device_create_file(dev, &dev_attr_aux1);
--              device_create_file(dev, &dev_attr_aux2);
--              device_create_file(dev, &dev_attr_aux3);
--              device_create_file(dev, &dev_attr_aux4);
-+              err = device_create_file(dev, &dev_attr_aux1);    
-+              err = device_create_file(dev, &dev_attr_aux2);
-+              err = device_create_file(dev, &dev_attr_aux3);
-+              err = device_create_file(dev, &dev_attr_aux4);
-       }
-       if (status_sys)
--              device_create_file(dev, &dev_attr_gpio);
-+              err = device_create_file(dev, &dev_attr_gpio);
-       return 0;
- }
-@@ -366,12 +368,12 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, wm97xx_gpio_dir_t dir,
- /*
-  * Handle a pen down interrupt.
-- */
--static void wm97xx_pen_irq_worker(void *ptr)
--{
--      struct wm97xx *wm = (struct wm97xx *) ptr;
--
--      /* do we need to enable the touch panel reader */
-+ */ 
-+static void wm97xx_pen_irq_worker(struct work_struct *work) 
-+{                  
-+      struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work);
-+      
-+      /* do we need to enable the touch panel reader */ 
-       if (wm->id == WM9705_ID2) {
-               if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & WM97XX_PEN_DOWN)
-                       wm->pen_is_down = 1;
-@@ -411,9 +413,8 @@ static void wm97xx_pen_irq_worker(void *ptr)
-  * We have to disable the codec interrupt in the handler because it can
-  * take upto 1ms to clear the interrupt source. The interrupt is then enabled
-  * again in the slow handler when the source has been cleared.
-- */
--static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id,
--                                      struct pt_regs *regs)
-+ */ 
-+static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id)
- {
-       struct wm97xx *wm = (struct wm97xx *) dev_id;
-       disable_irq(wm->pen_irq);
-@@ -428,15 +429,15 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm)
- {
-       u16 reg;
--      INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker, wm);
--      if ((wm->pen_irq_workq =
-+      INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker);
-+      if ((wm->pen_irq_workq = 
-               create_singlethread_workqueue("kwm97pen")) == NULL) {
-               err("could not create pen irq work queue");
-               wm->pen_irq = 0;
-               return -EINVAL;
-       }
 -      if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) {
 +      if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, "wm97xx-pen", wm)) {
                err("could not register codec pen down interrupt, will poll for pen down");
index b029ccc..c918c5d 100644 (file)
@@ -2897,2902 +2897,3 @@ Index: linux-2.6.17/include/linux/wm97xx.h
 +
 +extern struct bus_type wm97xx_bus_type;
 +#endif
-Index: linux-2.6.17/drivers/input/touchscreen/Kconfig
-===================================================================
---- linux-2.6.17.orig/drivers/input/touchscreen/Kconfig        2006-09-19 20:35:35.060495500 +0200
-+++ linux-2.6.17/drivers/input/touchscreen/Kconfig     2006-09-19 20:36:47.965051750 +0200
-@@ -121,4 +121,57 @@ config TOUCHSCREEN_TSC2101
-         To compile this driver as a module, choose M here: the
-         module will be called ads7846_ts.
-+config TOUCHSCREEN_WM97XX
-+      tristate "Support for WM97xx AC97 touchscreen controllers"
-+      depends SND_AC97_BUS
-+
-+choice
-+      prompt "WM97xx codec type"
-+
-+config TOUCHSCREEN_WM9705
-+      bool "WM9705 Touchscreen interface support"
-+      depends on TOUCHSCREEN_WM97XX
-+      help
-+        Say Y here if you have the wm9705 touchscreen.
-+
-+        If unsure, say N.
-+
-+        To compile this driver as a module, choose M here: the
-+        module will be called wm9705.
-+
-+config TOUCHSCREEN_WM9712
-+      bool "WM9712 Touchscreen interface support"
-+      depends on TOUCHSCREEN_WM97XX
-+      help
-+        Say Y here if you have the wm9712 touchscreen.
-+
-+        If unsure, say N.
-+
-+        To compile this driver as a module, choose M here: the
-+        module will be called wm9712.
-+
-+config TOUCHSCREEN_WM9713
-+      bool "WM9713 Touchscreen interface support"
-+      depends on TOUCHSCREEN_WM97XX
-+      help
-+        Say Y here if you have the wm9713 touchscreen.
-+
-+        If unsure, say N.
-+
-+        To compile this driver as a module, choose M here: the
-+        module will be called wm9713.
-+
-+endchoice
-+
-+config TOUCHSCREEN_WM97XX_PXA
-+      tristate "WM97xx PXA accelerated touch"
-+      depends on TOUCHSCREEN_WM97XX && ARCH_PXA
-+      help
-+        Say Y here for continuous mode touch on the PXA
-+
-+        If unsure, say N
-+
-+        To compile this driver as a module, choose M here: the
-+        module will be called pxa-wm97xx
-+
- endif
-Index: linux-2.6.17/drivers/input/touchscreen/Makefile
-===================================================================
---- linux-2.6.17.orig/drivers/input/touchscreen/Makefile       2006-09-19 20:35:35.072496250 +0200
-+++ linux-2.6.17/drivers/input/touchscreen/Makefile    2006-09-19 20:37:40.540337500 +0200
-@@ -4,6 +4,8 @@
- # Each configuration option enables a list of files.
-+wm97xx-ts-objs := wm97xx-core.o
-+
- obj-$(CONFIG_TOUCHSCREEN_ADS7846)     += ads7846.o
- obj-$(CONFIG_TOUCHSCREEN_BITSY)       += h3600_ts_input.o
- obj-$(CONFIG_TOUCHSCREEN_CORGI)       += corgi_ts.o
-@@ -13,3 +15,16 @@ obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtou
- obj-$(CONFIG_TOUCHSCREEN_MK712)       += mk712.o
- obj-$(CONFIG_TOUCHSCREEN_HP600)       += hp680_ts_input.o
- obj-$(CONFIG_TOUCHSCREEN_TSC2101)     += tsc2101_ts.o
-+obj-$(CONFIG_TOUCHSCREEN_WM97XX)      += wm97xx-ts.o
-+obj-$(CONFIG_TOUCHSCREEN_WM97XX_PXA)    += pxa-wm97xx.o
-+
-+ifeq ($(CONFIG_TOUCHSCREEN_WM9713),y)
-+wm97xx-ts-objs += wm9713.o
-+endif
-+
-+ifeq ($(CONFIG_TOUCHSCREEN_WM9712),y)
-+wm97xx-ts-objs += wm9712.o
-+endif
-+ifeq ($(CONFIG_TOUCHSCREEN_WM9705),y)
-+wm97xx-ts-objs += wm9705.o
-+endif
-Index: linux-2.6.17/drivers/input/touchscreen/pxa-wm97xx.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/drivers/input/touchscreen/pxa-wm97xx.c        2006-09-19 20:36:47.965051750 +0200
-@@ -0,0 +1,289 @@
-+/*
-+ * pxa-wm97xx.c  --  pxa-wm97xx Continuous Touch screen driver for
-+ *                   Wolfson WM97xx AC97 Codecs.
-+ *
-+ * Copyright 2004 Wolfson Microelectronics PLC.
-+ * Author: Liam Girdwood
-+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-+ * Parts Copyright : Ian Molton <spyro@f2s.com>
-+ *                   Andrew Zabolotny <zap@homelink.ru>
-+ *
-+ *  This program is free software; you can redistribute  it and/or modify it
-+ *  under  the terms of  the GNU General  Public License as published by the
-+ *  Free Software Foundation;  either version 2 of the  License, or (at your
-+ *  option) any later version.
-+ *
-+ * Notes:
-+ *     This is a wm97xx extended touch driver to capture touch
-+ *     data in a continuous manner on the Intel XScale archictecture
-+ *
-+ *  Features:
-+ *       - codecs supported:- WM9705, WM9712, WM9713
-+ *       - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
-+ *
-+ *  Revision history
-+ *    18th Aug 2004   Initial version.
-+ *    26th Jul 2005   Improved continous read back and added FIFO flushing.
-+ *    06th Sep 2005   Mike Arthur <linux@wolfsonmicro.com>
-+ *                    Moved to using the wm97xx bus
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/irq.h>
-+#include <linux/wm97xx.h>
-+#include <asm/io.h>
-+#include <asm/arch/pxa-regs.h>
-+
-+#define VERSION               "0.13"
-+
-+struct continuous {
-+      u16 id;    /* codec id */
-+      u8 code;   /* continuous code */
-+      u8 reads;  /* number of coord reads per read cycle */
-+      u32 speed; /* number of coords per second */
-+};
-+
-+#define WM_READS(sp) ((sp / HZ) + 1)
-+
-+static const struct continuous cinfo[] = {
-+      {WM9705_ID2, 0, WM_READS(94), 94},
-+      {WM9705_ID2, 1, WM_READS(188), 188},
-+      {WM9705_ID2, 2, WM_READS(375), 375},
-+      {WM9705_ID2, 3, WM_READS(750), 750},
-+      {WM9712_ID2, 0, WM_READS(94), 94},
-+      {WM9712_ID2, 1, WM_READS(188), 188},
-+      {WM9712_ID2, 2, WM_READS(375), 375},
-+      {WM9712_ID2, 3, WM_READS(750), 750},
-+      {WM9713_ID2, 0, WM_READS(94), 94},
-+      {WM9713_ID2, 1, WM_READS(120), 120},
-+      {WM9713_ID2, 2, WM_READS(154), 154},
-+      {WM9713_ID2, 3, WM_READS(188), 188},
-+};
-+
-+/* continuous speed index */
-+static int sp_idx = 0;
-+static u16 last = 0, tries = 0;
-+
-+/*
-+ * Pen sampling frequency (Hz) in continuous mode.
-+ */
-+static int cont_rate = 200;
-+module_param(cont_rate, int, 0);
-+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
-+
-+/*
-+ * Pen down detection.
-+ *
-+ * This driver can either poll or use an interrupt to indicate a pen down
-+ * event. If the irq request fails then it will fall back to polling mode.
-+ */
-+static int pen_int = 1;
-+module_param(pen_int, int, 0);
-+MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
-+
-+/*
-+ * Pressure readback.
-+ *
-+ * Set to 1 to read back pen down pressure
-+ */
-+static int pressure = 0;
-+module_param(pressure, int, 0);
-+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
-+
-+/*
-+ * AC97 touch data slot.
-+ *
-+ * Touch screen readback data ac97 slot
-+ */
-+static int ac97_touch_slot = 5;
-+module_param(ac97_touch_slot, int, 0);
-+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
-+
-+
-+/* flush AC97 slot 5 FIFO on pxa machines */
-+#ifdef CONFIG_PXA27x
-+void wm97xx_acc_pen_up (struct wm97xx* wm)
-+{
-+      set_current_state(TASK_INTERRUPTIBLE);
-+      schedule_timeout(1);
-+
-+      while (MISR & (1 << 2))
-+              MODR;
-+}
-+#else
-+void wm97xx_acc_pen_up (struct wm97xx* wm)
-+{
-+      int count = 16;
-+      set_current_state(TASK_INTERRUPTIBLE);
-+      schedule_timeout(1);
-+
-+      while (count < 16) {
-+              MODR;
-+              count--;
-+      }
-+}
-+#endif
-+
-+int wm97xx_acc_pen_down (struct wm97xx* wm)
-+{
-+      u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
-+      int reads = 0;
-+
-+      /* data is never immediately available after pen down irq */
-+      set_current_state(TASK_INTERRUPTIBLE);
-+      schedule_timeout(1);
-+
-+      if (tries > 5){
-+              tries = 0;
-+              return RC_PENUP;
-+      }
-+
-+      x = MODR;
-+      if (x == last) {
-+              tries++;
-+              return RC_AGAIN;
-+      }
-+      last = x;
-+      do {
-+              if (reads)
-+                      x= MODR;
-+              y= MODR;
-+              if (pressure)
-+                      p = MODR;
-+
-+              /* are samples valid */
-+              if ((x & 0x7000) != WM97XX_ADCSEL_X ||
-+                      (y & 0x7000) != WM97XX_ADCSEL_Y ||
-+                      (p & 0x7000) != WM97XX_ADCSEL_PRES)
-+                      goto up;
-+
-+              /* coordinate is good */
-+              tries = 0;
-+              //printk("x %x y %x p %x\n", x,y,p);
-+              input_report_abs (wm->input_dev, ABS_X, x & 0xfff);
-+              input_report_abs (wm->input_dev, ABS_Y, y & 0xfff);
-+              input_report_abs (wm->input_dev, ABS_PRESSURE, p & 0xfff);
-+              input_sync (wm->input_dev);
-+              reads++;
-+      } while (reads < cinfo[sp_idx].reads);
-+up:
-+      return RC_PENDOWN | RC_AGAIN;
-+}
-+
-+int wm97xx_acc_startup(struct wm97xx* wm)
-+{
-+      int idx = 0;
-+
-+      /* check we have a codec */
-+      if (wm->ac97 == NULL)
-+              return -ENODEV;
-+
-+      /* Go you big red fire engine */
-+      for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
-+              if (wm->id != cinfo[idx].id)
-+                      continue;
-+              sp_idx = idx;
-+              if (cont_rate <= cinfo[idx].speed)
-+                      break;
-+      }
-+      wm->acc_rate = cinfo[sp_idx].code;
-+      wm->acc_slot = ac97_touch_slot;
-+      printk(KERN_INFO "pxa2xx accelerated touchscreen driver, %d samples (sec)\n",
-+              cinfo[sp_idx].speed);
-+
-+      /* codec specific irq config */
-+      if (pen_int) {
-+              switch (wm->id) {
-+                      case WM9705_ID2:
-+                              wm->pen_irq = IRQ_GPIO(4);
-+                              set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE);
-+                              break;
-+                      case WM9712_ID2:
-+                      case WM9713_ID2:
-+                              /* enable pen down interrupt */
-+                              /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
-+                              wm->pen_irq = MAINSTONE_AC97_IRQ;
-+                              wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
-+                                      WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_STICKY, WM97XX_GPIO_WAKE);
-+                              wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
-+                                      WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_NOTSTICKY, WM97XX_GPIO_NOWAKE);
-+                              break;
-+                      default:
-+                              printk(KERN_WARNING "pen down irq not supported on this device\n");
-+                              pen_int = 0;
-+                              break;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+void wm97xx_acc_shutdown(struct wm97xx* wm)
-+{
-+    /* codec specific deconfig */
-+      if (pen_int) {
-+              switch (wm->id & 0xffff) {
-+                      case WM9705_ID2:
-+                              wm->pen_irq = 0;
-+                              break;
-+                      case WM9712_ID2:
-+                      case WM9713_ID2:
-+                              /* disable interrupt */
-+                              wm->pen_irq = 0;
-+                              break;
-+              }
-+      }
-+}
-+
-+static struct wm97xx_mach_ops pxa_mach_ops = {
-+      .acc_enabled = 1,
-+      .acc_pen_up = wm97xx_acc_pen_up,
-+    .acc_pen_down = wm97xx_acc_pen_down,
-+    .acc_startup = wm97xx_acc_startup,
-+    .acc_shutdown = wm97xx_acc_shutdown,
-+};
-+
-+int pxa_wm97xx_probe(struct device *dev)
-+{
-+    struct wm97xx *wm = dev->driver_data;
-+    return wm97xx_register_mach_ops (wm, &pxa_mach_ops);
-+}
-+
-+int pxa_wm97xx_remove(struct device *dev)
-+{
-+      struct wm97xx *wm = dev->driver_data;
-+    wm97xx_unregister_mach_ops (wm);
-+    return 0;
-+}
-+
-+static struct device_driver  pxa_wm97xx_driver = {
-+    .name = "wm97xx-touchscreen",
-+    .bus = &wm97xx_bus_type,
-+    .owner = THIS_MODULE,
-+    .probe = pxa_wm97xx_probe,
-+    .remove = pxa_wm97xx_remove
-+};
-+
-+static int __init pxa_wm97xx_init(void)
-+{
-+    return driver_register(&pxa_wm97xx_driver);
-+}
-+
-+static void __exit pxa_wm97xx_exit(void)
-+{
-+    driver_unregister(&pxa_wm97xx_driver);
-+}
-+
-+module_init(pxa_wm97xx_init);
-+module_exit(pxa_wm97xx_exit);
-+
-+/* Module information */
-+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
-+MODULE_DESCRIPTION("wm97xx continuous touch driver for pxa2xx");
-+MODULE_LICENSE("GPL");
-Index: linux-2.6.17/drivers/input/touchscreen/wm9705.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/drivers/input/touchscreen/wm9705.c    2006-09-19 20:36:47.969052000 +0200
-@@ -0,0 +1,360 @@
-+/*
-+ * wm9705.c  --  Codec driver for Wolfson WM9705 AC97 Codec.
-+ *
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-+ * Author: Liam Girdwood
-+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-+ * Parts Copyright : Ian Molton <spyro@f2s.com>
-+ *                   Andrew Zabolotny <zap@homelink.ru>
-+ *                   Russell King <rmk@arm.linux.org.uk>
-+ *
-+ *  This program is free software; you can redistribute  it and/or modify it
-+ *  under  the terms of  the GNU General  Public License as published by the
-+ *  Free Software Foundation;  either version 2 of the  License, or (at your
-+ *  option) any later version.
-+ *
-+ *  Revision history
-+ *     6th Sep 2006  Mike Arthur <linux@wolfsonmicro.com>
-+ *                   Added pre and post sample calls.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/wm97xx.h>
-+
-+#define TS_NAME                       "wm97xx"
-+#define WM9705_VERSION                "0.62"
-+#define DEFAULT_PRESSURE      0xb0c0
-+
-+/*
-+ * Debug
-+ */
-+#if 0
-+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
-+#else
-+#define dbg(format, arg...)
-+#endif
-+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
-+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
-+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
-+
-+/*
-+ * Module parameters
-+ */
-+
-+/*
-+ * Set current used for pressure measurement.
-+ *
-+ * Set pil = 2 to use 400uA
-+ *     pil = 1 to use 200uA and
-+ *     pil = 0 to disable pressure measurement.
-+ *
-+ * This is used to increase the range of values returned by the adc
-+ * when measureing touchpanel pressure.
-+ */
-+static int pil = 0;
-+module_param(pil, int, 0);
-+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
-+
-+/*
-+ * Set threshold for pressure measurement.
-+ *
-+ * Pen down pressure below threshold is ignored.
-+ */
-+static int pressure = DEFAULT_PRESSURE & 0xfff;
-+module_param(pressure, int, 0);
-+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
-+
-+/*
-+ * Set adc sample delay.
-+ *
-+ * For accurate touchpanel measurements, some settling time may be
-+ * required between the switch matrix applying a voltage across the
-+ * touchpanel plate and the ADC sampling the signal.
-+ *
-+ * This delay can be set by setting delay = n, where n is the array
-+ * position of the delay in the array delay_table below.
-+ * Long delays > 1ms are supported for completeness, but are not
-+ * recommended.
-+ */
-+static int delay = 4;
-+module_param(delay, int, 0);
-+MODULE_PARM_DESC(delay, "Set adc sample delay.");
-+
-+/*
-+ * Pen detect comparator threshold.
-+ *
-+ * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold
-+ * i.e. 1 =  Vmid/15 threshold
-+ *      15 =  Vmid/1 threshold
-+ *
-+ * Adjust this value if you are having problems with pen detect not
-+ * detecting any down events.
-+ */
-+static int pdd = 8;
-+module_param(pdd, int, 0);
-+MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold");
-+
-+/*
-+ * Set adc mask function.
-+ *
-+ * Sources of glitch noise, such as signals driving an LCD display, may feed
-+ * through to the touch screen plates and affect measurement accuracy. In
-+ * order to minimise this, a signal may be applied to the MASK pin to delay or
-+ * synchronise the sampling.
-+ *
-+ * 0 = No delay or sync
-+ * 1 = High on pin stops conversions
-+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
-+ * 3 = Edge triggered, edge on pin starts conversion after delay param
-+ */
-+static int mask = 0;
-+module_param(mask, int, 0);
-+MODULE_PARM_DESC(mask, "Set adc mask function.");
-+
-+/*
-+ * ADC sample delay times in uS
-+ */
-+static const int delay_table[] = {
-+      21,    // 1 AC97 Link frames
-+      42,    // 2
-+      84,    // 4
-+      167,   // 8
-+      333,   // 16
-+      667,   // 32
-+      1000,  // 48
-+      1333,  // 64
-+      2000,  // 96
-+      2667,  // 128
-+      3333,  // 160
-+      4000,  // 192
-+      4667,  // 224
-+      5333,  // 256
-+      6000,  // 288
-+      0      // No delay, switch matrix always on
-+};
-+
-+/*
-+ * Delay after issuing a POLL command.
-+ *
-+ * The delay is 3 AC97 link frames + the touchpanel settling delay
-+ */
-+static inline void poll_delay(int d)
-+{
-+      udelay (3 * AC97_LINK_FRAME + delay_table [d]);
-+}
-+
-+/*
-+ * set up the physical settings of the WM9705
-+ */
-+static void init_wm9705_phy(struct wm97xx* wm)
-+{
-+      u16 dig1 = 0, dig2 = WM97XX_RPR;
-+
-+      /*
-+      * mute VIDEO and AUX as they share X and Y touchscreen
-+      * inputs on the WM9705
-+      */
-+      wm97xx_reg_write(wm, AC97_AUX, 0x8000);
-+      wm97xx_reg_write(wm, AC97_VIDEO, 0x8000);
-+
-+      /* touchpanel pressure current*/
-+      if  (pil == 2) {
-+              dig2 |= WM9705_PIL;
-+              dbg("setting pressure measurement current to 400uA.");
-+      } else if (pil)
-+              dbg("setting pressure measurement current to 200uA.");
-+      if(!pil)
-+              pressure = 0;
-+
-+      /* polling mode sample settling delay */
-+      if (delay!=4) {
-+              if (delay < 0 || delay > 15) {
-+                  dbg("supplied delay out of range.");
-+                  delay = 4;
-+              }
-+      }
-+      dig1 &= 0xff0f;
-+      dig1 |= WM97XX_DELAY(delay);
-+      dbg("setting adc sample delay to %d u Secs.", delay_table[delay]);
-+
-+      /* WM9705 pdd */
-+      dig2 |= (pdd & 0x000f);
-+      dbg("setting pdd to Vmid/%d", 1 - (pdd & 0x000f));
-+
-+      /* mask */
-+      dig2 |= ((mask & 0x3) << 4);
-+
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
-+}
-+
-+static int wm9705_digitiser_ioctl(struct wm97xx* wm, int cmd)
-+{
-+      switch(cmd) {
-+      case WM97XX_DIG_START:
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] | WM97XX_PRP_DET_DIG);
-+              wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
-+              break;
-+      case WM97XX_DIG_STOP:
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] & ~WM97XX_PRP_DET_DIG);
-+              break;
-+      case WM97XX_AUX_PREPARE:
-+              memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
-+              break;
-+      case WM97XX_DIG_RESTORE:
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
-+              break;
-+      case WM97XX_PHY_INIT:
-+              init_wm9705_phy(wm);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+      return 0;
-+}
-+
-+static inline int is_pden (struct wm97xx* wm)
-+{
-+      return wm->dig[2] & WM9705_PDEN;
-+}
-+
-+/*
-+ * Read a sample from the WM9705 adc in polling mode.
-+ */
-+static int wm9705_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
-+{
-+      int timeout = 5 * delay;
-+
-+      if (!wm->pen_probably_down) {
-+              u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+              if (!(data & WM97XX_PEN_DOWN))
-+                      return RC_PENUP;
-+              wm->pen_probably_down = 1;
-+      }
-+
-+      /* set up digitiser */
-+      if (adcsel & 0x8000)
-+              adcsel = ((adcsel & 0x7fff) + 3) << 12;
-+
-+      if (wm->mach_ops && wm->mach_ops->pre_sample)
-+              wm->mach_ops->pre_sample(adcsel);
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
-+
-+      /* wait 3 AC97 time slots + delay for conversion */
-+      poll_delay (delay);
-+
-+      /* wait for POLL to go low */
-+      while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
-+              udelay(AC97_LINK_FRAME);
-+              timeout--;
-+      }
-+
-+      if (timeout <= 0) {
-+              /* If PDEN is set, we can get a timeout when pen goes up */
-+              if (is_pden(wm))
-+                      wm->pen_probably_down = 0;
-+              else
-+                      dbg ("adc sample timeout");
-+              return RC_PENUP;
-+      }
-+
-+      *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      if (wm->mach_ops && wm->mach_ops->post_sample)
-+              wm->mach_ops->post_sample(adcsel);
-+
-+      /* check we have correct sample */
-+      if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
-+              dbg ("adc wrong sample, read %x got %x", adcsel,
-+              *sample & WM97XX_ADCSEL_MASK);
-+              return RC_PENUP;
-+      }
-+
-+      if (!(*sample & WM97XX_PEN_DOWN)) {
-+              wm->pen_probably_down = 0;
-+              return RC_PENUP;
-+      }
-+
-+      return RC_VALID;
-+}
-+
-+/*
-+ * Sample the WM9705 touchscreen in polling mode
-+ */
-+static int wm9705_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
-+{
-+      int rc;
-+
-+      if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
-+              return rc;
-+      if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
-+              return rc;
-+      if (pil) {
-+              if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
-+                      return rc;
-+      } else
-+              data->p = DEFAULT_PRESSURE;
-+
-+      return RC_VALID;
-+}
-+
-+/*
-+ * Enable WM9705 continuous mode, i.e. touch data is streamed across an AC97 slot
-+ */
-+static int wm9705_acc_enable (struct wm97xx* wm, int enable)
-+{
-+      u16 dig1, dig2;
-+      int ret = 0;
-+
-+      dig1 = wm->dig[1];
-+      dig2 = wm->dig[2];
-+
-+      if (enable) {
-+              /* continous mode */
-+              if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0)
-+                      return ret;
-+              dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
-+                      WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
-+              dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
-+                      WM97XX_DELAY (delay) |
-+                      WM97XX_SLT (wm->acc_slot) |
-+                      WM97XX_RATE (wm->acc_rate);
-+              if (pil)
-+                      dig1 |= WM97XX_ADCSEL_PRES;
-+              dig2 |= WM9705_PDEN;
-+      } else {
-+              dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
-+              dig2 &= ~WM9705_PDEN;
-+              if (wm->mach_ops->acc_shutdown)
-+                      wm->mach_ops->acc_shutdown(wm);
-+      }
-+
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
-+      return ret;
-+}
-+
-+struct wm97xx_codec_drv wm97xx_codec = {
-+      .id =   WM9705_ID2,
-+      .name = "wm9705",
-+      .poll_sample = wm9705_poll_sample,
-+      .poll_touch = wm9705_poll_touch,
-+      .acc_enable = wm9705_acc_enable,
-+      .digitiser_ioctl = wm9705_digitiser_ioctl,
-+};
-+
-+EXPORT_SYMBOL_GPL(wm97xx_codec);
-+
-+/* Module information */
-+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
-+MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
-+MODULE_LICENSE("GPL");
-Index: linux-2.6.17/drivers/input/touchscreen/wm9712.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/drivers/input/touchscreen/wm9712.c    2006-09-19 20:36:47.969052000 +0200
-@@ -0,0 +1,464 @@
-+/*
-+ * wm9712.c  --  Codec driver for Wolfson WM9712 AC97 Codecs.
-+ *
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-+ * Author: Liam Girdwood
-+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-+ * Parts Copyright : Ian Molton <spyro@f2s.com>
-+ *                   Andrew Zabolotny <zap@homelink.ru>
-+ *                   Russell King <rmk@arm.linux.org.uk>
-+ *
-+ *  This program is free software; you can redistribute  it and/or modify it
-+ *  under  the terms of  the GNU General  Public License as published by the
-+ *  Free Software Foundation;  either version 2 of the  License, or (at your
-+ *  option) any later version.
-+ *
-+ *  Revision history
-+ *     4th Jul 2005  Initial version.
-+ *     6th Sep 2006  Mike Arthur <linux@wolfsonmicro.com>
-+ *                   Added pre and post sample calls.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/wm97xx.h>
-+
-+#define TS_NAME                       "wm97xx"
-+#define WM9712_VERSION                "0.61"
-+#define DEFAULT_PRESSURE      0xb0c0
-+
-+/*
-+ * Debug
-+ */
-+#if 0
-+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
-+#else
-+#define dbg(format, arg...)
-+#endif
-+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
-+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
-+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
-+
-+/*
-+ * Module parameters
-+ */
-+
-+/*
-+ * Set internal pull up for pen detect.
-+ *
-+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
-+ * i.e. pull up resistance = 64k Ohms / rpu.
-+ *
-+ * Adjust this value if you are having problems with pen detect not
-+ * detecting any down event.
-+ */
-+static int rpu = 3;
-+module_param(rpu, int, 0);
-+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
-+
-+/*
-+ * Set current used for pressure measurement.
-+ *
-+ * Set pil = 2 to use 400uA
-+ *     pil = 1 to use 200uA and
-+ *     pil = 0 to disable pressure measurement.
-+ *
-+ * This is used to increase the range of values returned by the adc
-+ * when measureing touchpanel pressure.
-+ */
-+static int pil = 0;
-+module_param(pil, int, 0);
-+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
-+
-+/*
-+ * Set threshold for pressure measurement.
-+ *
-+ * Pen down pressure below threshold is ignored.
-+ */
-+static int pressure = DEFAULT_PRESSURE & 0xfff;
-+module_param(pressure, int, 0);
-+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
-+
-+/*
-+ * Set adc sample delay.
-+ *
-+ * For accurate touchpanel measurements, some settling time may be
-+ * required between the switch matrix applying a voltage across the
-+ * touchpanel plate and the ADC sampling the signal.
-+ *
-+ * This delay can be set by setting delay = n, where n is the array
-+ * position of the delay in the array delay_table below.
-+ * Long delays > 1ms are supported for completeness, but are not
-+ * recommended.
-+ */
-+static int delay = 3;
-+module_param(delay, int, 0);
-+MODULE_PARM_DESC(delay, "Set adc sample delay.");
-+
-+/*
-+ * Set five_wire = 1 to use a 5 wire touchscreen.
-+ *
-+ * NOTE: Five wire mode does not allow for readback of pressure.
-+ */
-+static int five_wire;
-+module_param(five_wire, int, 0);
-+MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
-+
-+/*
-+ * Set adc mask function.
-+ *
-+ * Sources of glitch noise, such as signals driving an LCD display, may feed
-+ * through to the touch screen plates and affect measurement accuracy. In
-+ * order to minimise this, a signal may be applied to the MASK pin to delay or
-+ * synchronise the sampling.
-+ *
-+ * 0 = No delay or sync
-+ * 1 = High on pin stops conversions
-+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
-+ * 3 = Edge triggered, edge on pin starts conversion after delay param
-+ */
-+static int mask = 0;
-+module_param(mask, int, 0);
-+MODULE_PARM_DESC(mask, "Set adc mask function.");
-+
-+/*
-+ * Coordinate Polling Enable.
-+ *
-+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
-+ * for every poll.
-+ */
-+static int coord = 0;
-+module_param(coord, int, 0);
-+MODULE_PARM_DESC(coord, "Polling coordinate mode");
-+
-+/*
-+ * ADC sample delay times in uS
-+ */
-+static const int delay_table[] = {
-+      21,    // 1 AC97 Link frames
-+      42,    // 2
-+      84,    // 4
-+      167,   // 8
-+      333,   // 16
-+      667,   // 32
-+      1000,  // 48
-+      1333,  // 64
-+      2000,  // 96
-+      2667,  // 128
-+      3333,  // 160
-+      4000,  // 192
-+      4667,  // 224
-+      5333,  // 256
-+      6000,  // 288
-+      0      // No delay, switch matrix always on
-+};
-+
-+/*
-+ * Delay after issuing a POLL command.
-+ *
-+ * The delay is 3 AC97 link frames + the touchpanel settling delay
-+ */
-+static inline void poll_delay(int d)
-+{
-+      udelay (3 * AC97_LINK_FRAME + delay_table [d]);
-+}
-+
-+/*
-+ * set up the physical settings of the WM9712
-+ */
-+static void init_wm9712_phy(struct wm97xx* wm)
-+{
-+      u16 dig1 = 0;
-+      u16 dig2 = WM97XX_RPR | WM9712_RPU(1);
-+
-+      /* WM9712 rpu */
-+      if (rpu) {
-+              dig2 &= 0xffc0;
-+              dig2 |= WM9712_RPU(rpu);
-+              dbg("setting pen detect pull-up to %d Ohms",64000 / rpu);
-+      }
-+
-+      /* touchpanel pressure current*/
-+      if (pil == 2) {
-+              dig2 |= WM9712_PIL;
-+              dbg("setting pressure measurement current to 400uA.");
-+      } else if (pil)
-+              dbg("setting pressure measurement current to 200uA.");
-+      if(!pil)
-+              pressure = 0;
-+
-+      /* WM9712 five wire */
-+      if (five_wire) {
-+              dig2 |= WM9712_45W;
-+              dbg("setting 5-wire touchscreen mode.");
-+      }
-+
-+      /* polling mode sample settling delay */
-+      if (delay < 0 || delay > 15) {
-+              dbg("supplied delay out of range.");
-+              delay = 4;
-+      }
-+      dig1 &= 0xff0f;
-+      dig1 |= WM97XX_DELAY(delay);
-+      dbg("setting adc sample delay to %d u Secs.", delay_table[delay]);
-+
-+      /* mask */
-+      dig2 |= ((mask & 0x3) << 6);
-+      if (mask) {
-+              u16 reg;
-+              /* Set GPIO4 as Mask Pin*/
-+              reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
-+              wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4);
-+              reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
-+              wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4);
-+      }
-+
-+      /* wait - coord mode */
-+      if(coord)
-+              dig2 |= WM9712_WAIT;
-+
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
-+}
-+
-+static int wm9712_digitiser_ioctl(struct wm97xx* wm, int cmd)
-+{
-+      u16 dig2 = wm->dig[2];
-+
-+      switch(cmd) {
-+      case WM97XX_DIG_START:
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 | WM97XX_PRP_DET_DIG);
-+              wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
-+              break;
-+      case WM97XX_DIG_STOP:
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 & ~WM97XX_PRP_DET_DIG);
-+              break;
-+      case WM97XX_AUX_PREPARE:
-+              memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
-+              break;
-+      case WM97XX_DIG_RESTORE:
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
-+              wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
-+              break;
-+      case WM97XX_PHY_INIT:
-+              init_wm9712_phy(wm);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+      return 0;
-+}
-+
-+static inline int is_pden (struct wm97xx* wm)
-+{
-+      return wm->dig[2] & WM9712_PDEN;
-+}
-+
-+/*
-+ * Read a sample from the WM9712 adc in polling mode.
-+ */
-+static int wm9712_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
-+{
-+      int timeout = 5 * delay;
-+
-+      if (!wm->pen_probably_down) {
-+              u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+              if (!(data & WM97XX_PEN_DOWN))
-+                      return RC_PENUP;
-+              wm->pen_probably_down = 1;
-+      }
-+
-+      /* set up digitiser */
-+      if (adcsel & 0x8000)
-+              adcsel = ((adcsel & 0x7fff) + 3) << 12;
-+
-+      if (wm->mach_ops && wm->mach_ops->pre_sample)
-+              wm->mach_ops->pre_sample(adcsel);
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
-+
-+      /* wait 3 AC97 time slots + delay for conversion */
-+      poll_delay (delay);
-+
-+      /* wait for POLL to go low */
-+      while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
-+              udelay(AC97_LINK_FRAME);
-+              timeout--;
-+      }
-+
-+      if (timeout <= 0) {
-+              /* If PDEN is set, we can get a timeout when pen goes up */
-+              if (is_pden(wm))
-+                      wm->pen_probably_down = 0;
-+              else
-+                      dbg ("adc sample timeout");
-+              return RC_PENUP;
-+      }
-+
-+      *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      if (wm->mach_ops && wm->mach_ops->post_sample)
-+              wm->mach_ops->post_sample(adcsel);
-+
-+      /* check we have correct sample */
-+      if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
-+              dbg ("adc wrong sample, read %x got %x", adcsel,
-+              *sample & WM97XX_ADCSEL_MASK);
-+              return RC_PENUP;
-+      }
-+
-+      if (!(*sample & WM97XX_PEN_DOWN)) {
-+              wm->pen_probably_down = 0;
-+              return RC_PENUP;
-+      }
-+
-+      return RC_VALID;
-+}
-+
-+/*
-+ * Read a coord from the WM9712 adc in polling mode.
-+ */
-+static int wm9712_poll_coord (struct wm97xx* wm, struct wm97xx_data *data)
-+{
-+      int timeout = 5 * delay;
-+
-+      if (!wm->pen_probably_down) {
-+              u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+              if (!(data & WM97XX_PEN_DOWN))
-+                      return RC_PENUP;
-+              wm->pen_probably_down = 1;
-+      }
-+
-+      /* set up digitiser */
-+      if (wm->mach_ops && wm->mach_ops->pre_sample)
-+              wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
-+
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
-+              WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay));
-+
-+      /* wait 3 AC97 time slots + delay for conversion and read x */
-+      poll_delay(delay);
-+      data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      /* wait for POLL to go low */
-+      while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
-+              udelay(AC97_LINK_FRAME);
-+              timeout--;
-+      }
-+
-+      if (timeout <= 0) {
-+              /* If PDEN is set, we can get a timeout when pen goes up */
-+              if (is_pden(wm))
-+                      wm->pen_probably_down = 0;
-+              else
-+                      dbg ("adc sample timeout");
-+              return RC_PENUP;
-+      }
-+
-+      /* read back y data */
-+      data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      if (pil)
-+              data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      else
-+              data->p = DEFAULT_PRESSURE;
-+
-+      if (wm->mach_ops && wm->mach_ops->post_sample)
-+              wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
-+
-+      /* check we have correct sample */
-+      if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
-+              goto err;
-+      if(pil && !(data->p & WM97XX_ADCSEL_PRES))
-+              goto err;
-+
-+      if (!(data->x & WM97XX_PEN_DOWN)) {
-+              wm->pen_probably_down = 0;
-+              return RC_PENUP;
-+      }
-+      return RC_VALID;
-+err:
-+      return RC_PENUP;
-+}
-+
-+/*
-+ * Sample the WM9712 touchscreen in polling mode
-+ */
-+static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
-+{
-+      int rc;
-+
-+      if(coord) {
-+              if((rc = wm9712_poll_coord(wm, data)) != RC_VALID)
-+                      return rc;
-+      } else {
-+              if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
-+                      return rc;
-+
-+              if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
-+                      return rc;
-+
-+              if (pil && !five_wire) {
-+                      if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
-+                              return rc;
-+              } else
-+                      data->p = DEFAULT_PRESSURE;
-+      }
-+      return RC_VALID;
-+}
-+
-+/*
-+ * Enable WM9712 continuous mode, i.e. touch data is streamed across an AC97 slot
-+ */
-+static int wm9712_acc_enable (struct wm97xx* wm, int enable)
-+{
-+      u16 dig1, dig2;
-+      int ret = 0;
-+
-+      dig1 = wm->dig[1];
-+      dig2 = wm->dig[2];
-+
-+      if (enable) {
-+              /* continous mode */
-+              if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0)
-+                      return ret;
-+              dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
-+                      WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
-+              dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
-+                      WM97XX_DELAY (delay) |
-+                      WM97XX_SLT (wm->acc_slot) |
-+                      WM97XX_RATE (wm->acc_rate);
-+              if (pil)
-+                      dig1 |= WM97XX_ADCSEL_PRES;
-+              dig2 |= WM9712_PDEN;
-+      } else {
-+              dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
-+              dig2 &= ~WM9712_PDEN;
-+              if (wm->mach_ops->acc_shutdown)
-+                      wm->mach_ops->acc_shutdown(wm);
-+      }
-+
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
-+      wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
-+      return 0;
-+}
-+
-+struct wm97xx_codec_drv wm97xx_codec = {
-+      .id =   WM9712_ID2,
-+      .name = "wm9712",
-+      .poll_sample = wm9712_poll_sample,
-+      .poll_touch = wm9712_poll_touch,
-+      .acc_enable = wm9712_acc_enable,
-+      .digitiser_ioctl = wm9712_digitiser_ioctl,
-+};
-+
-+EXPORT_SYMBOL_GPL(wm97xx_codec);
-+
-+/* Module information */
-+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
-+MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
-+MODULE_LICENSE("GPL");
-Index: linux-2.6.17/drivers/input/touchscreen/wm9713.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/drivers/input/touchscreen/wm9713.c    2006-09-19 20:36:47.969052000 +0200
-@@ -0,0 +1,461 @@
-+/*
-+ * wm9713.c  --  Codec touch driver for Wolfson WM9713 AC97 Codec.
-+ *
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-+ * Author: Liam Girdwood
-+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-+ * Parts Copyright : Ian Molton <spyro@f2s.com>
-+ *                   Andrew Zabolotny <zap@homelink.ru>
-+ *                   Russell King <rmk@arm.linux.org.uk>
-+ *
-+ *  This program is free software; you can redistribute  it and/or modify it
-+ *  under  the terms of  the GNU General  Public License as published by the
-+ *  Free Software Foundation;  either version 2 of the  License, or (at your
-+ *  option) any later version.
-+ *
-+ *  Revision history
-+ *     6th Sep 2006  Mike Arthur <linux@wolfsonmicro.com>
-+ *                   Added pre and post sample calls.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/wm97xx.h>
-+
-+#define TS_NAME                       "wm97xx"
-+#define WM9713_VERSION                "0.53"
-+#define DEFAULT_PRESSURE      0xb0c0
-+
-+/*
-+ * Debug
-+ */
-+#if 0
-+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
-+#else
-+#define dbg(format, arg...)
-+#endif
-+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
-+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
-+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
-+
-+/*
-+ * Module parameters
-+ */
-+
-+/*
-+ * Set internal pull up for pen detect.
-+ *
-+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
-+ * i.e. pull up resistance = 64k Ohms / rpu.
-+ *
-+ * Adjust this value if you are having problems with pen detect not
-+ * detecting any down event.
-+ */
-+static int rpu = 1;
-+module_param(rpu, int, 0);
-+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
-+
-+/*
-+ * Set current used for pressure measurement.
-+ *
-+ * Set pil = 2 to use 400uA
-+ *     pil = 1 to use 200uA and
-+ *     pil = 0 to disable pressure measurement.
-+ *
-+ * This is used to increase the range of values returned by the adc
-+ * when measureing touchpanel pressure.
-+ */
-+static int pil = 0;
-+module_param(pil, int, 0);
-+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
-+
-+/*
-+ * Set threshold for pressure measurement.
-+ *
-+ * Pen down pressure below threshold is ignored.
-+ */
-+static int pressure = DEFAULT_PRESSURE & 0xfff;
-+module_param(pressure, int, 0);
-+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
-+
-+/*
-+ * Set adc sample delay.
-+ *
-+ * For accurate touchpanel measurements, some settling time may be
-+ * required between the switch matrix applying a voltage across the
-+ * touchpanel plate and the ADC sampling the signal.
-+ *
-+ * This delay can be set by setting delay = n, where n is the array
-+ * position of the delay in the array delay_table below.
-+ * Long delays > 1ms are supported for completeness, but are not
-+ * recommended.
-+ */
-+static int delay = 4;
-+module_param(delay, int, 0);
-+MODULE_PARM_DESC(delay, "Set adc sample delay.");
-+
-+/*
-+ * Set adc mask function.
-+ *
-+ * Sources of glitch noise, such as signals driving an LCD display, may feed
-+ * through to the touch screen plates and affect measurement accuracy. In
-+ * order to minimise this, a signal may be applied to the MASK pin to delay or
-+ * synchronise the sampling.
-+ *
-+ * 0 = No delay or sync
-+ * 1 = High on pin stops conversions
-+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
-+ * 3 = Edge triggered, edge on pin starts conversion after delay param
-+ */
-+static int mask = 0;
-+module_param(mask, int, 0);
-+MODULE_PARM_DESC(mask, "Set adc mask function.");
-+
-+/*
-+ * Coordinate Polling Enable.
-+ *
-+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
-+ * for every poll.
-+ */
-+static int coord = 1;
-+module_param(coord, int, 0);
-+MODULE_PARM_DESC(coord, "Polling coordinate mode");
-+
-+/*
-+ * ADC sample delay times in uS
-+ */
-+static const int delay_table[] = {
-+      21,    // 1 AC97 Link frames
-+      42,    // 2
-+      84,    // 4
-+      167,   // 8
-+      333,   // 16
-+      667,   // 32
-+      1000,  // 48
-+      1333,  // 64
-+      2000,  // 96
-+      2667,  // 128
-+      3333,  // 160
-+      4000,  // 192
-+      4667,  // 224
-+      5333,  // 256
-+      6000,  // 288
-+      0      // No delay, switch matrix always on
-+};
-+
-+/*
-+ * Delay after issuing a POLL command.
-+ *
-+ * The delay is 3 AC97 link frames + the touchpanel settling delay
-+ */
-+static inline void poll_delay(int d)
-+{
-+      udelay (3 * AC97_LINK_FRAME + delay_table [d]);
-+}
-+
-+/*
-+ * set up the physical settings of the WM9713
-+ */
-+static void init_wm9713_phy(struct wm97xx* wm)
-+{
-+      u16 dig1 = 0, dig2, dig3;
-+
-+      /* default values */
-+      dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5);
-+      dig3= WM9712_RPU(1);
-+
-+      /* rpu */
-+      if (rpu) {
-+              dig3 &= 0xffc0;
-+              dig3 |= WM9712_RPU(rpu);
-+              info("setting pen detect pull-up to %d Ohms",64000 / rpu);
-+      }
-+
-+      /* touchpanel pressure */
-+      if (pil == 2) {
-+              dig3 |= WM9712_PIL;
-+              info("setting pressure measurement current to 400uA.");
-+      } else if (pil)
-+              info ("setting pressure measurement current to 200uA.");
-+      if(!pil)
-+              pressure = 0;
-+
-+      /* sample settling delay */
-+      if (delay < 0 || delay > 15) {
-+              info ("supplied delay out of range.");
-+              delay = 4;
-+              info("setting adc sample delay to %d u Secs.", delay_table[delay]);
-+      }
-+      dig2 &= 0xff0f;
-+      dig2 |= WM97XX_DELAY(delay);
-+
-+      /* mask */
-+      dig3 |= ((mask & 0x3) << 4);
-+      if(coord)
-+              dig3 |= WM9713_WAIT;
-+
-+      wm->misc = wm97xx_reg_read(wm, 0x5a);
-+
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
-+      wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0);
-+}
-+
-+static int wm9713_digitiser_ioctl(struct wm97xx* wm, int cmd)
-+{
-+      u16 val = 0;
-+
-+      switch(cmd){
-+      case WM97XX_DIG_START:
-+              val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
-+              wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff);
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | WM97XX_PRP_DET_DIG);
-+              wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
-+              break;
-+      case WM97XX_DIG_STOP:
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & ~WM97XX_PRP_DET_DIG);
-+              val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
-+              wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000);
-+              break;
-+      case WM97XX_AUX_PREPARE:
-+              memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0);
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0);
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG);
-+              break;
-+      case WM97XX_DIG_RESTORE:
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]);
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]);
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]);
-+              break;
-+      case WM97XX_PHY_INIT:
-+              init_wm9713_phy(wm);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+      return 0;
-+}
-+
-+static inline int is_pden (struct wm97xx* wm)
-+{
-+      return wm->dig[2] & WM9713_PDEN;
-+}
-+
-+/*
-+ * Read a sample from the WM9713 adc in polling mode.
-+ */
-+static int wm9713_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
-+{
-+      u16 dig1;
-+      int timeout = 5 * delay;
-+
-+      if (!wm->pen_probably_down) {
-+              u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+              if (!(data & WM97XX_PEN_DOWN))
-+                      return RC_PENUP;
-+              wm->pen_probably_down = 1;
-+      }
-+
-+      /* set up digitiser */
-+      if (adcsel & 0x8000)
-+              adcsel = 1 << ((adcsel & 0x7fff) + 3);
-+
-+      dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
-+      dig1 &= ~WM9713_ADCSEL_MASK;
-+
-+      if (wm->mach_ops && wm->mach_ops->pre_sample)
-+              wm->mach_ops->pre_sample(adcsel);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel |WM9713_POLL);
-+
-+      /* wait 3 AC97 time slots + delay for conversion */
-+      poll_delay(delay);
-+
-+      /* wait for POLL to go low */
-+      while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) {
-+              udelay(AC97_LINK_FRAME);
-+              timeout--;
-+      }
-+
-+      if (timeout <= 0) {
-+              /* If PDEN is set, we can get a timeout when pen goes up */
-+              if (is_pden(wm))
-+                      wm->pen_probably_down = 0;
-+              else
-+                      dbg ("adc sample timeout");
-+              return RC_PENUP;
-+      }
-+
-+      *sample =wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      if (wm->mach_ops && wm->mach_ops->post_sample)
-+              wm->mach_ops->post_sample(adcsel);
-+
-+      /* check we have correct sample */
-+      if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) {
-+              dbg ("adc wrong sample, read %x got %x", adcsel,
-+                   *sample & WM97XX_ADCSRC_MASK);
-+              return RC_PENUP;
-+      }
-+
-+      if (!(*sample & WM97XX_PEN_DOWN)) {
-+              wm->pen_probably_down = 0;
-+              return RC_PENUP;
-+      }
-+
-+      return RC_VALID;
-+}
-+
-+/*
-+ * Read a coordinate from the WM9713 adc in polling mode.
-+ */
-+static int wm9713_poll_coord (struct wm97xx* wm, struct wm97xx_data *data)
-+{
-+      u16 dig1;
-+      int timeout = 5 * delay;
-+
-+      if (!wm->pen_probably_down) {
-+              u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+              if (!(data & WM97XX_PEN_DOWN))
-+                      return RC_PENUP;
-+              wm->pen_probably_down = 1;
-+      }
-+
-+      /* set up digitiser */
-+      dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
-+      dig1 &= ~WM9713_ADCSEL_MASK;
-+      if(pil)
-+              dig1 |= WM97XX_ADCSEL_PRES;
-+
-+      if (wm->mach_ops && wm->mach_ops->pre_sample)
-+              wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL | WM9713_COO);
-+
-+      /* wait 3 AC97 time slots + delay for conversion */
-+      poll_delay(delay);
-+      data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      /* wait for POLL to go low */
-+      while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) {
-+              udelay(AC97_LINK_FRAME);
-+              timeout--;
-+      }
-+
-+      if (timeout <= 0) {
-+              /* If PDEN is set, we can get a timeout when pen goes up */
-+              if (is_pden(wm))
-+                      wm->pen_probably_down = 0;
-+              else
-+                      dbg ("adc sample timeout");
-+              return RC_PENUP;
-+      }
-+
-+      /* read back data */
-+      data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      if (pil)
-+              data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
-+      else
-+              data->p = DEFAULT_PRESSURE;
-+
-+      if (wm->mach_ops && wm->mach_ops->post_sample)
-+              wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
-+
-+      /* check we have correct sample */
-+      if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
-+              goto err;
-+      if(pil && !(data->p & WM97XX_ADCSEL_PRES))
-+              goto err;
-+
-+      if (!(data->x & WM97XX_PEN_DOWN)) {
-+              wm->pen_probably_down = 0;
-+              return RC_PENUP;
-+      }
-+      return RC_VALID;
-+err:
-+      return RC_PENUP;
-+}
-+
-+/*
-+ * Sample the WM9713 touchscreen in polling mode
-+ */
-+static int wm9713_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
-+{
-+      int rc;
-+
-+      if(coord) {
-+              if((rc = wm9713_poll_coord(wm, data)) != RC_VALID)
-+                      return rc;
-+      } else {
-+              if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x)) != RC_VALID)
-+                      return rc;
-+              if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y)) != RC_VALID)
-+                      return rc;
-+              if (pil) {
-+                      if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, &data->p)) != RC_VALID)
-+                              return rc;
-+              } else
-+                      data->p = DEFAULT_PRESSURE;
-+      }
-+      return RC_VALID;
-+}
-+
-+/*
-+ * Enable WM9713 continuous mode, i.e. touch data is streamed across an AC97 slot
-+ */
-+static int wm9713_acc_enable (struct wm97xx* wm, int enable)
-+{
-+      u16 dig1, dig2, dig3;
-+      int ret = 0;
-+
-+      dig1 = wm->dig[0];
-+      dig2 = wm->dig[1];
-+      dig3 = wm->dig[2];
-+
-+      if (enable) {
-+              /* continous mode */
-+              if (wm->mach_ops->acc_startup &&
-+                      (ret = wm->mach_ops->acc_startup(wm)) < 0)
-+                      return ret;
-+
-+              dig1 &= ~WM9713_ADCSEL_MASK;
-+              dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | WM9713_ADCSEL_Y;
-+        if (pil)
-+              dig1 |= WM9713_ADCSEL_PRES;
-+              dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK  | WM97XX_CM_RATE_MASK);
-+              dig2 |= WM97XX_SLEN | WM97XX_DELAY (delay) |
-+              WM97XX_SLT (wm->acc_slot) | WM97XX_RATE (wm->acc_rate);
-+              dig3 |= WM9713_PDEN;
-+      } else {
-+              dig1 &= ~(WM9713_CTC | WM9713_COO);
-+              dig2 &= ~WM97XX_SLEN;
-+              dig3 &= ~WM9713_PDEN;
-+        if (wm->mach_ops->acc_shutdown)
-+            wm->mach_ops->acc_shutdown(wm);
-+      }
-+
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
-+      return ret;
-+}
-+
-+struct wm97xx_codec_drv wm97xx_codec = {
-+      .id =   WM9713_ID2,
-+    .name = "wm9713",
-+      .poll_sample = wm9713_poll_sample,
-+      .poll_touch = wm9713_poll_touch,
-+      .acc_enable = wm9713_acc_enable,
-+      .digitiser_ioctl = wm9713_digitiser_ioctl,
-+};
-+
-+EXPORT_SYMBOL_GPL(wm97xx_codec);
-+
-+/* Module information */
-+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
-+MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
-+MODULE_LICENSE("GPL");
-Index: linux-2.6.17/drivers/input/touchscreen/wm97xx-core.c
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/drivers/input/touchscreen/wm97xx-core.c       2006-09-19 20:36:47.969052000 +0200
-@@ -0,0 +1,912 @@
-+/*
-+ * wm97xx-core.c  --  Touch screen driver core for Wolfson WM9705, WM9712
-+ *                    and WM9713 AC97 Codecs.
-+ *
-+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
-+ * Author: Liam Girdwood
-+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
-+ * Parts Copyright : Ian Molton <spyro@f2s.com>
-+ *                   Andrew Zabolotny <zap@homelink.ru>
-+ *                   Russell King <rmk@arm.linux.org.uk>
-+ *
-+ *  This program is free software; you can redistribute  it and/or modify it
-+ *  under  the terms of  the GNU General  Public License as published by the
-+ *  Free Software Foundation;  either version 2 of the  License, or (at your
-+ *  option) any later version.
-+ *
-+ * Notes:
-+ *
-+ *  Features:
-+ *       - supports WM9705, WM9712, WM9713
-+ *       - polling mode
-+ *       - continuous mode (arch-dependent)
-+ *       - adjustable rpu/dpp settings
-+ *       - adjustable pressure current
-+ *       - adjustable sample settle delay
-+ *       - 4 and 5 wire touchscreens (5 wire is WM9712 only)
-+ *       - pen down detection
-+ *       - battery monitor
-+ *       - sample AUX adc's
-+ *       - power management
-+ *       - codec GPIO
-+ *       - codec event notification
-+ * Todo
-+ *       - Support for async sampling control for noisy LCD's.
-+ *
-+ *  Revision history
-+ *    7th May 2003   Initial version.
-+ *    6th June 2003  Added non module support and AC97 registration.
-+ *   18th June 2003  Added AUX adc sampling.
-+ *   23rd June 2003  Did some minimal reformatting, fixed a couple of
-+ *                   codec_mutexing bugs and noted a race to fix.
-+ *   24th June 2003  Added power management and fixed race condition.
-+ *   10th July 2003  Changed to a misc device.
-+ *   31st July 2003  Moved TS_EVENT and TS_CAL to wm97xx.h
-+ *    8th Aug  2003  Added option for read() calling wm97xx_sample_touch()
-+ *                   because some ac97_read/ac_97_write call schedule()
-+ *    7th Nov  2003  Added Input touch event interface, stanley.cai@intel.com
-+ *   13th Nov  2003  Removed h3600 touch interface, added interrupt based
-+ *                   pen down notification and implemented continous mode
-+ *                   on XScale arch.
-+ *   16th Nov  2003  Ian Molton <spyro@f2s.com>
-+ *                   Modified so that it suits the new 2.6 driver model.
-+ *   25th Jan  2004  Andrew Zabolotny <zap@homelink.ru>
-+ *                   Implemented IRQ-driven pen down detection, implemented
-+ *                   the private API meant to be exposed to platform-specific
-+ *                   drivers, reorganized the driver so that it supports
-+ *                   an arbitrary number of devices.
-+ *    1st Feb  2004  Moved continuous mode handling to a separate
-+ *                   architecture-dependent file. For now only PXA
-+ *                   built-in AC97 controller is supported (pxa-ac97-wm97xx.c).
-+ *    11th Feb 2004  Reduced CPU usage by keeping a cached copy of both
-+ *                   digitizer registers instead of reading them every time.
-+ *                   A reorganization of the whole code for better
-+ *                   error handling.
-+ *    17th Apr 2004  Added BMON support.
-+ *    17th Nov 2004  Added codec GPIO, codec event handling (real and virtual
-+ *                   GPIOs) and 2.6 power management.
-+ *    29th Nov 2004  Added WM9713 support.
-+ *     4th Jul 2005  Moved codec specific code out to seperate files.
-+ *     6th Sep 2006  Mike Arthur <linux@wolfsonmicro.com>
-+ *                   Added bus interface.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/string.h>
-+#include <linux/proc_fs.h>
-+#include <linux/pm.h>
-+#include <linux/interrupt.h>
-+#include <linux/bitops.h>
-+#include <linux/workqueue.h>
-+#include <linux/device.h>
-+#include <linux/wm97xx.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+
-+#define TS_NAME                       "wm97xx"
-+#define WM_CORE_VERSION               "0.63"
-+#define DEFAULT_PRESSURE      0xb0c0
-+
-+/*
-+ * WM97xx - enable/disable AUX ADC sysfs
-+ */
-+static int aux_sys = 1;
-+module_param(aux_sys, int, 0);
-+MODULE_PARM_DESC(aux_sys, "enable AUX ADC sysfs entries");
-+
-+/*
-+ * WM97xx - enable/disable codec status sysfs
-+ */
-+static int status_sys = 1;
-+module_param(status_sys, int, 0);
-+MODULE_PARM_DESC(status_sys, "enable codec status sysfs entries");
-+
-+/*
-+ * Touchscreen absolute values
-+ *
-+ * These parameters are used to help the input layer discard out of
-+ * range readings and reduce jitter etc.
-+ *
-+ *   o min, max:- indicate the min and max values your touch screen returns
-+ *   o fuzz:- use a higher number to reduce jitter
-+ *
-+ * The default values correspond to Mainstone II in QVGA mode
-+ *
-+ * Please read
-+ * Documentation/input/input-programming.txt for more details.
-+ */
-+
-+static int abs_x[3] = {350,3900,5};
-+module_param_array(abs_x, int, NULL, 0);
-+MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");
-+
-+static int abs_y[3] = {320,3750,40};
-+module_param_array(abs_y, int, NULL, 0);
-+MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");
-+
-+static int abs_p[3] = {0,150,4};
-+module_param_array(abs_p, int, NULL, 0);
-+MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");
-+
-+/*
-+ * Debug
-+ */
-+#if 0
-+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
-+#else
-+#define dbg(format, arg...)
-+#endif
-+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
-+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
-+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
-+
-+/* codec AC97 IO access */
-+int wm97xx_reg_read(struct wm97xx *wm, u16 reg)
-+{
-+      if (wm->ac97)
-+              return wm->ac97->bus->ops->read(wm->ac97, reg);
-+      else
-+              return -1;
-+}
-+
-+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val)
-+{
-+      /* cache digitiser registers */
-+      if(reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3)
-+              wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val;
-+
-+      /* cache gpio regs */
-+      if(reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE)
-+              wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val;
-+
-+      /* wm9713 irq reg */
-+      if(reg == 0x5a)
-+              wm->misc = val;
-+
-+      if (wm->ac97)
-+              wm->ac97->bus->ops->write(wm->ac97, reg, val);
-+}
-+
-+
-+/**
-+ *    wm97xx_read_aux_adc - Read the aux adc.
-+ *    @wm: wm97xx device.
-+ *  @adcsel: codec ADC to be read
-+ *
-+ *    Reads the selected AUX ADC.
-+ */
-+
-+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
-+{
-+      int power_adc = 0, auxval;
-+      u16 power = 0;
-+
-+      /* get codec */
-+      mutex_lock(&wm->codec_mutex);
-+
-+      /* When the touchscreen is not in use, we may have to power up the AUX ADC
-+       * before we can use sample the AUX inputs->
-+       */
-+      if (wm->id == WM9713_ID2 &&
-+          (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) {
-+              power_adc = 1;
-+              wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff);
-+      }
-+
-+      /* Prepare the codec for AUX reading */
-+      wm->codec->digitiser_ioctl(wm, WM97XX_AUX_PREPARE);
-+
-+      /* Turn polling mode on to read AUX ADC */
-+      wm->pen_probably_down = 1;
-+      wm->codec->poll_sample(wm, adcsel, &auxval);
-+
-+      if (power_adc)
-+              wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000);
-+
-+      wm->codec->digitiser_ioctl(wm, WM97XX_DIG_RESTORE);
-+
-+      wm->pen_probably_down = 0;
-+
-+      mutex_unlock(&wm->codec_mutex);
-+      return auxval & 0xfff;
-+}
-+
-+#define WM97XX_AUX_ATTR(name,input) \
-+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf)   \
-+{ \
-+      struct wm97xx *wm = (struct wm97xx*)dev->driver_data; \
-+      return sprintf(buf, "%d\n", wm97xx_read_aux_adc(wm, input)); \
-+} \
-+static DEVICE_ATTR(name, 0444, name##_show, NULL)
-+
-+WM97XX_AUX_ATTR(aux1, WM97XX_AUX_ID1);
-+WM97XX_AUX_ATTR(aux2, WM97XX_AUX_ID2);
-+WM97XX_AUX_ATTR(aux3, WM97XX_AUX_ID3);
-+WM97XX_AUX_ATTR(aux4, WM97XX_AUX_ID4);
-+
-+#define WM97XX_STATUS_ATTR(name) \
-+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf)   \
-+{ \
-+      struct wm97xx *wm = (struct wm97xx*)dev->driver_data; \
-+      return sprintf(buf, "%d\n", wm97xx_reg_read(wm, AC97_GPIO_STATUS)); \
-+} \
-+static DEVICE_ATTR(name, 0444, name##_show, NULL)
-+
-+WM97XX_STATUS_ATTR(gpio);
-+
-+static int wm97xx_sys_add(struct device *dev)
-+{
-+      if (aux_sys) {
-+              device_create_file(dev, &dev_attr_aux1);
-+              device_create_file(dev, &dev_attr_aux2);
-+              device_create_file(dev, &dev_attr_aux3);
-+              device_create_file(dev, &dev_attr_aux4);
-+      }
-+      if (status_sys)
-+              device_create_file(dev, &dev_attr_gpio);
-+      return 0;
-+}
-+
-+static void wm97xx_sys_remove(struct device *dev)
-+{
-+      if (status_sys)
-+              device_remove_file(dev, &dev_attr_gpio);
-+      if (aux_sys) {
-+              device_remove_file(dev, &dev_attr_aux1);
-+              device_remove_file(dev, &dev_attr_aux2);
-+              device_remove_file(dev, &dev_attr_aux3);
-+              device_remove_file(dev, &dev_attr_aux4);
-+      }
-+}
-+
-+/**
-+ *    wm97xx_get_gpio - Get the status of a codec GPIO.
-+ *    @wm: wm97xx device.
-+ *  @gpio: gpio
-+ *
-+ *    Get the status of a codec GPIO pin
-+ */
-+
-+wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio)
-+{
-+      u16 status;
-+      wm97xx_gpio_status_t ret;
-+
-+      mutex_lock(&wm->codec_mutex);
-+      status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
-+
-+      if (status & gpio)
-+              ret = WM97XX_GPIO_HIGH;
-+      else
-+              ret = WM97XX_GPIO_LOW;
-+
-+      mutex_unlock(&wm->codec_mutex);
-+      return ret;
-+}
-+
-+/**
-+ *    wm97xx_set_gpio - Set the status of a codec GPIO.
-+ *    @wm: wm97xx device.
-+ *  @gpio: gpio
-+ *
-+ *
-+ *    Set the status of a codec GPIO pin
-+ */
-+
-+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
-+                              wm97xx_gpio_status_t status)
-+{
-+      u16 reg;
-+
-+      mutex_lock(&wm->codec_mutex);
-+      reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
-+
-+      if (status & WM97XX_GPIO_HIGH)
-+              reg |= gpio;
-+      else
-+              reg &= ~gpio;
-+
-+      if (wm->id == WM9712_ID2)
-+              wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
-+      else
-+              wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
-+      mutex_unlock(&wm->codec_mutex);
-+}
-+
-+/*
-+ * Codec GPIO pin configuration, this set's pin direction, polarity,
-+ * stickyness and wake up.
-+ */
-+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, wm97xx_gpio_dir_t dir,
-+                 wm97xx_gpio_pol_t pol, wm97xx_gpio_sticky_t sticky,
-+                 wm97xx_gpio_wake_t wake)
-+{
-+      u16 reg;
-+
-+      mutex_lock(&wm->codec_mutex);
-+      reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
-+
-+      if (pol == WM97XX_GPIO_POL_HIGH)
-+              reg |= gpio;
-+      else
-+              reg &= ~gpio;
-+
-+      wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg);
-+      reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
-+
-+      if (sticky == WM97XX_GPIO_STICKY)
-+              reg |= gpio;
-+      else
-+              reg &= ~gpio;
-+
-+      wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg);
-+      reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
-+
-+      if (wake == WM97XX_GPIO_WAKE)
-+              reg |= gpio;
-+      else
-+              reg &= ~gpio;
-+
-+      wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg);
-+      reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
-+
-+      if (dir == WM97XX_GPIO_IN)
-+              reg |= gpio;
-+      else
-+              reg &= ~gpio;
-+
-+      wm97xx_reg_write(wm, AC97_GPIO_CFG, reg);
-+      mutex_unlock(&wm->codec_mutex);
-+}
-+
-+/*
-+ * Handle a pen down interrupt.
-+ */
-+static void wm97xx_pen_irq_worker(void *ptr)
-+{
-+      struct wm97xx *wm = (struct wm97xx *) ptr;
-+
-+      /* do we need to enable the touch panel reader */
-+      if (wm->id == WM9705_ID2) {
-+              if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & WM97XX_PEN_DOWN)
-+                      wm->pen_is_down = 1;
-+              else
-+                      wm->pen_is_down = 0;
-+              wake_up_interruptible(&wm->pen_irq_wait);
-+      } else {
-+              u16 status, pol;
-+              mutex_lock(&wm->codec_mutex);
-+              status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
-+              pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
-+
-+              if (WM97XX_GPIO_13 & pol & status) {
-+                      wm->pen_is_down = 1;
-+                      wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol & ~WM97XX_GPIO_13);
-+              } else {
-+                      wm->pen_is_down = 0;
-+                  wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol | WM97XX_GPIO_13);
-+              }
-+
-+              if (wm->id == WM9712_ID2)
-+                      wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status & ~WM97XX_GPIO_13) << 1);
-+              else
-+                      wm97xx_reg_write(wm, AC97_GPIO_STATUS, status & ~WM97XX_GPIO_13);
-+              mutex_unlock(&wm->codec_mutex);
-+              wake_up_interruptible(&wm->pen_irq_wait);
-+      }
-+
-+      if (!wm->pen_is_down && wm->mach_ops && wm->mach_ops->acc_enabled)
-+              wm->mach_ops->acc_pen_up(wm);
-+      enable_irq(wm->pen_irq);
-+}
-+
-+/*
-+ * Codec PENDOWN irq handler
-+ *
-+ * We have to disable the codec interrupt in the handler because it can
-+ * take upto 1ms to clear the interrupt source. The interrupt is then enabled
-+ * again in the slow handler when the source has been cleared.
-+ */
-+static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id,
-+                                      struct pt_regs *regs)
-+{
-+      struct wm97xx *wm = (struct wm97xx *) dev_id;
-+      disable_irq(wm->pen_irq);
-+      queue_work(wm->pen_irq_workq, &wm->pen_event_work);
-+      return IRQ_HANDLED;
-+}
-+
-+/*
-+ * initialise pen IRQ handler and workqueue
-+ */
-+static int wm97xx_init_pen_irq(struct wm97xx *wm)
-+{
-+      u16 reg;
-+
-+      INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker, wm);
-+      if ((wm->pen_irq_workq =
-+              create_singlethread_workqueue("kwm97pen")) == NULL) {
-+              err("could not create pen irq work queue");
-+              wm->pen_irq = 0;
-+              return -EINVAL;
-+      }
-+
-+      if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) {
-+              err("could not register codec pen down interrupt, will poll for pen down");
-+              destroy_workqueue(wm->pen_irq_workq);
-+              wm->pen_irq = 0;
-+              return -EINVAL;
-+      }
-+
-+      /* enable PEN down on wm9712/13 */
-+      if (wm->id != WM9705_ID2) {
-+              reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
-+              wm97xx_reg_write(wm, AC97_MISC_AFE, reg & 0xfffb);
-+              reg = wm97xx_reg_read(wm, 0x5a);
-+              wm97xx_reg_write(wm, 0x5a, reg & ~0x0001);
-+      }
-+
-+      return 0;
-+}
-+
-+/* Private struct for communication between struct wm97xx_tshread
-+ * and wm97xx_read_samples */
-+struct ts_state {
-+      int sleep_time;
-+      int min_sleep_time;
-+};
-+
-+static int wm97xx_read_samples(struct wm97xx *wm, struct ts_state *state)
-+{
-+      struct wm97xx_data data;
-+      int rc;
-+
-+      mutex_lock(&wm->codec_mutex);
-+
-+    if (wm->mach_ops && wm->mach_ops->acc_enabled)
-+         rc = wm->mach_ops->acc_pen_down(wm);
-+    else
-+        rc = wm->codec->poll_touch(wm, &data);
-+
-+      if (rc & RC_PENUP) {
-+              if (wm->pen_is_down) {
-+                      wm->pen_is_down = 0;
-+                      dbg("pen up");
-+                      input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
-+                      input_sync(wm->input_dev);
-+              } else if (!(rc & RC_AGAIN)) {
-+                      /* We need high frequency updates only while pen is down,
-+                      * the user never will be able to touch screen faster than
-+                      * a few times per second... On the other hand, when the
-+                      * user is actively working with the touchscreen we don't
-+                      * want to lose the quick response. So we will slowly
-+                      * increase sleep time after the pen is up and quicky
-+                      * restore it to ~one task switch when pen is down again.
-+                      */
-+                      if (state->sleep_time < HZ / 10)
-+                              state->sleep_time++;
-+              }
-+
-+      } else if (rc & RC_VALID) {
-+              dbg("pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n",
-+                      data.x >> 12, data.x & 0xfff, data.y >> 12,
-+                      data.y & 0xfff, data.p >> 12, data.p & 0xfff);
-+              input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
-+              input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
-+              input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
-+              input_sync(wm->input_dev);
-+              wm->pen_is_down = 1;
-+              state->sleep_time = state->min_sleep_time;
-+      } else if (rc & RC_PENDOWN) {
-+              dbg("pen down");
-+              wm->pen_is_down = 1;
-+              state->sleep_time = state->min_sleep_time;
-+      }
-+
-+      mutex_unlock(&wm->codec_mutex);
-+      return rc;
-+}
-+
-+/*
-+* The touchscreen sample reader thread.
-+*/
-+static int wm97xx_ts_read(void *data)
-+{
-+      int rc;
-+      struct ts_state state;
-+      struct wm97xx *wm = (struct wm97xx *) data;
-+
-+      /* set up thread context */
-+      wm->ts_task = current;
-+      daemonize("kwm97xxts");
-+
-+      if (wm->codec == NULL) {
-+              wm->ts_task = NULL;
-+              printk(KERN_ERR "codec is NULL, bailing\n");
-+      }
-+
-+      complete(&wm->ts_init);
-+      wm->pen_is_down = 0;
-+      state.min_sleep_time = HZ >= 100 ? HZ / 100 : 1;
-+      if (state.min_sleep_time < 1)
-+              state.min_sleep_time = 1;
-+      state.sleep_time = state.min_sleep_time;
-+
-+      /* touch reader loop */
-+      while (wm->ts_task) {
-+              do {
-+                      try_to_freeze();
-+                      rc = wm97xx_read_samples(wm, &state);
-+              } while (rc & RC_AGAIN);
-+              if (!wm->pen_is_down && wm->pen_irq) {
-+                      /* Nice, we don't have to poll for pen down event */
-+                      wait_event_interruptible(wm->pen_irq_wait, wm->pen_is_down);
-+              } else {
-+                      set_task_state(current, TASK_INTERRUPTIBLE);
-+                      schedule_timeout(state.sleep_time);
-+              }
-+      }
-+      complete_and_exit(&wm->ts_exit, 0);
-+}
-+
-+/**
-+ *    wm97xx_ts_input_open - Open the touch screen input device.
-+ *    @idev:  Input device to be opened.
-+ *
-+ *    Called by the input sub system to open a wm97xx touchscreen device.
-+ *  Starts the touchscreen thread and touch digitiser.
-+ */
-+static int wm97xx_ts_input_open(struct input_dev *idev)
-+{
-+      int ret = 0;
-+      struct wm97xx *wm = (struct wm97xx *) idev->private;
-+
-+      mutex_lock(&wm->codec_mutex);
-+      /* first time opened ? */
-+      if (wm->ts_use_count++ == 0) {
-+              /* start touchscreen thread */
-+              init_completion(&wm->ts_init);
-+              init_completion(&wm->ts_exit);
-+              ret = kernel_thread(wm97xx_ts_read, wm, CLONE_KERNEL);
-+
-+              if (ret >= 0) {
-+                      wait_for_completion(&wm->ts_init);
-+                      if (wm->ts_task == NULL)
-+                              ret = -EINVAL;
-+              } else {
-+                      mutex_unlock(&wm->codec_mutex);
-+                      return ret;
-+              }
-+
-+              /* start digitiser */
-+        if (wm->mach_ops && wm->mach_ops->acc_enabled)
-+            wm->codec->acc_enable(wm, 1);
-+              wm->codec->digitiser_ioctl(wm, WM97XX_DIG_START);
-+
-+              /* init pen down/up irq handling */
-+              if (wm->pen_irq) {
-+                      wm97xx_init_pen_irq(wm);
-+
-+                      if (wm->pen_irq == 0) {
-+                              /* we failed to get an irq for pen down events,
-+                               * so we resort to polling. kickstart the reader */
-+                              wm->pen_is_down = 1;
-+                              wake_up_interruptible(&wm->pen_irq_wait);
-+                      }
-+              }
-+      }
-+
-+      mutex_unlock(&wm->codec_mutex);
-+      return 0;
-+}
-+
-+/**
-+ *    wm97xx_ts_input_close - Close the touch screen input device.
-+ *    @idev:  Input device to be closed.
-+ *
-+ *    Called by the input sub system to close a wm97xx touchscreen device.
-+ *  Kills the touchscreen thread and stops the touch digitiser.
-+ */
-+
-+static void wm97xx_ts_input_close(struct input_dev *idev)
-+{
-+      struct wm97xx *wm = (struct wm97xx *) idev->private;
-+
-+      mutex_lock(&wm->codec_mutex);
-+      if (--wm->ts_use_count == 0) {
-+              /* destroy workqueues and free irqs */
-+              if (wm->pen_irq) {
-+                      free_irq(wm->pen_irq, wm);
-+                      destroy_workqueue(wm->pen_irq_workq);
-+              }
-+
-+              /* kill thread */
-+              if (wm->ts_task) {
-+                      wm->ts_task = NULL;
-+                      wm->pen_is_down = 1;
-+                      wake_up_interruptible(&wm->pen_irq_wait);
-+                      wait_for_completion(&wm->ts_exit);
-+                      wm->pen_is_down = 0;
-+              }
-+
-+              /* stop digitiser */
-+              wm->codec->digitiser_ioctl(wm, WM97XX_DIG_STOP);
-+              if (wm->mach_ops && wm->mach_ops->acc_enabled)
-+                      wm->codec->acc_enable(wm, 0);
-+      }
-+      mutex_unlock(&wm->codec_mutex);
-+}
-+
-+static int wm97xx_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+    return !(strcmp(dev->bus_id,drv->name));
-+}
-+
-+/*
-+ * The AC97 audio driver will do all the Codec suspend and resume
-+ * tasks. This is just for anything machine specific or extra.
-+ */
-+static int wm97xx_bus_suspend(struct device *dev, pm_message_t state)
-+{
-+    int ret = 0;
-+
-+    if (dev->driver && dev->driver->suspend)
-+        ret = dev->driver->suspend(dev, state);
-+
-+    return ret;
-+}
-+
-+static int wm97xx_bus_resume(struct device *dev)
-+{
-+    int ret = 0;
-+
-+    if (dev->driver && dev->driver->resume)
-+        ret = dev->driver->resume(dev);
-+
-+    return ret;
-+}
-+
-+struct bus_type wm97xx_bus_type = {
-+    .name       = "wm97xx",
-+    .match      = wm97xx_bus_match,
-+    .suspend    = wm97xx_bus_suspend,
-+    .resume     = wm97xx_bus_resume,
-+};
-+
-+static void  wm97xx_release(struct device *dev)
-+{
-+    kfree(dev);
-+}
-+
-+static int wm97xx_probe(struct device *dev)
-+{
-+      struct wm97xx* wm;
-+      int ret = 0, id = 0;
-+
-+      if (!(wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL)))
-+              return -ENOMEM;
-+    mutex_init(&wm->codec_mutex);
-+
-+      init_waitqueue_head(&wm->pen_irq_wait);
-+      wm->dev = dev;
-+      dev->driver_data = wm;
-+      wm->ac97 = to_ac97_t(dev);
-+
-+      /* check that we have a supported codec */
-+      if ((id = wm97xx_reg_read(wm, AC97_VENDOR_ID1)) != WM97XX_ID1) {
-+              err("could not find a wm97xx, found a %x instead\n", id);
-+              kfree(wm);
-+              return -ENODEV;
-+      }
-+
-+      wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
-+      if(wm->id != wm97xx_codec.id) {
-+              err("could not find a the selected codec, please build for wm97%2x", wm->id & 0xff);
-+              kfree(wm);
-+              return -ENODEV;
-+      }
-+
-+      if((wm->input_dev = input_allocate_device()) == NULL) {
-+        kfree(wm);
-+              return -ENOMEM;
-+    }
-+
-+      /* set up touch configuration */
-+      info("detected a wm97%2x codec", wm->id & 0xff);
-+      wm->input_dev->name = "wm97xx touchscreen";
-+      wm->input_dev->open = wm97xx_ts_input_open;
-+      wm->input_dev->close = wm97xx_ts_input_close;
-+      set_bit(EV_ABS, wm->input_dev->evbit);
-+      set_bit(ABS_X, wm->input_dev->absbit);
-+      set_bit(ABS_Y, wm->input_dev->absbit);
-+      set_bit(ABS_PRESSURE, wm->input_dev->absbit);
-+      wm->input_dev->absmax[ABS_X] = abs_x[1];
-+      wm->input_dev->absmax[ABS_Y] = abs_y[1];
-+      wm->input_dev->absmax[ABS_PRESSURE] = abs_p[1];
-+      wm->input_dev->absmin[ABS_X] = abs_x[0];
-+      wm->input_dev->absmin[ABS_Y] = abs_y[0];
-+      wm->input_dev->absmin[ABS_PRESSURE] = abs_p[0];
-+      wm->input_dev->absfuzz[ABS_X] = abs_x[2];
-+      wm->input_dev->absfuzz[ABS_Y] = abs_y[2];
-+      wm->input_dev->absfuzz[ABS_PRESSURE] = abs_p[2];
-+      wm->input_dev->private = wm;
-+      wm->codec = &wm97xx_codec;
-+      if((ret = input_register_device(wm->input_dev)) < 0) {
-+              kfree(wm);
-+              return -ENOMEM;
-+    }
-+
-+      if(aux_sys)
-+              wm97xx_sys_add(dev);
-+
-+      /* set up physical characteristics */
-+      wm->codec->digitiser_ioctl(wm, WM97XX_PHY_INIT);
-+
-+      /* load gpio cache */
-+      wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG);
-+      wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
-+      wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
-+      wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
-+      wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
-+      wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
-+
-+      /* register our battery device */
-+    if (!(wm->battery_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) {
-+      ret = -ENOMEM;
-+        goto batt_err;
-+    }
-+    wm->battery_dev->bus = &wm97xx_bus_type;
-+    strcpy(wm->battery_dev->bus_id,"wm97xx-battery");
-+    wm->battery_dev->driver_data = wm;
-+    wm->battery_dev->parent = dev;
-+    wm->battery_dev->release = wm97xx_release;
-+    if((ret = device_register(wm->battery_dev)) < 0)
-+      goto batt_reg_err;
-+
-+      /* register our extended touch device (for machine specific extensions) */
-+    if (!(wm->touch_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) {
-+      ret = -ENOMEM;
-+        goto touch_err;
-+    }
-+    wm->touch_dev->bus = &wm97xx_bus_type;
-+    strcpy(wm->touch_dev->bus_id,"wm97xx-touchscreen");
-+    wm->touch_dev->driver_data = wm;
-+    wm->touch_dev->parent = dev;
-+    wm->touch_dev->release = wm97xx_release;
-+    if((ret = device_register(wm->touch_dev)) < 0)
-+      goto touch_reg_err;
-+
-+    return ret;
-+
-+touch_reg_err:
-+      kfree(wm->touch_dev);
-+touch_err:
-+    device_unregister(wm->battery_dev);
-+batt_reg_err:
-+      kfree(wm->battery_dev);
-+batt_err:
-+    input_unregister_device(wm->input_dev);
-+    kfree(wm);
-+    return ret;
-+}
-+
-+static int wm97xx_remove(struct device *dev)
-+{
-+      struct wm97xx *wm = dev_get_drvdata(dev);
-+
-+      /* Stop touch reader thread */
-+      if (wm->ts_task) {
-+              wm->ts_task = NULL;
-+              wm->pen_is_down = 1;
-+              wake_up_interruptible(&wm->pen_irq_wait);
-+              wait_for_completion(&wm->ts_exit);
-+      }
-+      device_unregister(wm->battery_dev);
-+      device_unregister(wm->touch_dev);
-+    input_unregister_device(wm->input_dev);
-+
-+      if(aux_sys)
-+              wm97xx_sys_remove(dev);
-+
-+      kfree(wm);
-+      return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+int wm97xx_resume(struct device* dev)
-+{
-+      struct wm97xx *wm = dev_get_drvdata(dev);
-+
-+      /* restore digitiser and gpio's */
-+      if(wm->id == WM9713_ID2) {
-+              wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
-+              wm97xx_reg_write(wm, 0x5a, wm->misc);
-+              if(wm->ts_use_count) {
-+                      u16 reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
-+                      wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
-+              }
-+      }
-+
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]);
-+      wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]);
-+
-+      wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]);
-+      wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]);
-+      wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]);
-+      wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]);
-+      wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
-+      wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
-+
-+      return 0;
-+}
-+
-+#else
-+#define wm97xx_resume         NULL
-+#endif
-+
-+int wm97xx_register_mach_ops(struct wm97xx *wm, struct wm97xx_mach_ops *mach_ops)
-+{
-+      mutex_lock(&wm->codec_mutex);
-+    if(wm->mach_ops) {
-+      mutex_unlock(&wm->codec_mutex);
-+      return -EINVAL;
-+    }
-+    wm->mach_ops = mach_ops;
-+    mutex_unlock(&wm->codec_mutex);
-+    return 0;
-+}
-+
-+void wm97xx_unregister_mach_ops(struct wm97xx *wm)
-+{
-+      mutex_lock(&wm->codec_mutex);
-+    wm->mach_ops = NULL;
-+    mutex_unlock(&wm->codec_mutex);
-+}
-+
-+static struct device_driver wm97xx_driver = {
-+      .name =         "ac97",
-+      .bus =          &ac97_bus_type,
-+      .owner =        THIS_MODULE,
-+      .probe =        wm97xx_probe,
-+      .remove =       wm97xx_remove,
-+      .resume =       wm97xx_resume,
-+};
-+
-+static int __init wm97xx_init(void)
-+{
-+      int ret;
-+
-+      info("version %s liam.girdwood@wolfsonmicro.com", WM_CORE_VERSION);
-+    if((ret = bus_register(&wm97xx_bus_type)) < 0)
-+      return ret;
-+      return driver_register(&wm97xx_driver);
-+}
-+
-+static void __exit wm97xx_exit(void)
-+{
-+      driver_unregister(&wm97xx_driver);
-+    bus_unregister(&wm97xx_bus_type);
-+}
-+
-+EXPORT_SYMBOL_GPL(wm97xx_get_gpio);
-+EXPORT_SYMBOL_GPL(wm97xx_set_gpio);
-+EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
-+EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
-+EXPORT_SYMBOL_GPL(wm97xx_reg_read);
-+EXPORT_SYMBOL_GPL(wm97xx_reg_write);
-+EXPORT_SYMBOL_GPL(wm97xx_bus_type);
-+EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops);
-+EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
-+
-+module_init(wm97xx_init);
-+module_exit(wm97xx_exit);
-+
-+/* Module information */
-+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
-+MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
-+MODULE_LICENSE("GPL");
-Index: linux-2.6.17/include/linux/wm97xx.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17/include/linux/wm97xx.h        2006-09-19 20:36:47.973052250 +0200
-@@ -0,0 +1,291 @@
-+
-+/*
-+ * Register bits and API for Wolfson WM97xx series of codecs
-+ */
-+
-+#ifndef _LINUX_WM97XX_H
-+#define _LINUX_WM97XX_H
-+
-+#include <sound/driver.h>
-+#include <sound/core.h>
-+#include <sound/pcm.h>
-+#include <sound/ac97_codec.h>
-+#include <sound/initval.h>
-+#include <linux/types.h>
-+#include <linux/list.h>
-+#include <linux/input.h>      /* Input device layer */
-+
-+/*
-+ * WM97xx AC97 Touchscreen registers
-+ */
-+#define AC97_WM97XX_DIGITISER1                0x76
-+#define AC97_WM97XX_DIGITISER2                0x78
-+#define AC97_WM97XX_DIGITISER_RD      0x7a
-+#define AC97_WM9713_DIG1                      0x74
-+#define AC97_WM9713_DIG2                      AC97_WM97XX_DIGITISER1
-+#define AC97_WM9713_DIG3                      AC97_WM97XX_DIGITISER2
-+
-+/*
-+ * WM97xx register bits
-+ */
-+#define WM97XX_POLL                   0x8000  /* initiate a polling measurement */
-+#define WM97XX_ADCSEL_X               0x1000  /* x coord measurement */
-+#define WM97XX_ADCSEL_Y               0x2000  /* y coord measurement */
-+#define WM97XX_ADCSEL_PRES    0x3000  /* pressure measurement */
-+#define WM97XX_ADCSEL_MASK    0x7000
-+#define WM97XX_COO                    0x0800  /* enable coordinate mode */
-+#define WM97XX_CTC                    0x0400  /* enable continuous mode */
-+#define WM97XX_CM_RATE_93     0x0000  /* 93.75Hz continuous rate */
-+#define WM97XX_CM_RATE_187    0x0100  /* 187.5Hz continuous rate */
-+#define WM97XX_CM_RATE_375    0x0200  /* 375Hz continuous rate */
-+#define WM97XX_CM_RATE_750    0x0300  /* 750Hz continuous rate */
-+#define WM97XX_CM_RATE_8K     0x00f0  /* 8kHz continuous rate */
-+#define WM97XX_CM_RATE_12K    0x01f0  /* 12kHz continuous rate */
-+#define WM97XX_CM_RATE_24K    0x02f0  /* 24kHz continuous rate */
-+#define WM97XX_CM_RATE_48K    0x03f0  /* 48kHz continuous rate */
-+#define WM97XX_CM_RATE_MASK   0x03f0
-+#define WM97XX_RATE(i)                (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0))
-+#define WM97XX_DELAY(i)               ((i << 4) & 0x00f0)     /* sample delay times */
-+#define WM97XX_DELAY_MASK     0x00f0
-+#define WM97XX_SLEN                   0x0008  /* slot read back enable */
-+#define WM97XX_SLT(i)         ((i - 5) & 0x7) /* touchpanel slot selection (5-11) */
-+#define WM97XX_SLT_MASK               0x0007
-+#define WM97XX_PRP_DETW               0x4000  /* pen detect on, digitiser off, wake up */
-+#define WM97XX_PRP_DET                0x8000  /* pen detect on, digitiser off, no wake up */
-+#define WM97XX_PRP_DET_DIG    0xc000  /* pen detect on, digitiser on */
-+#define WM97XX_RPR                    0x2000  /* wake up on pen down */
-+#define WM97XX_PEN_DOWN               0x8000  /* pen is down */
-+#define WM97XX_ADCSRC_MASK    0x7000  /* ADC source mask */
-+
-+#define WM97XX_AUX_ID1                0x8001
-+#define WM97XX_AUX_ID2                0x8002
-+#define WM97XX_AUX_ID3                0x8003
-+#define WM97XX_AUX_ID4                0x8004
-+
-+
-+/* WM9712 Bits */
-+#define WM9712_45W                    0x1000  /* set for 5-wire touchscreen */
-+#define WM9712_PDEN                   0x0800  /* measure only when pen down */
-+#define WM9712_WAIT                   0x0200  /* wait until adc is read before next sample */
-+#define WM9712_PIL                    0x0100  /* current used for pressure measurement. set 400uA else 200uA */
-+#define WM9712_MASK_HI                0x0040  /* hi on mask pin (47) stops conversions */
-+#define WM9712_MASK_EDGE      0x0080  /* rising/falling edge on pin delays sample */
-+#define       WM9712_MASK_SYNC        0x00c0  /* rising/falling edge on mask initiates sample */
-+#define WM9712_RPU(i)         (i&0x3f)        /* internal pull up on pen detect (64k / rpu) */
-+#define WM9712_PD(i)          (0x1 << i)      /* power management */
-+
-+/* WM9712 Registers */
-+#define AC97_WM9712_POWER     0x24
-+#define AC97_WM9712_REV               0x58
-+
-+/* WM9705 Bits */
-+#define WM9705_PDEN                   0x1000  /* measure only when pen is down */
-+#define WM9705_PINV                   0x0800  /* inverts sense of pen down output */
-+#define WM9705_BSEN                   0x0400  /* BUSY flag enable, pin47 is 1 when busy */
-+#define WM9705_BINV                   0x0200  /* invert BUSY (pin47) output */
-+#define WM9705_WAIT                   0x0100  /* wait until adc is read before next sample */
-+#define WM9705_PIL                    0x0080  /* current used for pressure measurement. set 400uA else 200uA */
-+#define WM9705_PHIZ                   0x0040  /* set PHONE and PCBEEP inputs to high impedance */
-+#define WM9705_MASK_HI                0x0010  /* hi on mask stops conversions */
-+#define WM9705_MASK_EDGE      0x0020  /* rising/falling edge on pin delays sample */
-+#define       WM9705_MASK_SYNC        0x0030  /* rising/falling edge on mask initiates sample */
-+#define WM9705_PDD(i)         (i & 0x000f)    /* pen detect comparator threshold */
-+
-+
-+/* WM9713 Bits */
-+#define WM9713_PDPOL          0x0400  /* Pen down polarity */
-+#define WM9713_POLL                   0x0200  /* initiate a polling measurement */
-+#define WM9713_CTC                    0x0100  /* enable continuous mode */
-+#define WM9713_ADCSEL_X               0x0002  /* X measurement */
-+#define WM9713_ADCSEL_Y               0x0004  /* Y measurement */
-+#define WM9713_ADCSEL_PRES    0x0008  /* Pressure measurement */
-+#define WM9713_COO                    0x0001  /* enable coordinate mode */
-+#define WM9713_PDEN                   0x0800  /* measure only when pen down */
-+#define WM9713_ADCSEL_MASK    0x00fe  /* ADC selection mask */
-+#define WM9713_WAIT                   0x0200  /* coordinate wait */
-+
-+/* AUX ADC ID's */
-+#define TS_COMP1                      0x0
-+#define TS_COMP2                      0x1
-+#define TS_BMON                               0x2
-+#define TS_WIPER                      0x3
-+
-+/* ID numbers */
-+#define WM97XX_ID1                    0x574d
-+#define WM9712_ID2                    0x4c12
-+#define WM9705_ID2                    0x4c05
-+#define WM9713_ID2                    0x4c13
-+
-+/* Codec GPIO's */
-+#define WM97XX_MAX_GPIO               16
-+#define WM97XX_GPIO_1         (1 << 1)
-+#define WM97XX_GPIO_2         (1 << 2)
-+#define WM97XX_GPIO_3         (1 << 3)
-+#define WM97XX_GPIO_4         (1 << 4)
-+#define WM97XX_GPIO_5         (1 << 5)
-+#define WM97XX_GPIO_6         (1 << 6)
-+#define WM97XX_GPIO_7         (1 << 7)
-+#define WM97XX_GPIO_8         (1 << 8)
-+#define WM97XX_GPIO_9         (1 << 9)
-+#define WM97XX_GPIO_10                (1 << 10)
-+#define WM97XX_GPIO_11                (1 << 11)
-+#define WM97XX_GPIO_12                (1 << 12)
-+#define WM97XX_GPIO_13                (1 << 13)
-+#define WM97XX_GPIO_14                (1 << 14)
-+#define WM97XX_GPIO_15                (1 << 15)
-+
-+
-+#define AC97_LINK_FRAME               21      /* time in uS for AC97 link frame */
-+
-+
-+/*---------------- Return codes from sample reading functions ---------------*/
-+
-+/* More data is available; call the sample gathering function again */
-+#define RC_AGAIN                      0x00000001
-+/* The returned sample is valid */
-+#define RC_VALID                      0x00000002
-+/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */
-+#define RC_PENUP                      0x00000004
-+/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful
-+   to tell the handler that the pen is down but we don't know yet his coords,
-+   so the handler should not sleep or wait for pendown irq) */
-+#define RC_PENDOWN                    0x00000008
-+
-+/* The wm97xx driver provides a private API for writing platform-specific
-+ * drivers.
-+ */
-+
-+/* The structure used to return arch specific sampled data into */
-+struct wm97xx_data {
-+    int x;
-+    int y;
-+    int p;
-+};
-+
-+/* Codec GPIO status
-+ */
-+typedef enum {
-+    WM97XX_GPIO_HIGH,
-+    WM97XX_GPIO_LOW
-+} wm97xx_gpio_status_t;
-+
-+/* Codec GPIO direction
-+ */
-+typedef enum {
-+    WM97XX_GPIO_IN,
-+    WM97XX_GPIO_OUT
-+} wm97xx_gpio_dir_t;
-+
-+/* Codec GPIO polarity
-+ */
-+typedef enum {
-+    WM97XX_GPIO_POL_HIGH,
-+    WM97XX_GPIO_POL_LOW
-+} wm97xx_gpio_pol_t;
-+
-+/* Codec GPIO sticky
-+ */
-+typedef enum {
-+    WM97XX_GPIO_STICKY,
-+    WM97XX_GPIO_NOTSTICKY
-+} wm97xx_gpio_sticky_t;
-+
-+/* Codec GPIO wake
-+ */
-+typedef enum {
-+    WM97XX_GPIO_WAKE,
-+    WM97XX_GPIO_NOWAKE
-+} wm97xx_gpio_wake_t;
-+
-+
-+/*
-+ * Digitiser ioctl commands
-+ */
-+#define WM97XX_DIG_START      0x1
-+#define WM97XX_DIG_STOP               0x2
-+#define WM97XX_PHY_INIT               0x3
-+#define WM97XX_AUX_PREPARE    0x4
-+#define WM97XX_DIG_RESTORE    0x5
-+
-+struct wm97xx;
-+extern struct wm97xx_codec_drv wm97xx_codec;
-+
-+/*
-+ * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs
-+ */
-+struct wm97xx_codec_drv {
-+      u16 id;
-+    char *name;
-+      int (*poll_sample) (struct wm97xx *, int adcsel, int *sample);  /* read 1 sample */
-+      int (*poll_touch) (struct wm97xx *, struct wm97xx_data *);      /* read X,Y,[P] in poll */
-+      int (*digitiser_ioctl) (struct wm97xx *, int cmd);
-+      int (*acc_enable) (struct wm97xx *, int enable);
-+};
-+
-+
-+/* Machine specific and accelerated touch operations */
-+struct wm97xx_mach_ops {
-+
-+      /* accelerated touch readback - coords are transmited on AC97 link */
-+      int acc_enabled;
-+    void (*acc_pen_up) (struct wm97xx *);
-+    int (*acc_pen_down) (struct wm97xx *);
-+    int (*acc_startup) (struct wm97xx *);
-+    void (*acc_shutdown) (struct wm97xx *);
-+
-+    /* pre and post sample - can be used to minimise any analog noise */
-+    void (*pre_sample) (int);  /* function to run before sampling */
-+    void (*post_sample) (int);  /* function to run after sampling */
-+};
-+
-+struct wm97xx {
-+      u16 dig[3], id, gpio[6], misc;  /* Cached codec registers */
-+      u16 dig_save[3];                /* saved during aux reading */
-+      struct wm97xx_codec_drv *codec; /* attached codec driver*/
-+      struct input_dev* input_dev;    /* touchscreen input device */
-+      ac97_t *ac97;                   /* ALSA codec access */
-+      struct device *dev;             /* ALSA device */
-+    struct device *battery_dev;
-+    struct device *touch_dev;
-+    struct wm97xx_mach_ops *mach_ops;
-+    struct mutex codec_mutex;
-+      struct completion ts_init;
-+      struct completion ts_exit;
-+      struct task_struct *ts_task;
-+      unsigned int pen_irq;   /* Pen IRQ number in use */
-+      wait_queue_head_t pen_irq_wait; /* Pen IRQ wait queue */
-+      struct workqueue_struct *pen_irq_workq;
-+      struct work_struct pen_event_work;
-+      u16 acc_slot; /* AC97 slot used for acc touch data */
-+      u16 acc_rate; /* acc touch data rate */
-+      unsigned int ts_use_count;
-+      unsigned pen_is_down:1; /* Pen is down */
-+      unsigned aux_waiting:1; /* aux measurement waiting */
-+      unsigned pen_probably_down:1;   /* used in polling mode */
-+};
-+
-+/* Codec GPIO access (not supported on WM9705)
-+ * This can be used to set/get codec GPIO and Virtual GPIO status.
-+ */
-+wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio);
-+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
-+                        wm97xx_gpio_status_t status);
-+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio,
-+                                   wm97xx_gpio_dir_t dir,
-+                                   wm97xx_gpio_pol_t pol,
-+                                   wm97xx_gpio_sticky_t sticky,
-+                                   wm97xx_gpio_wake_t wake);
-+
-+/* codec AC97 IO access */
-+int wm97xx_reg_read(struct wm97xx *wm, u16 reg);
-+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val);
-+
-+/* aux adc readback */
-+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel);
-+
-+/* machine ops */
-+int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *);
-+void wm97xx_unregister_mach_ops(struct wm97xx *);
-+
-+extern struct bus_type wm97xx_bus_type;
-+#endif