From 7ce9708030347099c29ad4586dc66b2ed82f80b7 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:17:52 -0400 Subject: [PATCH] --- yaml --- r: 93227 b: refs/heads/master c: 8a0f83eacc1bb8899094b17483de95ddf2d8fcc6 h: refs/heads/master i: 93225: 11ca75a7fad39a06e34e1197b73119d23cee9ded 93223: 2e1f3ac17ef66355a4a09cb9eedd48628d8fe9da v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 10 - trunk/drivers/input/joystick/xpad.c | 21 +- trunk/drivers/input/keyboard/locomokbd.c | 73 +- trunk/drivers/input/keyboard/tosakbd.c | 21 +- trunk/drivers/input/mouse/appletouch.c | 13 +- trunk/drivers/input/touchscreen/Kconfig | 53 -- trunk/drivers/input/touchscreen/Makefile | 7 - trunk/drivers/input/touchscreen/ads7846.c | 22 +- .../input/touchscreen/mainstone-wm97xx.c | 302 ------- trunk/drivers/input/touchscreen/wm9705.c | 353 -------- trunk/drivers/input/touchscreen/wm9712.c | 462 ---------- trunk/drivers/input/touchscreen/wm9713.c | 460 ---------- trunk/drivers/input/touchscreen/wm97xx-core.c | 789 ------------------ trunk/include/linux/spi/ads7846.h | 3 +- trunk/include/linux/wm97xx.h | 311 ------- 16 files changed, 59 insertions(+), 2843 deletions(-) delete mode 100644 trunk/drivers/input/touchscreen/mainstone-wm97xx.c delete mode 100644 trunk/drivers/input/touchscreen/wm9705.c delete mode 100644 trunk/drivers/input/touchscreen/wm9712.c delete mode 100644 trunk/drivers/input/touchscreen/wm9713.c delete mode 100644 trunk/drivers/input/touchscreen/wm97xx-core.c delete mode 100644 trunk/include/linux/wm97xx.h diff --git a/[refs] b/[refs] index c8a74a5b8a7f..9f64f1f8cad4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5550fbaeb3cc88fe2982e9b5351073173d733f30 +refs/heads/master: 8a0f83eacc1bb8899094b17483de95ddf2d8fcc6 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 87bdced169a4..90dcbbcad91c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -4343,16 +4343,6 @@ L: linux-wireless@vger.kernel.org W: http://oops.ghostprotocols.net:81/blog S: Maintained -WM97XX TOUCHSCREEN DRIVERS -P: Mark Brown -M: broonie@opensource.wolfsonmicro.com -P: Liam Girdwood -M: liam.girdwood@wolfsonmicro.com -L: linux-input@vger.kernel.org -T: git git://opensource.wolfsonmicro.com/linux-2.6-touch -W: http://opensource.wolfsonmicro.com/node/7 -S: Supported - X.25 NETWORK LAYER P: Henner Eisen M: eis@baty.hanse.de diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/input/joystick/xpad.c index 0380597249bb..8804ad30dae2 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/input/joystick/xpad.c @@ -91,6 +91,7 @@ #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 +#define XTYPE_UNKNOWN 2 static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); @@ -138,7 +139,7 @@ static const struct xpad_device { { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX } + { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } }; static const signed short xpad_btn[] = { @@ -173,12 +174,20 @@ static const signed short xpad_abs_pad[] = { -1 /* terminating entry */ }; -/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only - * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, - * but we need only one of them. */ +/* Xbox 360 has a vendor-specific class, so we cannot match it with only + * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we + * match against vendor id as well. Also, some Xbox 360 devices have multiple + * interface protocols, we only need protocol 1. */ +#define XPAD_XBOX360_VENDOR(vend) \ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ + .idVendor = (vend), \ + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ + .bInterfaceSubClass = 93, \ + .bInterfaceProtocol = 1 + static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ - { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ + { XPAD_XBOX360_VENDOR(0x045e) }, /* Microsoft X-Box 360 controllers */ { } }; @@ -645,6 +654,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = dpad_to_buttons; + if (xpad->xtype == XTYPE_UNKNOWN) + xpad->xtype = (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC); xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); diff --git a/trunk/drivers/input/keyboard/locomokbd.c b/trunk/drivers/input/keyboard/locomokbd.c index 9caed30f3bbb..5a0ca18d6755 100644 --- a/trunk/drivers/input/keyboard/locomokbd.c +++ b/trunk/drivers/input/keyboard/locomokbd.c @@ -1,12 +1,14 @@ /* - * LoCoMo keyboard driver for Linux-based ARM PDAs: - * - SHARP Zaurus Collie (SL-5500) - * - SHARP Zaurus Poodle (SL-5600) + * Copyright (c) 2005 John Lenz * - * Copyright (c) 2005 John Lenz * Based on from xtkbd.c - * - * + */ + +/* + * LoCoMo keyboard driver for Linux/ARM + */ + +/* * 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 @@ -45,8 +47,7 @@ MODULE_LICENSE("GPL"); #define KEY_CONTACT KEY_F18 #define KEY_CENTER KEY_F15 -static const unsigned char -locomokbd_keycode[LOCOMOKBD_NUMKEYS] __devinitconst = { +static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ @@ -66,21 +67,22 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] __devinitconst = { #define KB_COLS 8 #define KB_ROWMASK(r) (1 << (r)) #define SCANCODE(c,r) ( ((c)<<4) + (r) + 1 ) +#define NR_SCANCODES 128 #define KB_DELAY 8 #define SCAN_INTERVAL (HZ/10) +#define LOCOMOKBD_PRESSED 1 struct locomokbd { unsigned char keycode[LOCOMOKBD_NUMKEYS]; struct input_dev *input; char phys[32]; + struct locomo_dev *ldev; unsigned long base; spinlock_t lock; struct timer_list timer; - unsigned long suspend_jiffies; - unsigned int count_cancel; }; /* helper functions for reading the keyboard matrix */ @@ -126,7 +128,7 @@ static inline void locomokbd_reset_col(unsigned long membase, int col) /* Scan the hardware keyboard and push any changes up through the input layer */ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) { - unsigned int row, col, rowd; + unsigned int row, col, rowd, scancode; unsigned long flags; unsigned int num_pressed; unsigned long membase = locomokbd->base; @@ -143,33 +145,13 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) rowd = ~locomo_readl(membase + LOCOMO_KIB); for (row = 0; row < KB_ROWS; row++) { - unsigned int scancode, pressed, key; - scancode = SCANCODE(col, row); - pressed = rowd & KB_ROWMASK(row); - key = locomokbd->keycode[scancode]; - - input_report_key(locomokbd->input, key, pressed); - if (likely(!pressed)) - continue; - - num_pressed++; - - /* The "Cancel/ESC" key is labeled "On/Off" on - * Collie and Poodle and should suspend the device - * if it was pressed for more than a second. */ - if (unlikely(key == KEY_ESC)) { - if (!time_after(jiffies, - locomokbd->suspend_jiffies + HZ)) - continue; - if (locomokbd->count_cancel++ - != (HZ/SCAN_INTERVAL + 1)) - continue; - input_event(locomokbd->input, EV_PWR, - KEY_SUSPEND, 1); - locomokbd->suspend_jiffies = jiffies; - } else - locomokbd->count_cancel = 0; + if (rowd & KB_ROWMASK(row)) { + num_pressed += 1; + input_report_key(locomokbd->input, locomokbd->keycode[scancode], 1); + } else { + input_report_key(locomokbd->input, locomokbd->keycode[scancode], 0); + } } locomokbd_reset_col(membase, col); } @@ -180,8 +162,6 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) /* if any keys are pressed, enable the timer */ if (num_pressed) mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL); - else - locomokbd->count_cancel = 0; spin_unlock_irqrestore(&locomokbd->lock, flags); } @@ -206,11 +186,10 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) static void locomokbd_timer_callback(unsigned long data) { struct locomokbd *locomokbd = (struct locomokbd *) data; - locomokbd_scankeyboard(locomokbd); } -static int __devinit locomokbd_probe(struct locomo_dev *dev) +static int locomokbd_probe(struct locomo_dev *dev) { struct locomokbd *locomokbd; struct input_dev *input_dev; @@ -232,6 +211,7 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) goto err_free_mem; } + locomokbd->ldev = dev; locomo_set_drvdata(dev, locomokbd); locomokbd->base = (unsigned long) dev->mapbase; @@ -242,8 +222,6 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) locomokbd->timer.function = locomokbd_timer_callback; locomokbd->timer.data = (unsigned long) locomokbd; - locomokbd->suspend_jiffies = jiffies; - locomokbd->input = input_dev; strcpy(locomokbd->phys, "locomokbd/input0"); @@ -255,10 +233,9 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) input_dev->id.version = 0x0100; input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | - BIT_MASK(EV_PWR); + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); input_dev->keycode = locomokbd->keycode; - input_dev->keycodesize = sizeof(locomokbd_keycode[0]); + input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); @@ -291,7 +268,7 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) return err; } -static int __devexit locomokbd_remove(struct locomo_dev *dev) +static int locomokbd_remove(struct locomo_dev *dev) { struct locomokbd *locomokbd = locomo_get_drvdata(dev); @@ -315,7 +292,7 @@ static struct locomo_driver keyboard_driver = { }, .devid = LOCOMO_DEVID_KEYBOARD, .probe = locomokbd_probe, - .remove = __devexit_p(locomokbd_remove), + .remove = locomokbd_remove, }; static int __init locomokbd_init(void) diff --git a/trunk/drivers/input/keyboard/tosakbd.c b/trunk/drivers/input/keyboard/tosakbd.c index a247006757de..3884d1e3f070 100644 --- a/trunk/drivers/input/keyboard/tosakbd.c +++ b/trunk/drivers/input/keyboard/tosakbd.c @@ -52,7 +52,7 @@ KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_ struct tosakbd { unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)]; struct input_dev *input; - int suspended; + spinlock_t lock; /* protect kbd scanning */ struct timer_list timer; }; @@ -133,9 +133,6 @@ static void tosakbd_scankeyboard(struct platform_device *dev) spin_lock_irqsave(&tosakbd->lock, flags); - if (tosakbd->suspended) - goto out; - for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) { /* * Discharge the output driver capacitatance @@ -177,7 +174,6 @@ static void tosakbd_scankeyboard(struct platform_device *dev) if (num_pressed) mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL); - out: spin_unlock_irqrestore(&tosakbd->lock, flags); } @@ -204,7 +200,6 @@ static irqreturn_t tosakbd_interrupt(int irq, void *__dev) static void tosakbd_timer_callback(unsigned long __dev) { struct platform_device *dev = (struct platform_device *)__dev; - tosakbd_scankeyboard(dev); } @@ -212,13 +207,6 @@ static void tosakbd_timer_callback(unsigned long __dev) static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) { struct tosakbd *tosakbd = platform_get_drvdata(dev); - unsigned long flags; - - spin_lock_irqsave(&tosakbd->lock, flags); - PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT); - PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT); - tosakbd->suspended = 1; - spin_unlock_irqrestore(&tosakbd->lock, flags); del_timer_sync(&tosakbd->timer); @@ -227,9 +215,6 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) static int tosakbd_resume(struct platform_device *dev) { - struct tosakbd *tosakbd = platform_get_drvdata(dev); - - tosakbd->suspended = 0; tosakbd_scankeyboard(dev); return 0; @@ -380,8 +365,8 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) { return error; } -static int __devexit tosakbd_remove(struct platform_device *dev) -{ +static int __devexit tosakbd_remove(struct platform_device *dev) { + int i; struct tosakbd *tosakbd = platform_get_drvdata(dev); diff --git a/trunk/drivers/input/mouse/appletouch.c b/trunk/drivers/input/mouse/appletouch.c index 8dd3942f3022..b4423a471f02 100644 --- a/trunk/drivers/input/mouse/appletouch.c +++ b/trunk/drivers/input/mouse/appletouch.c @@ -62,10 +62,6 @@ #define GEYSER4_ISO_PRODUCT_ID 0x021B #define GEYSER4_JIS_PRODUCT_ID 0x021C -#define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229 -#define GEYSER4_HF_ISO_PRODUCT_ID 0x022A -#define GEYSER4_HF_JIS_PRODUCT_ID 0x022B - #define ATP_DEVICE(prod) \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ USB_DEVICE_ID_MATCH_INT_CLASS | \ @@ -97,10 +93,6 @@ static struct usb_device_id atp_table [] = { { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) }, - /* Terminating entry */ { } }; @@ -225,10 +217,7 @@ static inline int atp_is_geyser_3(struct atp *dev) (productId == GEYSER3_JIS_PRODUCT_ID) || (productId == GEYSER4_ANSI_PRODUCT_ID) || (productId == GEYSER4_ISO_PRODUCT_ID) || - (productId == GEYSER4_JIS_PRODUCT_ID) || - (productId == GEYSER4_HF_ANSI_PRODUCT_ID) || - (productId == GEYSER4_HF_ISO_PRODUCT_ID) || - (productId == GEYSER4_HF_JIS_PRODUCT_ID); + (productId == GEYSER4_JIS_PRODUCT_ID); } /* diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index 565ec711c2ee..90e8e92dfe47 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -185,59 +185,6 @@ config TOUCHSCREEN_UCB1400 To compile this driver as a module, choose M here: the module will be called ucb1400_ts. -config TOUCHSCREEN_WM97XX - tristate "Support for WM97xx AC97 touchscreen controllers" - depends on AC97_BUS - help - Say Y here if you have a Wolfson Microelectronics WM97xx - touchscreen connected to your system. Note that this option - only enables core driver, you will also need to select - support for appropriate chip below. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called wm97xx-ts. - -config TOUCHSCREEN_WM9705 - bool "WM9705 Touchscreen interface support" - depends on TOUCHSCREEN_WM97XX - help - Say Y here if you have a Wolfson Microelectronics WM9705 - touchscreen controller connected to your system. - - If unsure, say N. - -config TOUCHSCREEN_WM9712 - bool "WM9712 Touchscreen interface support" - depends on TOUCHSCREEN_WM97XX - help - Say Y here if you have a Wolfson Microelectronics WM9712 - touchscreen controller connected to your system. - - If unsure, say N. - -config TOUCHSCREEN_WM9713 - bool "WM9713 Touchscreen interface support" - depends on TOUCHSCREEN_WM97XX - help - Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen - controller connected to your system. - - If unsure, say N. - -config TOUCHSCREEN_WM97XX_MAINSTONE - tristate "WM97xx Mainstone accelerated touch" - depends on TOUCHSCREEN_WM97XX && ARCH_PXA - help - Say Y here for support for streaming mode with WM97xx touchscreens - on Mainstone systems. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called mainstone-wm97xx. - config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" depends on USB_ARCH_HAS_HCD diff --git a/trunk/drivers/input/touchscreen/Makefile b/trunk/drivers/input/touchscreen/Makefile index 3c096d75651d..35d4097df35a 100644 --- a/trunk/drivers/input/touchscreen/Makefile +++ b/trunk/drivers/input/touchscreen/Makefile @@ -4,8 +4,6 @@ # Each configuration option enables a list of files. -wm97xx-ts-y := wm97xx-core.o - obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o @@ -21,8 +19,3 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o -obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o -wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o -wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o -wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o -obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index a571aa965da0..57a1c28bf122 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -87,7 +87,6 @@ struct ads7846 { #endif u16 model; - u16 vref_mv; u16 vref_delay_usecs; u16 x_plate_ohms; u16 pressure_max; @@ -185,6 +184,9 @@ struct ads7846 { * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; * ads7846 lets that pin be unconnected, to use internal vREF. */ +static unsigned vREF_mV; +module_param(vREF_mV, uint, 0); +MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts"); struct ser_req { u8 ref_on; @@ -211,6 +213,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) struct ads7846 *ts = dev_get_drvdata(dev); struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); int status; + int uninitialized_var(sample); int use_internal; if (!req) @@ -267,13 +270,13 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) if (status == 0) { /* on-wire is a must-ignore bit, a BE12 value, then padding */ - status = be16_to_cpu(req->sample); - status = status >> 3; - status &= 0x0fff; + sample = be16_to_cpu(req->sample); + sample = sample >> 3; + sample &= 0x0fff; } kfree(req); - return status; + return status ? status : sample; } #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) @@ -314,7 +317,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) unsigned retval = v; /* external resistors may scale vAUX into 0..vREF */ - retval *= ts->vref_mv; + retval *= vREF_mV; retval = retval >> 12; return retval; } @@ -372,14 +375,14 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) /* hwmon sensors need a reference voltage */ switch (ts->model) { case 7846: - if (!ts->vref_mv) { + if (!vREF_mV) { dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); - ts->vref_mv = 2500; + vREF_mV = 2500; } break; case 7845: case 7843: - if (!ts->vref_mv) { + if (!vREF_mV) { dev_warn(&spi->dev, "external vREF for ADS%d not specified\n", ts->model); @@ -872,7 +875,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->spi = spi; ts->input = input_dev; - ts->vref_mv = pdata->vref_mv; hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ts->timer.function = ads7846_timer; diff --git a/trunk/drivers/input/touchscreen/mainstone-wm97xx.c b/trunk/drivers/input/touchscreen/mainstone-wm97xx.c deleted file mode 100644 index a79f029b91c0..000000000000 --- a/trunk/drivers/input/touchscreen/mainstone-wm97xx.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * mainstone-wm97xx.c -- Mainstone Continuous Touch screen driver for - * Wolfson WM97xx AC97 Codecs. - * - * Copyright 2004, 2007 Wolfson Microelectronics PLC. - * Author: Liam Girdwood - * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com - * Parts Copyright : Ian Molton - * Andrew Zabolotny - * - * 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 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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; -static u16 last, tries; - -/* - * 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; -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; -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 -static void wm97xx_acc_pen_up(struct wm97xx *wm) -{ - schedule_timeout_uninterruptible(1); - - while (MISR & (1 << 2)) - MODR; -} -#else -static void wm97xx_acc_pen_up(struct wm97xx *wm) -{ - int count = 16; - schedule_timeout_uninterruptible(1); - - while (count < 16) { - MODR; - count--; - } -} -#endif - -static int wm97xx_acc_pen_down(struct wm97xx *wm) -{ - u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES; - int reads = 0; - - /* When the AC97 queue has been drained we need to allow time - * to buffer up samples otherwise we end up spinning polling - * for samples. The controller can't have a suitably low - * threashold set to use the notifications it gives. - */ - schedule_timeout_uninterruptible(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 & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || - (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || - (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES) - goto up; - - /* coordinate is good */ - tries = 0; - 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; -} - -static 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; - dev_info(wm->dev, - "mainstone 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: - dev_err(wm->dev, - "pen down irq not supported on this device\n"); - pen_int = 0; - break; - } - } - - return 0; -} - -static 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 void wm97xx_irq_enable(struct wm97xx *wm, int enable) -{ - if (enable) - enable_irq(wm->pen_irq); - else - disable_irq(wm->pen_irq); -} - -static struct wm97xx_mach_ops mainstone_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, - .irq_enable = wm97xx_irq_enable, - .irq_gpio = WM97XX_GPIO_2, -}; - -static int mainstone_wm97xx_probe(struct platform_device *pdev) -{ - struct wm97xx *wm = platform_get_drvdata(pdev); - - return wm97xx_register_mach_ops(wm, &mainstone_mach_ops); -} - -static int mainstone_wm97xx_remove(struct platform_device *pdev) -{ - struct wm97xx *wm = platform_get_drvdata(pdev); - - wm97xx_unregister_mach_ops(wm); - return 0; -} - -static struct platform_driver mainstone_wm97xx_driver = { - .probe = mainstone_wm97xx_probe, - .remove = mainstone_wm97xx_remove, - .driver = { - .name = "wm97xx-touch", - }, -}; - -static int __init mainstone_wm97xx_init(void) -{ - return platform_driver_register(&mainstone_wm97xx_driver); -} - -static void __exit mainstone_wm97xx_exit(void) -{ - platform_driver_unregister(&mainstone_wm97xx_driver); -} - -module_init(mainstone_wm97xx_init); -module_exit(mainstone_wm97xx_exit); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood "); -MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm9705.c b/trunk/drivers/input/touchscreen/wm9705.c deleted file mode 100644 index 978e1a13ffc7..000000000000 --- a/trunk/drivers/input/touchscreen/wm9705.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. - * - * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. - * Author: Liam Girdwood - * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com - * Parts Copyright : Ian Molton - * Andrew Zabolotny - * Russell King - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define TS_NAME "wm97xx" -#define WM9705_VERSION "1.00" -#define DEFAULT_PRESSURE 0xb0c0 - -/* - * 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; -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; -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 wm9705_phy_init(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; - dev_dbg(wm->dev, - "setting pressure measurement current to 400uA."); - } else if (pil) - dev_dbg(wm->dev, - "setting pressure measurement current to 200uA."); - if (!pil) - pressure = 0; - - /* polling mode sample settling delay */ - if (delay != 4) { - if (delay < 0 || delay > 15) { - dev_dbg(wm->dev, "supplied delay out of range."); - delay = 4; - } - } - dig1 &= 0xff0f; - dig1 |= WM97XX_DELAY(delay); - dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.", - delay_table[delay]); - - /* WM9705 pdd */ - dig2 |= (pdd & 0x000f); - dev_dbg(wm->dev, "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 void wm9705_dig_enable(struct wm97xx *wm, int enable) -{ - if (enable) { - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, - wm->dig[2] | WM97XX_PRP_DET_DIG); - wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ - } else - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, - wm->dig[2] & ~WM97XX_PRP_DET_DIG); -} - -static void wm9705_aux_prepare(struct wm97xx *wm) -{ - 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); -} - -static void wm9705_dig_restore(struct wm97xx *wm) -{ - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); -} - -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 - dev_dbg(wm->dev, "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) { - dev_dbg(wm->dev, "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; - - rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); - if (rc != RC_VALID) - return rc; - rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); - if (rc != RC_VALID) - return rc; - if (pil) { - rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p); - if (rc != 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 wm9705_codec = { - .id = WM9705_ID2, - .name = "wm9705", - .poll_sample = wm9705_poll_sample, - .poll_touch = wm9705_poll_touch, - .acc_enable = wm9705_acc_enable, - .phy_init = wm9705_phy_init, - .dig_enable = wm9705_dig_enable, - .dig_restore = wm9705_dig_restore, - .aux_prepare = wm9705_aux_prepare, -}; -EXPORT_SYMBOL_GPL(wm9705_codec); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood "); -MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm9712.c b/trunk/drivers/input/touchscreen/wm9712.c deleted file mode 100644 index 0b6e4cfa6a21..000000000000 --- a/trunk/drivers/input/touchscreen/wm9712.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. - * - * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. - * Author: Liam Girdwood - * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com - * Parts Copyright : Ian Molton - * Andrew Zabolotny - * Russell King - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define TS_NAME "wm97xx" -#define WM9712_VERSION "1.00" -#define DEFAULT_PRESSURE 0xb0c0 - -/* - * 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 = 8; -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; -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; -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; -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 wm9712_phy_init(struct wm97xx *wm) -{ - u16 dig1 = 0; - u16 dig2 = WM97XX_RPR | WM9712_RPU(1); - - /* WM9712 rpu */ - if (rpu) { - dig2 &= 0xffc0; - dig2 |= WM9712_RPU(rpu); - dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms", - 64000 / rpu); - } - - /* touchpanel pressure current*/ - if (pil == 2) { - dig2 |= WM9712_PIL; - dev_dbg(wm->dev, - "setting pressure measurement current to 400uA."); - } else if (pil) - dev_dbg(wm->dev, - "setting pressure measurement current to 200uA."); - if (!pil) - pressure = 0; - - /* WM9712 five wire */ - if (five_wire) { - dig2 |= WM9712_45W; - dev_dbg(wm->dev, "setting 5-wire touchscreen mode."); - } - - /* polling mode sample settling delay */ - if (delay < 0 || delay > 15) { - dev_dbg(wm->dev, "supplied delay out of range."); - delay = 4; - } - dig1 &= 0xff0f; - dig1 |= WM97XX_DELAY(delay); - dev_dbg(wm->dev, "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 void wm9712_dig_enable(struct wm97xx *wm, int enable) -{ - u16 dig2 = wm->dig[2]; - - if (enable) { - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, - dig2 | WM97XX_PRP_DET_DIG); - wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ - } else - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, - dig2 & ~WM97XX_PRP_DET_DIG); -} - -static void wm9712_aux_prepare(struct wm97xx *wm) -{ - 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); -} - -static void wm9712_dig_restore(struct wm97xx *wm) -{ - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); -} - -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 - dev_dbg(wm->dev, "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) { - dev_dbg(wm->dev, "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_rd = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); - if (!(data_rd & 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 - dev_dbg(wm->dev, "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) || !(data->y & WM97XX_PEN_DOWN)) { - wm->pen_probably_down = 0; - return RC_PENUP; - } - return RC_VALID; -err: - return 0; -} - -/* - * Sample the WM9712 touchscreen in polling mode - */ -static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) -{ - int rc; - - if (coord) { - rc = wm9712_poll_coord(wm, data); - if (rc != RC_VALID) - return rc; - } else { - rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); - if (rc != RC_VALID) - return rc; - - rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); - if (rc != RC_VALID) - return rc; - - if (pil && !five_wire) { - rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, - &data->p); - if (rc != 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); - if (ret < 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 wm9712_codec = { - .id = WM9712_ID2, - .name = "wm9712", - .poll_sample = wm9712_poll_sample, - .poll_touch = wm9712_poll_touch, - .acc_enable = wm9712_acc_enable, - .phy_init = wm9712_phy_init, - .dig_enable = wm9712_dig_enable, - .dig_restore = wm9712_dig_restore, - .aux_prepare = wm9712_aux_prepare, -}; -EXPORT_SYMBOL_GPL(wm9712_codec); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood "); -MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm9713.c b/trunk/drivers/input/touchscreen/wm9713.c deleted file mode 100644 index 01278bd7e65c..000000000000 --- a/trunk/drivers/input/touchscreen/wm9713.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. - * - * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. - * Author: Liam Girdwood - * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com - * Parts Copyright : Ian Molton - * Andrew Zabolotny - * Russell King - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define TS_NAME "wm97xx" -#define WM9713_VERSION "1.00" -#define DEFAULT_PRESSURE 0xb0c0 - -/* - * 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 = 8; -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; -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; -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; -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 wm9713_phy_init(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); - dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n", - 64000 / rpu); - } - - /* touchpanel pressure */ - if (pil == 2) { - dig3 |= WM9712_PIL; - dev_info(wm->dev, - "setting pressure measurement current to 400uA."); - } else if (pil) - dev_info(wm->dev, - "setting pressure measurement current to 200uA."); - if (!pil) - pressure = 0; - - /* sample settling delay */ - if (delay < 0 || delay > 15) { - dev_info(wm->dev, "supplied delay out of range."); - delay = 4; - dev_info(wm->dev, "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 void wm9713_dig_enable(struct wm97xx *wm, int enable) -{ - u16 val; - - if (enable) { - 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 */ - } else { - 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); - } -} - -static void wm9713_dig_restore(struct wm97xx *wm) -{ - 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]); -} - -static void wm9713_aux_prepare(struct wm97xx *wm) -{ - 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); -} - -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 - dev_dbg(wm->dev, "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) { - dev_dbg(wm->dev, "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 val = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); - if (!(val & 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 |= WM9713_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 - dev_dbg(wm->dev, "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) || !(data->y & WM97XX_PEN_DOWN)) { - wm->pen_probably_down = 0; - return RC_PENUP; - } - return RC_VALID; -err: - return 0; -} - -/* - * Sample the WM9713 touchscreen in polling mode - */ -static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) -{ - int rc; - - if (coord) { - rc = wm9713_poll_coord(wm, data); - if (rc != RC_VALID) - return rc; - } else { - rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x); - if (rc != RC_VALID) - return rc; - rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y); - if (rc != RC_VALID) - return rc; - if (pil) { - rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, - &data->p); - if (rc != 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 wm9713_codec = { - .id = WM9713_ID2, - .name = "wm9713", - .poll_sample = wm9713_poll_sample, - .poll_touch = wm9713_poll_touch, - .acc_enable = wm9713_acc_enable, - .phy_init = wm9713_phy_init, - .dig_enable = wm9713_dig_enable, - .dig_restore = wm9713_dig_restore, - .aux_prepare = wm9713_aux_prepare, -}; -EXPORT_SYMBOL_GPL(wm9713_codec); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood "); -MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm97xx-core.c b/trunk/drivers/input/touchscreen/wm97xx-core.c deleted file mode 100644 index 2910999e05a0..000000000000 --- a/trunk/drivers/input/touchscreen/wm97xx-core.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712 - * and WM9713 AC97 Codecs. - * - * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. - * Author: Liam Girdwood - * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com - * Parts Copyright : Ian Molton - * Andrew Zabolotny - * Russell King - * - * 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 adcs - * - power management - * - codec GPIO - * - codec event notification - * Todo - * - Support for async sampling control for noisy LCDs. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TS_NAME "wm97xx" -#define WM_CORE_VERSION "1.00" -#define DEFAULT_PRESSURE 0xb0c0 - - -/* - * 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"); - -/* - * wm97xx IO access, all IO locking done by AC97 layer - */ -int wm97xx_reg_read(struct wm97xx *wm, u16 reg) -{ - if (wm->ac97) - return wm->ac97->bus->ops->read(wm->ac97, reg); - else - return -1; -} -EXPORT_SYMBOL_GPL(wm97xx_reg_read); - -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); -} -EXPORT_SYMBOL_GPL(wm97xx_reg_write); - -/** - * 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->aux_prepare(wm); - - /* 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->dig_restore(wm); - - wm->pen_probably_down = 0; - - mutex_unlock(&wm->codec_mutex); - return auxval & 0xfff; -} -EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); - -/** - * wm97xx_get_gpio - Get the status of a codec GPIO. - * @wm: wm97xx device. - * @gpio: gpio - * - * Get the status of a codec GPIO pin - */ - -enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio) -{ - u16 status; - enum wm97xx_gpio_status 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; -} -EXPORT_SYMBOL_GPL(wm97xx_get_gpio); - -/** - * 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, - enum wm97xx_gpio_status 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); -} -EXPORT_SYMBOL_GPL(wm97xx_set_gpio); - -/* - * Codec GPIO pin configuration, this sets pin direction, polarity, - * stickyness and wake up. - */ -void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir, - enum wm97xx_gpio_pol pol, enum wm97xx_gpio_sticky sticky, - enum wm97xx_gpio_wake 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); -} -EXPORT_SYMBOL_GPL(wm97xx_config_gpio); - -/* - * Handle a pen down interrupt. - */ -static void wm97xx_pen_irq_worker(struct work_struct *work) -{ - struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work); - int pen_was_down = wm->pen_is_down; - - /* 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; - } 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); - } - - /* If the system is not using continuous mode or it provides a - * pen down operation then we need to schedule polls while the - * pen is down. Otherwise the machine driver is responsible - * for scheduling reads. - */ - if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { - if (wm->pen_is_down && !pen_was_down) { - /* Data is not availiable immediately on pen down */ - queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); - } - - /* Let ts_reader report the pen up for debounce. */ - if (!wm->pen_is_down && pen_was_down) - wm->pen_is_down = 1; - } - - if (!wm->pen_is_down && wm->mach_ops->acc_enabled) - wm->mach_ops->acc_pen_up(wm); - - wm->mach_ops->irq_enable(wm, 1); -} - -/* - * 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. We schedule a task - * in a work queue to do the actual interaction with the chip (it - * doesn't matter if we end up reenqueing it before it is executed - * since we don't touch the chip until it has run). 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 wm97xx *wm = dev_id; - - wm->mach_ops->irq_enable(wm, 0); - queue_work(wm->ts_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; - - /* If an interrupt is supplied an IRQ enable operation must also be - * provided. */ - BUG_ON(!wm->mach_ops->irq_enable); - - if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, - "wm97xx-pen", wm)) { - dev_err(wm->dev, - "Failed to register pen down interrupt, polling"); - wm->pen_irq = 0; - return -EINVAL; - } - - /* Configure GPIO as interrupt source on WM971x */ - if (wm->id != WM9705_ID2) { - BUG_ON(!wm->mach_ops->irq_gpio); - reg = wm97xx_reg_read(wm, AC97_MISC_AFE); - wm97xx_reg_write(wm, AC97_MISC_AFE, - reg & ~(wm->mach_ops->irq_gpio)); - reg = wm97xx_reg_read(wm, 0x5a); - wm97xx_reg_write(wm, 0x5a, reg & ~0x0001); - } - - return 0; -} - -static int wm97xx_read_samples(struct wm97xx *wm) -{ - 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; - dev_dbg(wm->dev, "pen up\n"); - 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 (wm->ts_reader_interval < HZ / 10) - wm->ts_reader_interval++; - } - - } else if (rc & RC_VALID) { - dev_dbg(wm->dev, - "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; - wm->ts_reader_interval = wm->ts_reader_min_interval; - } else if (rc & RC_PENDOWN) { - dev_dbg(wm->dev, "pen down\n"); - wm->pen_is_down = 1; - wm->ts_reader_interval = wm->ts_reader_min_interval; - } - - mutex_unlock(&wm->codec_mutex); - return rc; -} - -/* -* The touchscreen sample reader. -*/ -static void wm97xx_ts_reader(struct work_struct *work) -{ - int rc; - struct wm97xx *wm = container_of(work, struct wm97xx, ts_reader.work); - - BUG_ON(!wm->codec); - - do { - rc = wm97xx_read_samples(wm); - } while (rc & RC_AGAIN); - - if (wm->pen_is_down || !wm->pen_irq) - queue_delayed_work(wm->ts_workq, &wm->ts_reader, - wm->ts_reader_interval); -} - -/** - * 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) -{ - struct wm97xx *wm = input_get_drvdata(idev); - - wm->ts_workq = create_singlethread_workqueue("kwm97xx"); - if (wm->ts_workq == NULL) { - dev_err(wm->dev, - "Failed to create workqueue\n"); - return -EINVAL; - } - - /* start digitiser */ - if (wm->mach_ops && wm->mach_ops->acc_enabled) - wm->codec->acc_enable(wm, 1); - wm->codec->dig_enable(wm, 1); - - INIT_DELAYED_WORK(&wm->ts_reader, wm97xx_ts_reader); - INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker); - - wm->ts_reader_min_interval = HZ >= 100 ? HZ / 100 : 1; - if (wm->ts_reader_min_interval < 1) - wm->ts_reader_min_interval = 1; - wm->ts_reader_interval = wm->ts_reader_min_interval; - - wm->pen_is_down = 0; - if (wm->pen_irq) - wm97xx_init_pen_irq(wm); - else - dev_err(wm->dev, "No IRQ specified\n"); - - /* If we either don't have an interrupt for pen down events or - * failed to acquire it then we need to poll. - */ - if (wm->pen_irq == 0) - queue_delayed_work(wm->ts_workq, &wm->ts_reader, - wm->ts_reader_interval); - - 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 = input_get_drvdata(idev); - u16 reg; - - if (wm->pen_irq) { - /* Return the interrupt to GPIO usage (disabling it) */ - if (wm->id != WM9705_ID2) { - BUG_ON(!wm->mach_ops->irq_gpio); - reg = wm97xx_reg_read(wm, AC97_MISC_AFE); - wm97xx_reg_write(wm, AC97_MISC_AFE, - reg | wm->mach_ops->irq_gpio); - } - - free_irq(wm->pen_irq, wm); - } - - wm->pen_is_down = 0; - - /* Balance out interrupt disables/enables */ - if (cancel_work_sync(&wm->pen_event_work)) - wm->mach_ops->irq_enable(wm, 1); - - /* ts_reader rearms itself so we need to explicitly stop it - * before we destroy the workqueue. - */ - cancel_delayed_work_sync(&wm->ts_reader); - - destroy_workqueue(wm->ts_workq); - - /* stop digitiser */ - wm->codec->dig_enable(wm, 0); - if (wm->mach_ops && wm->mach_ops->acc_enabled) - wm->codec->acc_enable(wm, 0); -} - -static int wm97xx_probe(struct device *dev) -{ - struct wm97xx *wm; - int ret = 0, id = 0; - - wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL); - if (!wm) - return -ENOMEM; - mutex_init(&wm->codec_mutex); - - wm->dev = dev; - dev->driver_data = wm; - wm->ac97 = to_ac97_t(dev); - - /* check that we have a supported codec */ - id = wm97xx_reg_read(wm, AC97_VENDOR_ID1); - if (id != WM97XX_ID1) { - dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id); - ret = -ENODEV; - goto alloc_err; - } - - wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2); - - dev_info(wm->dev, "detected a wm97%02x codec\n", wm->id & 0xff); - - switch (wm->id & 0xff) { -#ifdef CONFIG_TOUCHSCREEN_WM9705 - case 0x05: - wm->codec = &wm9705_codec; - break; -#endif -#ifdef CONFIG_TOUCHSCREEN_WM9712 - case 0x12: - wm->codec = &wm9712_codec; - break; -#endif -#ifdef CONFIG_TOUCHSCREEN_WM9713 - case 0x13: - wm->codec = &wm9713_codec; - break; -#endif - default: - dev_err(wm->dev, "Support for wm97%02x not compiled in.\n", - wm->id & 0xff); - ret = -ENODEV; - goto alloc_err; - } - - wm->input_dev = input_allocate_device(); - if (wm->input_dev == NULL) { - ret = -ENOMEM; - goto alloc_err; - } - - /* set up touch configuration */ - 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); - input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1], - abs_x[2], 0); - input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1], - abs_y[2], 0); - input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], - abs_p[2], 0); - input_set_drvdata(wm->input_dev, wm); - wm->input_dev->dev.parent = dev; - ret = input_register_device(wm->input_dev); - if (ret < 0) - goto dev_alloc_err; - - /* set up physical characteristics */ - wm->codec->phy_init(wm); - - /* 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 */ - wm->battery_dev = platform_device_alloc("wm97xx-battery", -1); - if (!wm->battery_dev) { - ret = -ENOMEM; - goto batt_err; - } - platform_set_drvdata(wm->battery_dev, wm); - wm->battery_dev->dev.parent = dev; - ret = platform_device_add(wm->battery_dev); - if (ret < 0) - goto batt_reg_err; - - /* register our extended touch device (for machine specific - * extensions) */ - wm->touch_dev = platform_device_alloc("wm97xx-touch", -1); - if (!wm->touch_dev) { - ret = -ENOMEM; - goto touch_err; - } - platform_set_drvdata(wm->touch_dev, wm); - wm->touch_dev->dev.parent = dev; - ret = platform_device_add(wm->touch_dev); - if (ret < 0) - goto touch_reg_err; - - return ret; - - touch_reg_err: - platform_device_put(wm->touch_dev); - touch_err: - platform_device_unregister(wm->battery_dev); - wm->battery_dev = NULL; - batt_reg_err: - platform_device_put(wm->battery_dev); - batt_err: - input_unregister_device(wm->input_dev); - wm->input_dev = NULL; - dev_alloc_err: - input_free_device(wm->input_dev); - alloc_err: - kfree(wm); - - return ret; -} - -static int wm97xx_remove(struct device *dev) -{ - struct wm97xx *wm = dev_get_drvdata(dev); - - platform_device_unregister(wm->battery_dev); - platform_device_unregister(wm->touch_dev); - input_unregister_device(wm->input_dev); - kfree(wm); - - return 0; -} - -#ifdef CONFIG_PM -static int wm97xx_suspend(struct device *dev, pm_message_t state) -{ - struct wm97xx *wm = dev_get_drvdata(dev); - - if (wm->input_dev->users) - cancel_delayed_work_sync(&wm->ts_reader); - - return 0; -} - -static int wm97xx_resume(struct device *dev) -{ - struct wm97xx *wm = dev_get_drvdata(dev); - - /* restore digitiser and gpios */ - if (wm->id == WM9713_ID2) { - wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]); - wm97xx_reg_write(wm, 0x5a, wm->misc); - if (wm->input_dev->users) { - u16 reg; - 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]); - - if (wm->input_dev->users && !wm->pen_irq) { - wm->ts_reader_interval = wm->ts_reader_min_interval; - queue_delayed_work(wm->ts_workq, &wm->ts_reader, - wm->ts_reader_interval); - } - - return 0; -} - -#else -#define wm97xx_suspend NULL -#define wm97xx_resume NULL -#endif - -/* - * Machine specific operations - */ -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; -} -EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops); - -void wm97xx_unregister_mach_ops(struct wm97xx *wm) -{ - mutex_lock(&wm->codec_mutex); - wm->mach_ops = NULL; - mutex_unlock(&wm->codec_mutex); -} -EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops); - -static struct device_driver wm97xx_driver = { - .name = "ac97", - .bus = &ac97_bus_type, - .owner = THIS_MODULE, - .probe = wm97xx_probe, - .remove = wm97xx_remove, - .suspend = wm97xx_suspend, - .resume = wm97xx_resume, -}; - -static int __init wm97xx_init(void) -{ - return driver_register(&wm97xx_driver); -} - -static void __exit wm97xx_exit(void) -{ - driver_unregister(&wm97xx_driver); -} - -module_init(wm97xx_init); -module_exit(wm97xx_exit); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood "); -MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/include/linux/spi/ads7846.h b/trunk/include/linux/spi/ads7846.h index daf744017a31..334d31411629 100644 --- a/trunk/include/linux/spi/ads7846.h +++ b/trunk/include/linux/spi/ads7846.h @@ -14,8 +14,7 @@ enum ads7846_filter { struct ads7846_platform_data { u16 model; /* 7843, 7845, 7846. */ u16 vref_delay_usecs; /* 0 for external vref; etc */ - u16 vref_mv; /* external vref value, milliVolts */ - bool keep_vref_on; /* set to keep vref on for differential + int keep_vref_on:1; /* set to keep vref on for differential * measurements as well */ /* Settling time of the analog signals; a function of Vcc and the diff --git a/trunk/include/linux/wm97xx.h b/trunk/include/linux/wm97xx.h deleted file mode 100644 index ed01c7df54a3..000000000000 --- a/trunk/include/linux/wm97xx.h +++ /dev/null @@ -1,311 +0,0 @@ - -/* - * Register bits and API for Wolfson WM97xx series of codecs - */ - -#ifndef _LINUX_WM97XX_H -#define _LINUX_WM97XX_H - -#include -#include -#include -#include -#include -#include -#include /* Input device layer */ -#include - -/* - * 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) /* panel slot (5-11) */ -#define WM97XX_SLT_MASK 0x0007 -#define WM97XX_PRP_DETW 0x4000 /* detect on, digitise off, wake */ -#define WM97XX_PRP_DET 0x8000 /* detect on, digitise off, no wake */ -#define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise 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 - */ -enum wm97xx_gpio_status { - WM97XX_GPIO_HIGH, - WM97XX_GPIO_LOW -}; - -/* - * Codec GPIO direction - */ -enum wm97xx_gpio_dir { - WM97XX_GPIO_IN, - WM97XX_GPIO_OUT -}; - -/* - * Codec GPIO polarity - */ -enum wm97xx_gpio_pol { - WM97XX_GPIO_POL_HIGH, - WM97XX_GPIO_POL_LOW -}; - -/* - * Codec GPIO sticky - */ -enum wm97xx_gpio_sticky { - WM97XX_GPIO_STICKY, - WM97XX_GPIO_NOTSTICKY -}; - -/* - * Codec GPIO wake - */ -enum wm97xx_gpio_wake { - WM97XX_GPIO_WAKE, - WM97XX_GPIO_NOWAKE -}; - -/* - * 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 wm9705_codec; -extern struct wm97xx_codec_drv wm9712_codec; -extern struct wm97xx_codec_drv wm9713_codec; - -/* - * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs - */ -struct wm97xx_codec_drv { - u16 id; - char *name; - - /* read 1 sample */ - int (*poll_sample) (struct wm97xx *, int adcsel, int *sample); - - /* read X,Y,[P] in poll */ - int (*poll_touch) (struct wm97xx *, struct wm97xx_data *); - - int (*acc_enable) (struct wm97xx *, int enable); - void (*phy_init) (struct wm97xx *); - void (*dig_enable) (struct wm97xx *, int enable); - void (*dig_restore) (struct wm97xx *); - void (*aux_prepare) (struct wm97xx *); -}; - - -/* 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 *); - - /* interrupt mask control - required for accelerated operation */ - void (*irq_enable) (struct wm97xx *, int enable); - - /* GPIO pin used for accelerated operation */ - int irq_gpio; - - /* 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 */ - struct snd_ac97 *ac97; /* ALSA codec access */ - struct device *dev; /* ALSA device */ - struct platform_device *battery_dev; - struct platform_device *touch_dev; - struct wm97xx_mach_ops *mach_ops; - struct mutex codec_mutex; - struct delayed_work ts_reader; /* Used to poll touchscreen */ - unsigned long ts_reader_interval; /* Current interval for timer */ - unsigned long ts_reader_min_interval; /* Minimum interval */ - unsigned int pen_irq; /* Pen IRQ number in use */ - struct workqueue_struct *ts_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 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. - */ -enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio); -void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, - enum wm97xx_gpio_status status); -void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, - enum wm97xx_gpio_dir dir, - enum wm97xx_gpio_pol pol, - enum wm97xx_gpio_sticky sticky, - enum wm97xx_gpio_wake 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 *); - -#endif