<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.kernel.input">
    <title>gmane.linux.kernel.input</title>
    <link>http://blog.gmane.org/gmane.linux.kernel.input</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6137"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6136"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6135"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6134"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6133"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6132"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6131"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6130"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6129"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6128"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6124"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6123"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6122"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6121"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6120"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6119"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6118"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6117"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6116"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.input/6115"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6137">
    <title>[PATCH] input: strict_strtoul takes unsigned long</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6137</link>
    <description>Fix sparse warning introduced by:
commit 160f1fef7e52e974489b3c70fbd4e094c06965c2 Input: convert drivers to use strict_strtoul()

Signed-off-by: Harvey Harrison &lt;harvey.harrison&lt; at &gt;gmail.com&gt;
---
Just noticed this while fixing the lock annotation patch.

 drivers/input/touchscreen/ads7846.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 77ac820..f695b0b 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
&lt; at &gt;&lt; at &gt; -472,7 +472,7 &lt; at &gt;&lt; at &gt; static ssize_t ads7846_disable_store(struct device *dev,
      const char *buf, size_t count)
 {
 struct ads7846 *ts = dev_get_drvdata(dev);
-long i;
+unsigned long i;
 
 if (strict_strtoul(buf, 10, &amp;i))
 return -EINVAL;
</description>
    <dc:creator>Harvey Harrison</dc:creator>
    <dc:date>2008-12-02T00:04:20</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6136">
    <title>Re: [patch 3/8] input: ads7846.c sparse lock annotation</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6136</link>
    <description>
Small nit with this patch I just noticed (sorry).  It's more
conventional to do the annotation in the other order (was done
late after some other annotations), please apply the following instead:

--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
&lt; at &gt;&lt; at &gt; -761,6 +761,8 &lt; at &gt;&lt; at &gt; static irqreturn_t ads7846_irq(int irq, void *handle)
 
 /* Must be called with ts-&gt;lock held */
 static void ads7846_disable(struct ads7846 *ts)
+__releases(&amp;ts-&gt;lock)
+__acquires(&amp;ts-&gt;lock)
 {
 if (ts-&gt;disabled)
 return;


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Harvey Harrison</dc:creator>
    <dc:date>2008-12-01T23:18:48</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6135">
    <title>[patch 1/8] drivers/input/touchscreen/ucb1400_ts.c needs GPIO</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6135</link>
    <description>From: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;

ia64 allmodconfig:

include/asm-generic/gpio.h: In function `gpio_get_value_cansleep':
include/asm-generic/gpio.h:147: error: implicit declaration of function `gpio_get_value'
include/asm-generic/gpio.h: In function `gpio_set_value_cansleep':
include/asm-generic/gpio.h:153: error: implicit declaration of function `gpio_set_value'

recent linux-next breakage.  Not sure what caused it..

Cc: Marek Vasut &lt;marek.vasut&lt; at &gt;gmail.com&gt;
Cc: Russell King &lt;rmk+kernel&lt; at &gt;arm.linux.org.uk&gt;
Cc: Vernon Sauder &lt;vsauder&lt; at &gt;inhand.com&gt;
Cc: Nicolas Pitre &lt;nico&lt; at &gt;marvell.com&gt;
Cc: Dmitry Torokhov &lt;dtor&lt; at &gt;mail.ru&gt;
Cc: David Brownell &lt;david-b&lt; at &gt;pacbell.net&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/touchscreen/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff -puN drivers/input/touchscreen/Kconfig~drivers-input-touchscreen-ucb1400_tsc-needs-gpio drivers/input/touchscreen/Kconfig
--- a/drivers/input/touchscreen/Kconfig~drivers-input-touchscreen-ucb1400_tsc-needs-gpio
+++ a/drivers/input/touchscreen/Kconfig
&lt; at &gt;&lt; at &gt; -238,6 +238,7 &lt; at &gt;&lt; at &gt; config TOUCHSCREEN_UCB1400
 tristate "Philips UCB1400 touchscreen"
 depends on AC97_BUS
 depends on UCB1400_CORE
+depends on GPIOLIB
 help
   This enables support for the Philips UCB1400 touchscreen interface.
   The UCB1400 is an AC97 audio codec.  The touchscreen interface
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:12</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6134">
    <title>[patch 7/8] input: AD7879 Touchscreen driver</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6134</link>
    <description>From: Michael Hennerich &lt;michael.hennerich&lt; at &gt;analog.com&gt;

Signed-off-by: Michael Hennerich &lt;michael.hennerich&lt; at &gt;analog.com&gt;
Signed-off-by: Bryan Wu &lt;cooloney&lt; at &gt;kernel.org&gt;
Cc: Dmitry Torokhov &lt;dtor&lt; at &gt;mail.ru&gt;
Cc: Michael Hennerich &lt;michael.hennerich&lt; at &gt;analog.com&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/touchscreen/Kconfig  |   32 +
 drivers/input/touchscreen/Makefile |    1 
 drivers/input/touchscreen/ad7879.c |  797 +++++++++++++++++++++++++++
 include/linux/spi/ad7879.h         |   35 +
 4 files changed, 865 insertions(+)

diff -puN drivers/input/touchscreen/Kconfig~input-ad7879-touchscreen-driver drivers/input/touchscreen/Kconfig
--- a/drivers/input/touchscreen/Kconfig~input-ad7879-touchscreen-driver
+++ a/drivers/input/touchscreen/Kconfig
&lt; at &gt;&lt; at &gt; -42,6 +42,38 &lt; at &gt;&lt; at &gt; config TOUCHSCREEN_AD7877
   To compile this driver as a module, choose M here: the
   module will be called ad7877.
 
+config TOUCHSCREEN_AD7879_I2C
+tristate "AD7879 based touchscreens: AD7879-1 I2C Interface"
+depends on I2C
+select TOUCHSCREEN_AD7879
+help
+  Say Y here if you have a touchscreen interface using the
+  AD7879-1 controller, and your board-specific initialization
+  code includes that in its table of I2C devices.
+
+  If unsure, say N (but it's safe to say "Y").
+
+  To compile this driver as a module, choose M here: the
+  module will be called ad7879.
+
+config TOUCHSCREEN_AD7879_SPI
+tristate "AD7879 based touchscreens: AD7879 SPI Interface"
+depends on SPI_MASTER &amp;&amp; TOUCHSCREEN_AD7879_I2C = n
+select TOUCHSCREEN_AD7879
+help
+  Say Y here if you have a touchscreen interface using the
+  AD7879 controller, and your board-specific initialization
+  code includes that in its table of SPI devices.
+
+  If unsure, say N (but it's safe to say "Y").
+
+  To compile this driver as a module, choose M here: the
+  module will be called ad7879.
+
+config TOUCHSCREEN_AD7879
+tristate
+default n
+
 config TOUCHSCREEN_BITSY
 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
 depends on SA1100_BITSY
diff -puN drivers/input/touchscreen/Makefile~input-ad7879-touchscreen-driver drivers/input/touchscreen/Makefile
--- a/drivers/input/touchscreen/Makefile~input-ad7879-touchscreen-driver
+++ a/drivers/input/touchscreen/Makefile
&lt; at &gt;&lt; at &gt; -7,6 +7,7 &lt; at &gt;&lt; at &gt;
 wm97xx-ts-y := wm97xx-core.o
 
 obj-$(CONFIG_TOUCHSCREEN_AD7877)+= ad7877.o
+obj-$(CONFIG_TOUCHSCREEN_AD7879)+= ad7879.o
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)+= ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)+= h3600_ts_input.o
diff -puN /dev/null drivers/input/touchscreen/ad7879.c
--- /dev/null
+++ a/drivers/input/touchscreen/ad7879.c
&lt; at &gt;&lt; at &gt; -0,0 +1,797 &lt; at &gt;&lt; at &gt;
+/*
+ * File:        drivers/input/touchscreen/ad7879.c
+ *
+ *Copyright (C) 2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description:AD7879 based touchscreen, and GPIO driver (I2C/SPI Interface)
+ *
+ * Bugs:        Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak &lt;imre.deak&lt; at &gt;nokia.com&gt;
+ *
+ * Using code from:
+ *  - corgi_ts.c
+ *Copyright (C) 2004-2005 Richard Purdie
+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
+ *Copyright (C) 2002 MontaVista Software
+ *Copyright (C) 2004 Texas Instruments
+ *Copyright (C) 2005 Dirk Behme
+ *  - ad7877.c
+ * Copyright (C) 2006-2008 Analog Devices Inc.
+ */
+
+#include &lt;linux/device.h&gt;
+#include &lt;linux/init.h&gt;
+#include &lt;linux/delay.h&gt;
+#include &lt;linux/input.h&gt;
+#include &lt;linux/interrupt.h&gt;
+#include &lt;linux/irq.h&gt;
+#include &lt;linux/slab.h&gt;
+#include &lt;linux/workqueue.h&gt;
+#include &lt;linux/spi/spi.h&gt;
+#include &lt;linux/i2c.h&gt;
+
+#include &lt;linux/spi/ad7879.h&gt;
+
+#define AD7879_REG_ZEROS0
+#define AD7879_REG_CTRL11
+#define AD7879_REG_CTRL22
+#define AD7879_REG_CTRL33
+#define AD7879_REG_AUX1HIGH4
+#define AD7879_REG_AUX1LOW5
+#define AD7879_REG_TEMP1HIGH6
+#define AD7879_REG_TEMP1LOW7
+#define AD7879_REG_XPLUS8
+#define AD7879_REG_YPLUS9
+#define AD7879_REG_Z110
+#define AD7879_REG_Z211
+#define AD7879_REG_AUXVBAT12
+#define AD7879_REG_TEMP13
+#define AD7879_REG_REVID14
+
+/* Control REG 1 */
+#define AD7879_TMR(x)((x &amp; 0xFF) &lt;&lt; 0)
+#define AD7879_ACQ(x)((x &amp; 0x3) &lt;&lt; 8)
+#define AD7879_MODE_NOC  (0 &lt;&lt; 10)/* Do not convert */
+#define AD7879_MODE_SCC  (1 &lt;&lt; 10)/* Single channel conversion */
+#define AD7879_MODE_SEQ0 (2 &lt;&lt; 10)/* Sequence 0 in Slave Mode */
+#define AD7879_MODE_SEQ1 (3 &lt;&lt; 10)/* Sequence 1 in Master Mode */
+#define AD7879_MODE_INT (1 &lt;&lt; 15)/* PENIRQ disabled INT enabled */
+
+/* Control REG 2 */
+#define AD7879_FCD(x)((x &amp; 0x3) &lt;&lt; 0)
+#define AD7879_RESET(1 &lt;&lt; 4)
+#define AD7879_MFS(x)((x &amp; 0x3) &lt;&lt; 5)
+#define AD7879_AVG(x)((x &amp; 0x3) &lt;&lt; 7)
+#defineAD7879_SER(1 &lt;&lt; 9)/* non-differential */
+#defineAD7879_DFR(0 &lt;&lt; 9)/* differential */
+#define AD7879_GPIOPOL(1 &lt;&lt; 10)
+#define AD7879_GPIODIR(1 &lt;&lt; 11)
+#define AD7879_GPIO_DATA(1 &lt;&lt; 12)
+#define AD7879_GPIO_EN(1 &lt;&lt; 13)
+#define AD7879_PM(x)((x &amp; 0x3) &lt;&lt; 14)
+#define AD7879_PM_SHUTDOWN(0)
+#define AD7879_PM_DYN(1)
+#define AD7879_PM_FULLON(2)
+
+/* Control REG 3 */
+#define AD7879_TEMPMASK_BIT(1&lt;&lt;15)
+#define AD7879_AUXVBATMASK_BIT(1&lt;&lt;14)
+#define AD7879_INTMODE_BIT(1&lt;&lt;13)
+#define AD7879_GPIOALERTMASK_BIT(1&lt;&lt;12)
+#define AD7879_AUXLOW_BIT(1&lt;&lt;11)
+#define AD7879_AUXHIGH_BIT(1&lt;&lt;10)
+#define AD7879_TEMPLOW_BIT(1&lt;&lt;9)
+#define AD7879_TEMPHIGH_BIT(1&lt;&lt;8)
+#define AD7879_YPLUS_BIT(1&lt;&lt;7)
+#define AD7879_XPLUS_BIT(1&lt;&lt;6)
+#define AD7879_Z1_BIT(1&lt;&lt;5)
+#define AD7879_Z2_BIT(1&lt;&lt;4)
+#define AD7879_AUX_BIT(1&lt;&lt;3)
+#define AD7879_VBAT_BIT(1&lt;&lt;2)
+#define AD7879_TEMP_BIT(1&lt;&lt;1)
+
+enum {
+AD7879_SEQ_XPOS  = 0,
+AD7879_SEQ_YPOS  = 1,
+AD7879_SEQ_Z1    = 2,
+AD7879_SEQ_Z2    = 3,
+AD7879_NR_SENSE  = 4,
+};
+
+#defineMAX_12BIT((1&lt;&lt;12)-1)
+#defineTS_PEN_UP_TIMEOUTmsecs_to_jiffies(50)
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define AD7879_DEVID0x7A
+typedef struct spi_devicebus_device;
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+#define AD7879_DEVID0x79
+typedef struct i2c_clientbus_device;
+#endif
+
+struct ad7879 {
+bus_device *bus;
+struct input_dev*input;
+struct work_structwork;
+struct timer_listtimer;
+spinlock_tlock;
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+struct spi_messagemsg;
+struct spi_transferxfer[AD7879_NR_SENSE + 1];
+u16cmd;
+#endif
+u16 conversion_data[AD7879_NR_SENSE];
+charphys[32];
+u8first_conversion_delay;
+u8acquisition_time;
+u8averaging;
+u8pen_down_acc_interval;
+u8median;
+u16x_plate_ohms;
+u16pressure_max;
+u16gpio_init;
+u16cmd_crtl1;
+u16cmd_crtl2;
+u16cmd_crtl3;
+unsigneddisabled:1;/* P: lock */
+unsignedgpio:1;
+};
+
+static int ad7879_read(bus_device *, u8);
+static int ad7879_write(bus_device *, u8, u16);
+static void ad7879_collect(struct ad7879 *);
+
+static void ad7879_report(struct ad7879 *ts)
+{
+struct input_dev*input_dev = ts-&gt;input;
+unsignedRt;
+u16x, y, z1, z2;
+
+x = ts-&gt;conversion_data[AD7879_SEQ_XPOS] &amp; MAX_12BIT;
+y = ts-&gt;conversion_data[AD7879_SEQ_YPOS] &amp; MAX_12BIT;
+z1 = ts-&gt;conversion_data[AD7879_SEQ_Z1] &amp; MAX_12BIT;
+z2 = ts-&gt;conversion_data[AD7879_SEQ_Z2] &amp; MAX_12BIT;
+
+/*
+ * The samples processed here are already preprocessed by the AD7879.
+ * The preprocessing function consists of a median and an averaging filter.
+ * The combination of these two techniques provides a robust solution,
+ * discarding the spurious noise in the signal and keeping only the data of interest.
+ * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h)
+ * Other user-programmable conversion controls include variable acquisition time,
+ * and first conversion delay. Up to 16 averages can be taken per conversion.
+ */
+
+if (likely(x &amp;&amp; z1)) {
+/* compute touch pressure resistance using equation #1 */
+Rt = (z2 - z1) * x * ts-&gt;x_plate_ohms;
+Rt /= z1;
+Rt = (Rt + 2047) &gt;&gt; 12;
+} else
+Rt = 0;
+
+if (Rt) {
+input_report_abs(input_dev, ABS_X, x);
+input_report_abs(input_dev, ABS_Y, y);
+input_report_abs(input_dev, ABS_PRESSURE, Rt);
+input_sync(input_dev);
+}
+}
+
+static void ad7879_work(struct work_struct *work)
+{
+struct ad7879 *ts = container_of(work, struct ad7879, work);
+
+/* use keventd context to read the result registers */
+ad7879_collect(ts);
+ad7879_report(ts);
+mod_timer(&amp;ts-&gt;timer, jiffies + TS_PEN_UP_TIMEOUT);
+}
+
+static void ad7879_ts_event_release(struct ad7879 *ts)
+{
+struct input_dev *input_dev = ts-&gt;input;
+
+input_report_abs(input_dev, ABS_PRESSURE, 0);
+input_sync(input_dev);
+}
+
+static void ad7879_timer(unsigned long handle)
+{
+struct ad7879*ts = (void *)handle;
+
+ad7879_ts_event_release(ts);
+}
+
+static irqreturn_t ad7879_irq(int irq, void *handle)
+{
+struct ad7879 *ts = handle;
+
+/* The repeated conversion sequencer controlled by TMR kicked off too fast.
+ * We ignore the last and process the sample sequence currently in the queue.
+ * It can't be older than 9.4ms
+ */
+
+if (!work_pending(&amp;ts-&gt;work))
+schedule_work(&amp;ts-&gt;work);
+
+return IRQ_HANDLED;
+}
+
+static void ad7879_disable(struct ad7879 *ts)
+{
+unsigned long flags;
+
+spin_lock_irqsave(&amp;ts-&gt;lock, flags);
+if (ts-&gt;disabled) {
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+return;
+}
+
+ts-&gt;disabled = 1;
+disable_irq(ts-&gt;bus-&gt;irq);
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+
+cancel_work_sync(&amp;ts-&gt;work);
+
+if (del_timer_sync(&amp;ts-&gt;timer))
+ad7879_ts_event_release(ts);
+
+/* we know the chip's in lowpower mode since we always
+ * leave it that way after every request
+ */
+}
+
+static void ad7879_enable(struct ad7879 *ts)
+{
+unsigned long flags;
+
+spin_lock_irqsave(&amp;ts-&gt;lock, flags);
+if (ts-&gt;disabled) {
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+return;
+}
+ts-&gt;disabled = 0;
+enable_irq(ts-&gt;bus-&gt;irq);
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+}
+
+static ssize_t ad7879_disable_show(struct device *dev,
+     struct device_attribute *attr, char *buf)
+{
+struct ad7879 *ts = dev_get_drvdata(dev);
+
+return sprintf(buf, "%u\n", ts-&gt;disabled);
+}
+
+static ssize_t ad7879_disable_store(struct device *dev,
+     struct device_attribute *attr,
+     const char *buf, size_t count)
+{
+struct ad7879 *ts = dev_get_drvdata(dev);
+unsigned long val;
+int ret;
+
+ret = strict_strtoul(buf, 10, &amp;val);
+
+if (ret)
+return ret;
+
+if (val)
+ad7879_disable(ts);
+else
+ad7879_enable(ts);
+
+return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store);
+
+static ssize_t ad7879_gpio_show(struct device *dev,
+     struct device_attribute *attr, char *buf)
+{
+struct ad7879 *ts = dev_get_drvdata(dev);
+
+return sprintf(buf, "%u\n", ts-&gt;gpio);
+}
+
+static ssize_t ad7879_gpio_store(struct device *dev,
+     struct device_attribute *attr,
+     const char *buf, size_t count)
+{
+struct ad7879 *ts = dev_get_drvdata(dev);
+unsigned long val;
+int ret;
+
+ret = strict_strtoul(buf, 10, &amp;val);
+if (ret)
+return ret;
+
+ts-&gt;gpio = !!val;
+
+ret = ad7879_write(ts-&gt;bus, AD7879_REG_CTRL2,
+ts-&gt;gpio ? ts-&gt;cmd_crtl2 &amp; ~AD7879_GPIO_DATA
+: ts-&gt;cmd_crtl2 | AD7879_GPIO_DATA);
+
+if (ret)
+return ret;
+
+return count;
+}
+
+static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store);
+
+static struct attribute *ad7879_attributes[] = {
+&amp;dev_attr_disable.attr,
+&amp;dev_attr_gpio.attr,
+NULL
+};
+
+static const struct attribute_group ad7879_attr_group = {
+.attrs = ad7879_attributes,
+};
+
+static void ad7879_setup(bus_device *bus, struct ad7879 *ts)
+{
+ts-&gt;cmd_crtl3 = AD7879_YPLUS_BIT |
+AD7879_XPLUS_BIT |
+AD7879_Z2_BIT |
+AD7879_Z1_BIT |
+AD7879_TEMPMASK_BIT |
+AD7879_AUXVBATMASK_BIT |
+AD7879_GPIOALERTMASK_BIT;
+
+ts-&gt;cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
+AD7879_AVG(ts-&gt;averaging) |
+AD7879_MFS(ts-&gt;median) |
+AD7879_FCD(ts-&gt;first_conversion_delay) |
+ts-&gt;gpio_init;
+
+ts-&gt;cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
+AD7879_ACQ(ts-&gt;acquisition_time) |
+AD7879_TMR(ts-&gt;pen_down_acc_interval);
+
+ad7879_write(bus, AD7879_REG_CTRL2, ts-&gt;cmd_crtl2);
+ad7879_write(bus, AD7879_REG_CTRL3, ts-&gt;cmd_crtl3);
+ad7879_write(bus, AD7879_REG_CTRL1, ts-&gt;cmd_crtl1);
+}
+
+static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
+{
+struct input_dev *input_dev;
+struct ad7879_platform_data *pdata = bus-&gt;dev.platform_data;
+int err;
+u16 revid;
+
+if (!bus-&gt;irq) {
+dev_err(&amp;bus-&gt;dev, "no IRQ?\n");
+return -ENODEV;
+}
+
+if (!pdata) {
+dev_err(&amp;bus-&gt;dev, "no platform data?\n");
+return -ENODEV;
+}
+
+input_dev = input_allocate_device();
+if (!input_dev)
+return -ENOMEM;
+
+ts-&gt;input = input_dev;
+
+setup_timer(&amp;ts-&gt;timer, ad7879_timer, (unsigned long) ts);
+INIT_WORK(&amp;ts-&gt;work, ad7879_work);
+spin_lock_init(&amp;ts-&gt;lock);
+
+ts-&gt;x_plate_ohms = pdata-&gt;x_plate_ohms ? : 400;
+ts-&gt;pressure_max = pdata-&gt;pressure_max ? : ~0;
+
+ts-&gt;first_conversion_delay = pdata-&gt;first_conversion_delay;
+ts-&gt;acquisition_time = pdata-&gt;acquisition_time;
+ts-&gt;averaging = pdata-&gt;averaging;
+ts-&gt;pen_down_acc_interval = pdata-&gt;pen_down_acc_interval;
+ts-&gt;median = pdata-&gt;median;
+
+if (pdata-&gt;gpio_output)
+ts-&gt;gpio_init = AD7879_GPIO_EN |
+(pdata-&gt;gpio_default ? 0 : AD7879_GPIO_DATA);
+else
+ts-&gt;gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR;
+
+snprintf(ts-&gt;phys, sizeof(ts-&gt;phys), "%s/inputX", bus-&gt;dev.bus_id);
+
+input_dev-&gt;name = "AD7879 Touchscreen";
+input_dev-&gt;phys = ts-&gt;phys;
+input_dev-&gt;dev.parent = &amp;bus-&gt;dev;
+
+__set_bit(EV_ABS, input_dev-&gt;evbit);
+__set_bit(ABS_X, input_dev-&gt;absbit);
+__set_bit(ABS_Y, input_dev-&gt;absbit);
+__set_bit(ABS_PRESSURE, input_dev-&gt;absbit);
+
+input_set_abs_params(input_dev, ABS_X,
+pdata-&gt;x_min ? : 0,
+pdata-&gt;x_max ? : MAX_12BIT,
+0, 0);
+input_set_abs_params(input_dev, ABS_Y,
+pdata-&gt;y_min ? : 0,
+pdata-&gt;y_max ? : MAX_12BIT,
+0, 0);
+input_set_abs_params(input_dev, ABS_PRESSURE,
+pdata-&gt;pressure_min, pdata-&gt;pressure_max, 0, 0);
+
+err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET);
+
+if (err &lt; 0) {
+dev_err(&amp;bus-&gt;dev, "Failed to write %s\n", input_dev-&gt;name);
+goto err_free_mem;
+}
+
+revid = ad7879_read(bus, AD7879_REG_REVID);
+
+if ((revid &amp; 0xFF) != AD7879_DEVID) {
+dev_err(&amp;bus-&gt;dev, "Failed to probe %s\n", input_dev-&gt;name);
+err = -ENODEV;
+goto err_free_mem;
+}
+
+ad7879_setup(bus, ts);
+
+err = request_irq(bus-&gt;irq, ad7879_irq, IRQF_TRIGGER_FALLING |
+IRQF_SAMPLE_RANDOM, bus-&gt;dev.driver-&gt;name, ts);
+
+if (err) {
+dev_err(&amp;bus-&gt;dev, "irq %d busy?\n", bus-&gt;irq);
+goto err_free_mem;
+}
+
+err = sysfs_create_group(&amp;bus-&gt;dev.kobj, &amp;ad7879_attr_group);
+if (err)
+goto err_free_irq;
+
+err = input_register_device(input_dev);
+if (err)
+goto err_remove_attr;
+
+dev_info(&amp;bus-&gt;dev, "Rev.%d touchscreen, irq %d\n",
+revid &gt;&gt; 8, bus-&gt;irq);
+
+return 0;
+
+err_remove_attr:
+sysfs_remove_group(&amp;bus-&gt;dev.kobj, &amp;ad7879_attr_group);
+err_free_irq:
+free_irq(bus-&gt;irq, ts);
+err_free_mem:
+input_free_device(input_dev);
+
+return err;
+}
+
+static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
+{
+ad7879_disable(ts);
+ad7879_write(ts-&gt;bus, AD7879_REG_CTRL2,
+AD7879_PM(AD7879_PM_SHUTDOWN));
+sysfs_remove_group(&amp;ts-&gt;bus-&gt;dev.kobj, &amp;ad7879_attr_group);
+free_irq(ts-&gt;bus-&gt;irq, ts);
+input_unregister_device(ts-&gt;input);
+dev_dbg(&amp;bus-&gt;dev, "unregistered touchscreen\n");
+
+return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7879_suspend(bus_device *bus, pm_message_t message)
+{
+struct ad7879 *ts = dev_get_drvdata(&amp;bus-&gt;dev);
+
+ad7879_disable(ts);
+ad7879_write(bus, AD7879_REG_CTRL2,
+AD7879_PM(AD7879_PM_SHUTDOWN));
+
+return 0;
+}
+
+static int ad7879_resume(bus_device *bus)
+{
+struct ad7879 *ts = dev_get_drvdata(&amp;bus-&gt;dev);
+
+ad7879_setup(bus, ts);
+ad7879_enable(ts);
+
+return 0;
+}
+#else
+#define ad7879_suspend NULL
+#define ad7879_resume  NULL
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define MAX_SPI_FREQ_HZ5000000
+#define AD7879_CMD_MAGIC0xE000
+#define AD7879_CMD_READ(1 &lt;&lt; 10)
+#define AD7879_WRITECMD(reg)  (AD7879_CMD_MAGIC | (reg &amp; 0xF))
+#define AD7879_READCMD(reg)  (AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg &amp; 0xF))
+
+struct ser_req {
+u16command;
+u16data;
+struct spi_messagemsg;
+struct spi_transferxfer[2];
+};
+
+/*
+ * ad7879_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done in ad7879_collect().
+ */
+
+static int ad7879_read(struct spi_device *spi, u8 reg)
+{
+struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
+int status, ret;
+
+if (!req)
+return -ENOMEM;
+
+spi_message_init(&amp;req-&gt;msg);
+
+req-&gt;command = (u16) AD7879_READCMD(reg);
+req-&gt;xfer[0].tx_buf = &amp;req-&gt;command;
+req-&gt;xfer[0].len = 2;
+
+req-&gt;xfer[1].rx_buf = &amp;req-&gt;data;
+req-&gt;xfer[1].len = 2;
+
+spi_message_add_tail(&amp;req-&gt;xfer[0], &amp;req-&gt;msg);
+spi_message_add_tail(&amp;req-&gt;xfer[1], &amp;req-&gt;msg);
+
+status = spi_sync(spi, &amp;req-&gt;msg);
+
+if (status == 0)
+status = req-&gt;msg.status;
+
+ret = status ? status : req-&gt;data;
+kfree(req);
+
+return ret;
+}
+
+static int ad7879_write(struct spi_device *spi, u8 reg, u16 val)
+{
+struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
+int status;
+
+if (!req)
+return -ENOMEM;
+
+spi_message_init(&amp;req-&gt;msg);
+
+req-&gt;command = (u16) AD7879_WRITECMD(reg);
+req-&gt;xfer[0].tx_buf = &amp;req-&gt;command;
+req-&gt;xfer[0].len = 2;
+
+req-&gt;data = val;
+req-&gt;xfer[1].tx_buf = &amp;req-&gt;data;
+req-&gt;xfer[1].len = 2;
+
+spi_message_add_tail(&amp;req-&gt;xfer[0], &amp;req-&gt;msg);
+spi_message_add_tail(&amp;req-&gt;xfer[1], &amp;req-&gt;msg);
+
+status = spi_sync(spi, &amp;req-&gt;msg);
+
+if (status == 0)
+status = req-&gt;msg.status;
+
+kfree(req);
+
+return status;
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+int status = spi_sync(ts-&gt;bus, &amp;ts-&gt;msg);
+if (status)
+dev_err(&amp;ts-&gt;bus-&gt;dev, "spi_sync --&gt; %d\n", status);
+}
+
+static void ad7879_setup_ts_def_msg(struct ad7879 *ts)
+{
+struct spi_message *m;
+int i;
+
+ts-&gt;cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS);
+
+m = &amp;ts-&gt;msg;
+spi_message_init(m);
+ts-&gt;xfer[0].tx_buf = &amp;ts-&gt;cmd;
+ts-&gt;xfer[0].len = 2;
+
+spi_message_add_tail(&amp;ts-&gt;xfer[0], m);
+
+for (i = 0; i &lt; AD7879_NR_SENSE; i++) {
+ts-&gt;xfer[i + 1].rx_buf = &amp;ts-&gt;conversion_data[i];
+ts-&gt;xfer[i + 1].len = 2;
+spi_message_add_tail(&amp;ts-&gt;xfer[i + 1], m);
+}
+}
+
+static int __devinit ad7879_probe(struct spi_device *spi)
+{
+struct ad7879 *ts;
+int ret;
+
+/* don't exceed max specified SPI CLK frequency */
+if (spi-&gt;max_speed_hz &gt; MAX_SPI_FREQ_HZ) {
+dev_err(&amp;spi-&gt;dev, "SPI CLK %d Hz?\n", spi-&gt;max_speed_hz);
+return -EINVAL;
+}
+
+ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+if (!ts)
+return -ENOMEM;
+
+dev_set_drvdata(&amp;spi-&gt;dev, ts);
+ts-&gt;bus = spi;
+
+ad7879_setup_ts_def_msg(ts);
+
+ret = ad7879_construct(spi, ts);
+if (!ret)
+return ret;
+
+dev_set_drvdata(&amp;spi-&gt;dev, NULL);
+kfree(ts);
+
+return ret;
+}
+
+static int __devexit ad7879_remove(struct spi_device *spi)
+{
+struct ad7879 *ts = dev_get_drvdata(&amp;spi-&gt;dev);
+
+ad7879_destroy(spi, ts);
+dev_set_drvdata(&amp;spi-&gt;dev, NULL);
+kfree(ts);
+return 0;
+}
+
+static struct spi_driver ad7879_driver = {
+.driver = {
+.name= "ad7879",
+.bus= &amp;spi_bus_type,
+.owner= THIS_MODULE,
+},
+.probe= ad7879_probe,
+.remove= __devexit_p(ad7879_remove),
+.suspend= ad7879_suspend,
+.resume= ad7879_resume,
+};
+
+static int __init ad7879_init(void)
+{
+return spi_register_driver(&amp;ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+spi_unregister_driver(&amp;ad7879_driver);
+}
+module_exit(ad7879_exit);
+
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+
+/* All registers are word-sized.
+ * AD7879 uses a high-byte first convention.
+ */
+static int ad7879_read(struct i2c_client *client, u8 reg)
+{
+return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+static int ad7879_write(struct i2c_client *client, u8 reg, u16 val)
+{
+return i2c_smbus_write_word_data(client, reg, swab16(val));
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+int i;
+for (i = 0; i &lt; AD7879_NR_SENSE; i++)
+ts-&gt;conversion_data[i] =
+ad7879_read(ts-&gt;bus, AD7879_REG_XPLUS + i);
+}
+
+static int __devinit ad7879_probe(struct i2c_client *client,
+const struct i2c_device_id *id)
+{
+struct ad7879 *ts;
+int ret;
+
+if (!i2c_check_functionality(client-&gt;adapter,
+I2C_FUNC_SMBUS_WORD_DATA)) {
+dev_err(&amp;client-&gt;dev, "SMBUS Word Data not Supported\n");
+return -EIO;
+}
+
+ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+if (!ts)
+return -ENOMEM;
+
+i2c_set_clientdata(client, ts);
+ts-&gt;bus = client;
+
+ret = ad7879_construct(client, ts);
+if (!ret)
+return ret;
+
+i2c_set_clientdata(client, NULL);
+kfree(ts);
+
+return ret;
+}
+
+static int __devexit ad7879_remove(struct i2c_client *client)
+{
+struct ad7879 *ts = dev_get_drvdata(&amp;client-&gt;dev);
+
+ad7879_destroy(client, ts);
+i2c_set_clientdata(client, NULL);
+kfree(ts);
+return 0;
+}
+static const struct i2c_device_id ad7979_id[] = {
+{ "ad7879", 0 },
+{ }
+};
+MODULE_DEVICE_TABLE(i2c, ad7979_id);
+
+static struct i2c_driver ad7879_driver = {
+.driver = {
+.name= "ad7879",
+.owner= THIS_MODULE,
+},
+.probe= ad7879_probe,
+.remove= __devexit_p(ad7879_remove),
+.suspend= ad7879_suspend,
+.resume= ad7879_resume,
+.id_table = ad7979_id,
+};
+
+static int __init ad7879_init(void)
+{
+return i2c_add_driver(&amp;ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+i2c_del_driver(&amp;ad7879_driver);
+}
+module_exit(ad7879_exit);
+#endif
+
+MODULE_AUTHOR("Michael Hennerich &lt;hennerich&lt; at &gt;blackfin.uclinux.org&gt;");
+MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver");
+MODULE_LICENSE("GPL");
diff -puN /dev/null include/linux/spi/ad7879.h
--- /dev/null
+++ a/include/linux/spi/ad7879.h
&lt; at &gt;&lt; at &gt; -0,0 +1,35 &lt; at &gt;&lt; at &gt;
+/* linux/spi/ad7879.h */
+
+/* Touchscreen characteristics vary between boards and models.  The
+ * platform_data for the device's "struct device" holds this information.
+ *
+ * It's OK if the min/max values are zero.
+ */
+struct ad7879_platform_data {
+u16model;/* 7879 */
+u16x_plate_ohms;
+u16x_min, x_max;
+u16y_min, y_max;
+u16pressure_min, pressure_max;
+
+/* [0..255] 0=OFF Starts at 1=550us and goes
+ * all the way to 9.440ms in steps of 35us.
+ */
+u8pen_down_acc_interval;
+/* [0..15] Starts at 0=128us and goes all the
+ * way to 4.096ms in steps of 128us.
+ */
+u8first_conversion_delay;
+/* [0..3] 0 = 2us, 1 = 4us, 2 = 8us, 3 = 16us */
+u8acquisition_time;
+/* [0..3] Average X middle samples 0 = 2, 1 = 4, 2 = 8, 3 = 16 */
+u8averaging;
+/* [0..3] Perform X measurements 0 = OFF,
+ * 1 = 4, 2 = 8, 3 = 16 (median &gt; averaging)
+ */
+u8median;
+/* 1 = AUX/VBAT/GPIO set to GPIO Output */
+u8gpio_output;
+/* Initial GPIO pin state (valid if gpio_output = 1) */
+u8gpio_default;
+};
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6133">
    <title>[patch 2/8] input/touchscreen driver: add support AD7877 touchscreen driver</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6133</link>
    <description>From: Michael Hennerich &lt;michael.hennerich&lt; at &gt;analog.com&gt;

Apply patch from Philip Douglass:
Make ad7877 ts driver not dependent on Blackfin specific cs_change_per_word_option

Signed-off-by: Michael Hennerich &lt;michael.hennerich&lt; at &gt;analog.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu&lt; at &gt;analog.com&gt;
Cc: Jiri Kosina &lt;jkosina&lt; at &gt;suse.cz&gt;
Cc: Dmitry Torokhov &lt;dmitry.torokhov&lt; at &gt;gmail.com&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/touchscreen/Kconfig  |   13 
 drivers/input/touchscreen/Makefile |    1 
 drivers/input/touchscreen/ad7877.c |  875 +++++++++++++++++++++++++++
 3 files changed, 889 insertions(+)

diff -puN drivers/input/touchscreen/Kconfig~input-touchscreen-driver-add-support-ad7877-touchscreen-driver drivers/input/touchscreen/Kconfig
--- a/drivers/input/touchscreen/Kconfig~input-touchscreen-driver-add-support-ad7877-touchscreen-driver
+++ a/drivers/input/touchscreen/Kconfig
&lt; at &gt;&lt; at &gt; -29,6 +29,19 &lt; at &gt;&lt; at &gt; config TOUCHSCREEN_ADS7846
   To compile this driver as a module, choose M here: the
   module will be called ads7846.
 
+config TOUCHSCREEN_AD7877
+tristate "AD7877 based touchscreens"
+depends on SPI_MASTER
+help
+  Say Y here if you have a touchscreen interface using the
+  AD7877 controller, and your board-specific initialization
+  code includes that in its table of SPI devices.
+
+  If unsure, say N (but it's safe to say "Y").
+
+  To compile this driver as a module, choose M here: the
+  module will be called ad7877.
+
 config TOUCHSCREEN_BITSY
 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
 depends on SA1100_BITSY
diff -puN drivers/input/touchscreen/Makefile~input-touchscreen-driver-add-support-ad7877-touchscreen-driver drivers/input/touchscreen/Makefile
--- a/drivers/input/touchscreen/Makefile~input-touchscreen-driver-add-support-ad7877-touchscreen-driver
+++ a/drivers/input/touchscreen/Makefile
&lt; at &gt;&lt; at &gt; -6,6 +6,7 &lt; at &gt;&lt; at &gt;
 
 wm97xx-ts-y := wm97xx-core.o
 
+obj-$(CONFIG_TOUCHSCREEN_AD7877)+= ad7877.o
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)+= ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)+= h3600_ts_input.o
diff -puN /dev/null drivers/input/touchscreen/ad7877.c
--- /dev/null
+++ a/drivers/input/touchscreen/ad7877.c
&lt; at &gt;&lt; at &gt; -0,0 +1,875 &lt; at &gt;&lt; at &gt;
+/*
+ * File:        drivers/input/touchscreen/ad7877.c
+ *
+ * Based on: ads7846.c
+ *
+ *Copyright (C) 2006-2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description:AD7877 based touchscreen, sensor (ADCs), DAC and GPIO driver
+ *
+ * Bugs:        Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak &lt;imre.deak&lt; at &gt;nokia.com&gt;
+ *
+ * Using code from:
+ *  - corgi_ts.c
+ *Copyright (C) 2004-2005 Richard Purdie
+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
+ *Copyright (C) 2002 MontaVista Software
+ *Copyright (C) 2004 Texas Instruments
+ *Copyright (C) 2005 Dirk Behme
+ */
+
+
+#include &lt;linux/device.h&gt;
+#include &lt;linux/init.h&gt;
+#include &lt;linux/delay.h&gt;
+#include &lt;linux/input.h&gt;
+#include &lt;linux/interrupt.h&gt;
+#include &lt;linux/slab.h&gt;
+#include &lt;linux/spi/spi.h&gt;
+#include &lt;linux/spi/ad7877.h&gt;
+#include &lt;asm/irq.h&gt;
+
+#defineTS_PEN_UP_TIMEOUTmsecs_to_jiffies(50)
+
+#define MAX_SPI_FREQ_HZ20000000
+#defineMAX_12BIT((1&lt;&lt;12)-1)
+
+#define AD7877_REG_ZEROS0
+#define AD7877_REG_CTRL11
+#define AD7877_REG_CTRL22
+#define AD7877_REG_ALERT3
+#define AD7877_REG_AUX1HIGH4
+#define AD7877_REG_AUX1LOW5
+#define AD7877_REG_BAT1HIGH6
+#define AD7877_REG_BAT1LOW7
+#define AD7877_REG_BAT2HIGH8
+#define AD7877_REG_BAT2LOW9
+#define AD7877_REG_TEMP1HIGH10
+#define AD7877_REG_TEMP1LOW11
+#define AD7877_REG_SEQ012
+#define AD7877_REG_SEQ113
+#define AD7877_REG_DAC14
+#define AD7877_REG_NONE115
+#define AD7877_REG_EXTWRITE15
+#define AD7877_REG_XPLUS16
+#define AD7877_REG_YPLUS17
+#define AD7877_REG_Z218
+#define AD7877_REG_aux119
+#define AD7877_REG_aux220
+#define AD7877_REG_aux321
+#define AD7877_REG_bat122
+#define AD7877_REG_bat223
+#define AD7877_REG_temp124
+#define AD7877_REG_temp225
+#define AD7877_REG_Z126
+#define AD7877_REG_GPIOCTRL127
+#define AD7877_REG_GPIOCTRL228
+#define AD7877_REG_GPIODATA29
+#define AD7877_REG_NONE230
+#define AD7877_REG_NONE331
+
+#define AD7877_SEQ_YPLUS_BIT(1&lt;&lt;11)
+#define AD7877_SEQ_XPLUS_BIT(1&lt;&lt;10)
+#define AD7877_SEQ_Z2_BIT(1&lt;&lt;9)
+#define AD7877_SEQ_AUX1_BIT(1&lt;&lt;8)
+#define AD7877_SEQ_AUX2_BIT(1&lt;&lt;7)
+#define AD7877_SEQ_AUX3_BIT(1&lt;&lt;6)
+#define AD7877_SEQ_BAT1_BIT(1&lt;&lt;5)
+#define AD7877_SEQ_BAT2_BIT(1&lt;&lt;4)
+#define AD7877_SEQ_TEMP1_BIT(1&lt;&lt;3)
+#define AD7877_SEQ_TEMP2_BIT(1&lt;&lt;2)
+#define AD7877_SEQ_Z1_BIT(1&lt;&lt;1)
+
+enum {
+AD7877_SEQ_YPOS  = 0,
+AD7877_SEQ_XPOS  = 1,
+AD7877_SEQ_Z2    = 2,
+AD7877_SEQ_AUX1  = 3,
+AD7877_SEQ_AUX2  = 4,
+AD7877_SEQ_AUX3  = 5,
+AD7877_SEQ_BAT1  = 6,
+AD7877_SEQ_BAT2  = 7,
+AD7877_SEQ_TEMP1 = 8,
+AD7877_SEQ_TEMP2 = 9,
+AD7877_SEQ_Z1    = 10,
+AD7877_NR_SENSE  = 11,
+};
+
+/* DAC Register Default RANGE 0 to Vcc, Volatge Mode, DAC On */
+#define AD7877_DAC_CONF0x1
+
+/* If gpio3 is set AUX3/GPIO3 acts as GPIO Output */
+#define AD7877_EXTW_GPIO_3_CONF0x1C4
+#define AD7877_EXTW_GPIO_DATA0x200
+
+/* Control REG 2 */
+#define AD7877_TMR(x)((x &amp; 0x3) &lt;&lt; 0)
+#define AD7877_REF(x)((x &amp; 0x1) &lt;&lt; 2)
+#define AD7877_POL(x)((x &amp; 0x1) &lt;&lt; 3)
+#define AD7877_FCD(x)((x &amp; 0x3) &lt;&lt; 4)
+#define AD7877_PM(x)((x &amp; 0x3) &lt;&lt; 6)
+#define AD7877_ACQ(x)((x &amp; 0x3) &lt;&lt; 8)
+#define AD7877_AVG(x)((x &amp; 0x3) &lt;&lt; 10)
+
+/* Control REG 1 */
+#defineAD7877_SER(1 &lt;&lt; 11)/* non-differential */
+#defineAD7877_DFR(0 &lt;&lt; 11)/* differential */
+
+#define AD7877_MODE_NOC  (0)/* Do not convert */
+#define AD7877_MODE_SCC  (1)/* Single channel conversion */
+#define AD7877_MODE_SEQ0 (2)/* Sequence 0 in Slave Mode */
+#define AD7877_MODE_SEQ1 (3)/* Sequence 1 in Master Mode */
+
+#define AD7877_CHANADD(x)((x&amp;0xF)&lt;&lt;7)
+#define AD7877_READADD(x)((x)&lt;&lt;2)
+#define AD7877_WRITEADD(x)((x)&lt;&lt;12)
+
+#define AD7877_READ_CHAN(x) (AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_SER | \
+AD7877_MODE_SCC | AD7877_CHANADD(AD7877_REG_ ## x) | \
+AD7877_READADD(AD7877_REG_ ## x))
+
+#define AD7877_MM_SEQUENCE (AD7877_SEQ_YPLUS_BIT | AD7877_SEQ_XPLUS_BIT | \
+AD7877_SEQ_Z2_BIT | AD7877_SEQ_Z1_BIT)
+
+/*
+ * Non-touchscreen sensors only use single-ended conversions.
+ */
+
+struct ser_req {
+u16reset;
+u16ref_on;
+u16command;
+u16sample;
+struct spi_messagemsg;
+struct spi_transferxfer[6];
+};
+
+struct ad7877 {
+struct input_dev*input;
+charphys[32];
+
+struct spi_device*spi;
+u16model;
+u16vref_delay_usecs;
+u16x_plate_ohms;
+u16pressure_max;
+
+u16cmd_crtl1;
+u16cmd_crtl2;
+u16cmd_dummy;
+u16dac;
+
+u8stopacq_polarity;
+u8first_conversion_delay;
+u8acquisition_time;
+u8averaging;
+u8pen_down_acc_interval;
+
+u16 conversion_data[AD7877_NR_SENSE];
+
+struct spi_transferxfer[AD7877_NR_SENSE + 2];
+struct spi_messagemsg;
+
+spinlock_tlock;
+struct timer_listtimer;/* P: lock */
+unsignedpendown:1;/* P: lock */
+unsignedpending:1;/* P: lock */
+unsigneddisabled:1;
+unsignedgpio3:1;
+unsignedgpio4:1;
+};
+
+static int gpio3;
+
+/*
+ * ad7877_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done using spi_async() in the interrupt handler.
+ */
+
+static int ad7877_read(struct spi_device *spi, u16 reg)
+{
+struct ser_req*req = kzalloc(sizeof *req, GFP_KERNEL);
+intstatus, ret;
+
+if (!req)
+return -ENOMEM;
+
+spi_message_init(&amp;req-&gt;msg);
+
+req-&gt;command = (u16) (AD7877_WRITEADD(AD7877_REG_CTRL1) |
+AD7877_READADD(reg));
+req-&gt;xfer[0].tx_buf = &amp;req-&gt;command;
+req-&gt;xfer[0].len = 2;
+
+req-&gt;xfer[1].rx_buf = &amp;req-&gt;sample;
+req-&gt;xfer[1].len = 2;
+
+spi_message_add_tail(&amp;req-&gt;xfer[0], &amp;req-&gt;msg);
+spi_message_add_tail(&amp;req-&gt;xfer[1], &amp;req-&gt;msg);
+
+status = spi_sync(spi, &amp;req-&gt;msg);
+
+if (status == 0)
+status = req-&gt;msg.status;
+
+ret = status ? status : req-&gt;sample;
+kfree(req);
+
+return ret;
+}
+
+static int ad7877_write(struct spi_device *spi, u16 reg, u16 val)
+{
+struct ser_req*req = kzalloc(sizeof *req, GFP_KERNEL);
+intstatus;
+
+if (!req)
+return -ENOMEM;
+
+spi_message_init(&amp;req-&gt;msg);
+
+req-&gt;command = (u16) (AD7877_WRITEADD(reg) | (val &amp; MAX_12BIT));
+req-&gt;xfer[0].tx_buf = &amp;req-&gt;command;
+req-&gt;xfer[0].len = 2;
+
+spi_message_add_tail(&amp;req-&gt;xfer[0], &amp;req-&gt;msg);
+
+status = spi_sync(spi, &amp;req-&gt;msg);
+
+if (status == 0)
+status = req-&gt;msg.status;
+
+kfree(req);
+
+return status;
+}
+
+static int ad7877_read_adc(struct spi_device *spi, unsigned command)
+{
+struct ad7877 *ts = dev_get_drvdata(&amp;spi-&gt;dev);
+struct ser_req*req = kzalloc(sizeof *req, GFP_KERNEL);
+intstatus;
+intsample;
+inti;
+
+if (!req)
+return -ENOMEM;
+
+spi_message_init(&amp;req-&gt;msg);
+
+/* activate reference, so it has time to settle; */
+req-&gt;ref_on = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+ AD7877_POL(ts-&gt;stopacq_polarity) |
+ AD7877_AVG(0) | AD7877_PM(2) | AD7877_TMR(0) |
+ AD7877_ACQ(ts-&gt;acquisition_time) | AD7877_FCD(0);
+
+req-&gt;reset = AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_MODE_NOC;
+
+req-&gt;command = (u16) command;
+
+req-&gt;xfer[0].tx_buf = &amp;req-&gt;reset;
+req-&gt;xfer[0].len = 2;
+
+req-&gt;xfer[1].tx_buf = &amp;req-&gt;ref_on;
+req-&gt;xfer[1].len = 2;
+req-&gt;xfer[1].delay_usecs = ts-&gt;vref_delay_usecs;
+
+req-&gt;xfer[2].tx_buf = &amp;req-&gt;command;
+req-&gt;xfer[2].len = 2;
+req-&gt;xfer[2].delay_usecs = ts-&gt;vref_delay_usecs;
+
+req-&gt;xfer[3].rx_buf = &amp;req-&gt;sample;
+req-&gt;xfer[3].len = 2;
+
+req-&gt;xfer[4].tx_buf = &amp;ts-&gt;cmd_crtl2;/*REF OFF*/
+req-&gt;xfer[4].len = 2;
+
+req-&gt;xfer[5].tx_buf = &amp;ts-&gt;cmd_crtl1;/*DEFAULT*/
+req-&gt;xfer[5].len = 2;
+
+/* group all the transfers together, so we can't interfere with
+ * reading touchscreen state; disable penirq while sampling
+ */
+for (i = 0; i &lt; 6; i++)
+spi_message_add_tail(&amp;req-&gt;xfer[i], &amp;req-&gt;msg);
+
+status = spi_sync(spi, &amp;req-&gt;msg);
+
+if (status == 0)
+status = req-&gt;msg.status;
+
+sample = req-&gt;sample;
+
+kfree(req);
+return status ? status : sample;
+}
+
+static void ad7877_rx(struct ad7877 *ts)
+{
+struct input_dev*input_dev = ts-&gt;input;
+unsignedRt;
+u16x, y, z1, z2;
+
+x = ts-&gt;conversion_data[AD7877_SEQ_XPOS] &amp; MAX_12BIT;
+y = ts-&gt;conversion_data[AD7877_SEQ_YPOS] &amp; MAX_12BIT;
+z1 = ts-&gt;conversion_data[AD7877_SEQ_Z1] &amp; MAX_12BIT;
+z2 = ts-&gt;conversion_data[AD7877_SEQ_Z2] &amp; MAX_12BIT;
+
+/*
+ * The samples processed here are already preprocessed by the AD7877.
+ * The preprocessing function consists of an averaging filter.
+ * The combination of 'first conversion delay' and averaging provides a robust solution,
+ * discarding the spurious noise in the signal and keeping only the data of interest.
+ * The size of the averaging filter is programmable. (dev.platform_data, see linux/spi/ad7877.h)
+ * Other user-programmable conversion controls include variable acquisition time,
+ * and first conversion delay. Up to 16 averages can be taken per conversion.
+ */
+
+if (likely(x &amp;&amp; z1)) {
+/* compute touch pressure resistance using equation #1 */
+Rt = (z2 - z1) * x * ts-&gt;x_plate_ohms;
+Rt /= z1;
+Rt = (Rt + 2047) &gt;&gt; 12;
+} else
+Rt = 0;
+
+if (Rt) {
+input_report_abs(input_dev, ABS_X, x);
+input_report_abs(input_dev, ABS_Y, y);
+input_report_abs(input_dev, ABS_PRESSURE, Rt);
+input_sync(input_dev);
+}
+}
+
+static inline void ad7877_ts_event_release(struct ad7877 *ts)
+{
+struct input_dev *input_dev = ts-&gt;input;
+
+input_report_abs(input_dev, ABS_PRESSURE, 0);
+input_sync(input_dev);
+}
+
+static void ad7877_timer(unsigned long handle)
+{
+struct ad7877*ts = (void *)handle;
+
+ad7877_ts_event_release(ts);
+}
+
+static irqreturn_t ad7877_irq(int irq, void *handle)
+{
+struct ad7877 *ts = handle;
+unsigned long flags;
+int status;
+
+/* The repeated conversion sequencer controlled by TMR kicked off too fast.
+ * We ignore the last and process the sample sequence currently in the queue
+ * It can't be older than 9.4ms, and we need to avoid that ts-&gt;msg
+ * doesn't get issued twice while in work.
+ */
+
+spin_lock_irqsave(&amp;ts-&gt;lock, flags);
+if (ts-&gt;pending) {
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+return IRQ_HANDLED;
+}
+ts-&gt;pending = 1;
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+
+status = spi_async(ts-&gt;spi, &amp;ts-&gt;msg);
+
+if (status)
+dev_err(&amp;ts-&gt;spi-&gt;dev, "spi_sync --&gt; %d\n", status);
+
+return IRQ_HANDLED;
+}
+
+static void ad7877_callback(void *_ts)
+{
+struct ad7877 *ts = _ts;
+unsigned long flags;
+
+ad7877_rx(ts);
+
+spin_lock_irqsave(&amp;ts-&gt;lock, flags);
+ts-&gt;pending = 0;
+mod_timer(&amp;ts-&gt;timer, jiffies + TS_PEN_UP_TIMEOUT);
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+}
+
+static void ad7877_disable(struct ad7877 *ts)
+{
+unsigned long flags;
+
+spin_lock_irqsave(&amp;ts-&gt;lock, flags);
+if (ts-&gt;disabled) {
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+return;
+}
+
+ts-&gt;disabled = 1;
+disable_irq(ts-&gt;spi-&gt;irq);
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+
+while (ts-&gt;pending) /* Wait for spi_async callback */
+msleep(1);
+
+if (del_timer_sync(&amp;ts-&gt;timer))
+ad7877_ts_event_release(ts);
+
+/* we know the chip's in lowpower mode since we always
+ * leave it that way after every request
+ */
+}
+
+static void ad7877_enable(struct ad7877 *ts)
+{
+unsigned long flags;
+
+spin_lock_irqsave(&amp;ts-&gt;lock, flags);
+if (ts-&gt;disabled) {
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+return;
+}
+ts-&gt;disabled = 0;
+enable_irq(ts-&gt;spi-&gt;irq);
+spin_unlock_irqrestore(&amp;ts-&gt;lock, flags);
+}
+
+#define SHOW(name) static ssize_t \
+name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+struct ad7877*ts = dev_get_drvdata(dev); \
+ssize_t v = ad7877_read_adc(ts-&gt;spi, \
+AD7877_READ_CHAN(name)); \
+if (v &lt; 0) \
+return v; \
+return sprintf(buf, "%u\n", (unsigned) v); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
+
+SHOW(aux1)
+SHOW(aux2)
+SHOW(aux3)
+SHOW(bat1)
+SHOW(bat2)
+SHOW(temp1)
+SHOW(temp2)
+
+static ssize_t ad7877_disable_show(struct device *dev,
+     struct device_attribute *attr, char *buf)
+{
+struct ad7877*ts = dev_get_drvdata(dev);
+
+return sprintf(buf, "%u\n", ts-&gt;disabled);
+}
+
+static ssize_t ad7877_disable_store(struct device *dev,
+     struct device_attribute *attr,
+     const char *buf, size_t count)
+{
+struct ad7877 *ts = dev_get_drvdata(dev);
+unsigned long val;
+int ret;
+
+ret = strict_strtoul(buf, 10, &amp;val);
+
+if (ret)
+return ret;
+
+if (val)
+ad7877_disable(ts);
+else
+ad7877_enable(ts);
+
+return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store);
+
+static ssize_t ad7877_dac_show(struct device *dev,
+     struct device_attribute *attr, char *buf)
+{
+struct ad7877*ts = dev_get_drvdata(dev);
+
+return sprintf(buf, "%u\n", ts-&gt;dac);
+}
+
+static ssize_t ad7877_dac_store(struct device *dev,
+     struct device_attribute *attr,
+     const char *buf, size_t count)
+{
+struct ad7877 *ts = dev_get_drvdata(dev);
+unsigned long val;
+int ret;
+
+ret = strict_strtoul(buf, 10, &amp;val);
+
+if (ret)
+return ret;
+
+ts-&gt;dac = val &amp; 0xFF;
+
+ad7877_write(ts-&gt;spi, AD7877_REG_DAC, (ts-&gt;dac &lt;&lt; 4) | AD7877_DAC_CONF);
+
+return count;
+}
+
+static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store);
+
+static ssize_t ad7877_gpio3_show(struct device *dev,
+     struct device_attribute *attr, char *buf)
+{
+struct ad7877*ts = dev_get_drvdata(dev);
+
+return sprintf(buf, "%u\n", ts-&gt;gpio3);
+}
+
+static ssize_t ad7877_gpio3_store(struct device *dev,
+     struct device_attribute *attr,
+     const char *buf, size_t count)
+{
+struct ad7877 *ts = dev_get_drvdata(dev);
+unsigned long val;
+int ret;
+
+ret = strict_strtoul(buf, 10, &amp;val);
+if (ret)
+return ret;
+
+ts-&gt;gpio3 = !!val;
+
+ad7877_write(ts-&gt;spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+ (ts-&gt;gpio4 &lt;&lt; 4) | (ts-&gt;gpio3 &lt;&lt; 5));
+
+return count;
+}
+
+static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store);
+
+static ssize_t ad7877_gpio4_show(struct device *dev,
+     struct device_attribute *attr, char *buf)
+{
+struct ad7877*ts = dev_get_drvdata(dev);
+
+return sprintf(buf, "%u\n", ts-&gt;gpio4);
+}
+
+static ssize_t ad7877_gpio4_store(struct device *dev,
+     struct device_attribute *attr,
+     const char *buf, size_t count)
+{
+struct ad7877 *ts = dev_get_drvdata(dev);
+unsigned long val;
+int ret;
+
+ret = strict_strtoul(buf, 10, &amp;val);
+if (ret)
+return ret;
+
+ts-&gt;gpio4 = !!val;
+
+ad7877_write(ts-&gt;spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+ (ts-&gt;gpio4 &lt;&lt; 4) | (ts-&gt;gpio3 &lt;&lt; 5));
+
+return count;
+}
+
+static DEVICE_ATTR(gpio4, 0664, ad7877_gpio4_show, ad7877_gpio4_store);
+
+static struct attribute *ad7877_attributes[] = {
+&amp;dev_attr_temp1.attr,
+&amp;dev_attr_temp2.attr,
+&amp;dev_attr_aux1.attr,
+&amp;dev_attr_aux2.attr,
+&amp;dev_attr_bat1.attr,
+&amp;dev_attr_bat2.attr,
+&amp;dev_attr_disable.attr,
+&amp;dev_attr_dac.attr,
+&amp;dev_attr_gpio4.attr,
+NULL
+};
+
+static const struct attribute_group ad7877_attr_group = {
+.attrs = ad7877_attributes,
+};
+
+static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts)
+{
+struct spi_message *m;
+int i;
+
+ts-&gt;cmd_crtl2 = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+AD7877_POL(ts-&gt;stopacq_polarity) |
+AD7877_AVG(ts-&gt;averaging) | AD7877_PM(1) |
+AD7877_TMR(ts-&gt;pen_down_acc_interval) |
+AD7877_ACQ(ts-&gt;acquisition_time) |
+AD7877_FCD(ts-&gt;first_conversion_delay);
+
+ad7877_write(spi, AD7877_REG_CTRL2, ts-&gt;cmd_crtl2);
+
+ts-&gt;cmd_crtl1 = AD7877_WRITEADD(AD7877_REG_CTRL1) |
+AD7877_READADD(AD7877_REG_XPLUS-1) |
+AD7877_MODE_SEQ1 | AD7877_DFR;
+
+ad7877_write(spi, AD7877_REG_CTRL1, ts-&gt;cmd_crtl1);
+
+ts-&gt;cmd_dummy = 0;
+
+m = &amp;ts-&gt;msg;
+
+spi_message_init(m);
+
+m-&gt;complete = ad7877_callback;
+m-&gt;context = ts;
+
+ts-&gt;xfer[0].tx_buf = &amp;ts-&gt;cmd_crtl1;
+ts-&gt;xfer[0].len = 2;
+
+spi_message_add_tail(&amp;ts-&gt;xfer[0], m);
+
+ts-&gt;xfer[1].tx_buf = &amp;ts-&gt;cmd_dummy; /* Send ZERO */
+ts-&gt;xfer[1].len = 2;
+
+spi_message_add_tail(&amp;ts-&gt;xfer[1], m);
+
+for (i = 0; i &lt; 11; i++) {
+ts-&gt;xfer[i + 2].rx_buf = &amp;ts-&gt;conversion_data[AD7877_SEQ_YPOS + i];
+ts-&gt;xfer[i + 2].len = 2;
+spi_message_add_tail(&amp;ts-&gt;xfer[i + 2], m);
+}
+}
+
+static int __devinit ad7877_probe(struct spi_device *spi)
+{
+struct ad7877*ts;
+struct input_dev*input_dev;
+struct ad7877_platform_data*pdata = spi-&gt;dev.platform_data;
+interr;
+u16verify;
+
+if (!spi-&gt;irq) {
+dev_dbg(&amp;spi-&gt;dev, "no IRQ?\n");
+return -ENODEV;
+}
+
+if (!pdata) {
+dev_dbg(&amp;spi-&gt;dev, "no platform data?\n");
+return -ENODEV;
+}
+
+/* don't exceed max specified SPI CLK frequency */
+if (spi-&gt;max_speed_hz &gt; MAX_SPI_FREQ_HZ) {
+dev_dbg(&amp;spi-&gt;dev, "SPI CLK %d Hz?\n",spi-&gt;max_speed_hz);
+return -EINVAL;
+}
+
+ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL);
+if (!ts)
+return -ENOMEM;
+
+
+input_dev = input_allocate_device();
+if (!input_dev) {
+kfree(ts);
+return -ENOMEM;
+}
+
+dev_set_drvdata(&amp;spi-&gt;dev, ts);
+ts-&gt;spi = spi;
+ts-&gt;input = input_dev;
+
+setup_timer(&amp;ts-&gt;timer, ad7877_timer, (unsigned long) ts);
+spin_lock_init(&amp;ts-&gt;lock);
+
+ts-&gt;model = pdata-&gt;model ? : 7877;
+ts-&gt;vref_delay_usecs = pdata-&gt;vref_delay_usecs ? : 100;
+ts-&gt;x_plate_ohms = pdata-&gt;x_plate_ohms ? : 400;
+ts-&gt;pressure_max = pdata-&gt;pressure_max ? : ~0;
+
+ts-&gt;stopacq_polarity = pdata-&gt;stopacq_polarity;
+ts-&gt;first_conversion_delay = pdata-&gt;first_conversion_delay;
+ts-&gt;acquisition_time = pdata-&gt;acquisition_time;
+ts-&gt;averaging = pdata-&gt;averaging;
+ts-&gt;pen_down_acc_interval = pdata-&gt;pen_down_acc_interval;
+
+snprintf(ts-&gt;phys, sizeof(ts-&gt;phys), "%s/inputX", spi-&gt;dev.bus_id);
+
+input_dev-&gt;name = "AD7877 Touchscreen";
+input_dev-&gt;phys = ts-&gt;phys;
+input_dev-&gt;dev.parent = &amp;spi-&gt;dev;
+
+__set_bit(EV_ABS, input_dev-&gt;evbit);
+__set_bit(ABS_X, input_dev-&gt;absbit);
+__set_bit(ABS_Y, input_dev-&gt;absbit);
+__set_bit(ABS_PRESSURE, input_dev-&gt;absbit);
+
+input_set_abs_params(input_dev, ABS_X,
+pdata-&gt;x_min ? : 0,
+pdata-&gt;x_max ? : MAX_12BIT,
+0, 0);
+input_set_abs_params(input_dev, ABS_Y,
+pdata-&gt;y_min ? : 0,
+pdata-&gt;y_max ? : MAX_12BIT,
+0, 0);
+input_set_abs_params(input_dev, ABS_PRESSURE,
+pdata-&gt;pressure_min, pdata-&gt;pressure_max, 0, 0);
+
+ad7877_write(spi, AD7877_REG_SEQ1, AD7877_MM_SEQUENCE);
+
+verify = ad7877_read(spi, AD7877_REG_SEQ1);
+
+if (verify != AD7877_MM_SEQUENCE){
+dev_err(&amp;spi-&gt;dev, "%s: Failed to probe %s\n", spi-&gt;dev.bus_id,
+ input_dev-&gt;name);
+err = -ENODEV;
+goto err_free_mem;
+}
+
+if (gpio3)
+ad7877_write(spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_3_CONF);
+
+ad7877_setup_ts_def_msg(spi, ts);
+
+/* Request AD7877 /DAV GPIO interrupt */
+
+err = request_irq(spi-&gt;irq, ad7877_irq, IRQF_TRIGGER_FALLING |
+IRQF_SAMPLE_RANDOM, spi-&gt;dev.driver-&gt;name, ts);
+if (err) {
+dev_dbg(&amp;spi-&gt;dev, "irq %d busy?\n", spi-&gt;irq);
+goto err_free_mem;
+}
+
+err = sysfs_create_group(&amp;spi-&gt;dev.kobj, &amp;ad7877_attr_group);
+
+if (gpio3)
+err |= device_create_file(&amp;spi-&gt;dev, &amp;dev_attr_gpio3);
+else
+err |= device_create_file(&amp;spi-&gt;dev, &amp;dev_attr_aux3);
+
+if (err)
+goto err_free_irq;
+
+err = input_register_device(input_dev);
+if (err)
+goto err_remove_attr;
+
+dev_info(&amp;spi-&gt;dev, "touchscreen, irq %d\n", spi-&gt;irq);
+
+return 0;
+
+err_remove_attr:
+sysfs_remove_group(&amp;spi-&gt;dev.kobj, &amp;ad7877_attr_group);
+
+if (gpio3)
+device_remove_file(&amp;spi-&gt;dev, &amp;dev_attr_gpio3);
+else
+device_remove_file(&amp;spi-&gt;dev, &amp;dev_attr_aux3);
+err_free_irq:
+free_irq(spi-&gt;irq, ts);
+err_free_mem:
+input_free_device(input_dev);
+kfree(ts);
+dev_set_drvdata(&amp;spi-&gt;dev, NULL);
+return err;
+}
+
+static int __devexit ad7877_remove(struct spi_device *spi)
+{
+struct ad7877*ts = dev_get_drvdata(&amp;spi-&gt;dev);
+
+ad7877_disable(ts);
+
+sysfs_remove_group(&amp;spi-&gt;dev.kobj, &amp;ad7877_attr_group);
+
+if (gpio3)
+device_remove_file(&amp;spi-&gt;dev, &amp;dev_attr_gpio3);
+else
+device_remove_file(&amp;spi-&gt;dev, &amp;dev_attr_aux3);
+
+free_irq(ts-&gt;spi-&gt;irq, ts);
+
+input_unregister_device(ts-&gt;input);
+
+kfree(ts);
+
+dev_dbg(&amp;spi-&gt;dev, "unregistered touchscreen\n");
+dev_set_drvdata(&amp;spi-&gt;dev, NULL);
+
+return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7877_suspend(struct spi_device *spi, pm_message_t message)
+{
+struct ad7877 *ts = dev_get_drvdata(&amp;spi-&gt;dev);
+
+ad7877_disable(ts);
+
+return 0;
+}
+
+static int ad7877_resume(struct spi_device *spi)
+{
+struct ad7877 *ts = dev_get_drvdata(&amp;spi-&gt;dev);
+
+ad7877_enable(ts);
+
+return 0;
+}
+#else
+#define ad7877_suspend NULL
+#define ad7877_resume  NULL
+#endif
+
+static struct spi_driver ad7877_driver = {
+.driver = {
+.name= "ad7877",
+.bus= &amp;spi_bus_type,
+.owner= THIS_MODULE,
+},
+.probe= ad7877_probe,
+.remove= __devexit_p(ad7877_remove),
+.suspend= ad7877_suspend,
+.resume= ad7877_resume,
+};
+
+static int __init ad7877_init(void)
+{
+return spi_register_driver(&amp;ad7877_driver);
+}
+module_init(ad7877_init);
+
+static void __exit ad7877_exit(void)
+{
+spi_unregister_driver(&amp;ad7877_driver);
+}
+module_exit(ad7877_exit);
+
+module_param(gpio3, int, 0);
+MODULE_PARM_DESC(gpio3,
+"If gpio3 is set to 1 AUX3 acts as GPIO3");
+
+MODULE_AUTHOR("Michael Hennerich &lt;hennerich&lt; at &gt;blackfin.uclinux.org&gt;");
+MODULE_DESCRIPTION("AD7877 touchscreen Driver");
+MODULE_LICENSE("GPL");
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:13</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6132">
    <title>[patch 5/8] input: mousedev: distinguish a moving finger from a tapping finger</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6132</link>
    <description>From: Henrik Rydberg &lt;rydberg&lt; at &gt;euromail.se&gt;

The tap functionality of mousedev does not distinguish between a tap
(on/off localized in time and space) and a quick move (on/off localized in
time only).  This patch improves the tap detection by testing also for
space locality.

Signed-off-by: Henrik Rydberg &lt;rydberg&lt; at &gt;euromail.se&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/mousedev.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff -puN drivers/input/mousedev.c~input-mousedev-distinguish-a-moving-finger-from-a-tapping-finger drivers/input/mousedev.c
--- a/drivers/input/mousedev.c~input-mousedev-distinguish-a-moving-finger-from-a-tapping-finger
+++ a/drivers/input/mousedev.c
&lt; at &gt;&lt; at &gt; -49,6 +49,10 &lt; at &gt;&lt; at &gt; static unsigned tap_time = 200;
 module_param(tap_time, uint, 0644);
 MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
 
+static unsigned tap_move = 20;
+module_param(tap_move, uint, 0644);
+MODULE_PARM_DESC(tap_move, "Tap distance for touchpads in absolute mode (res)");
+
 struct mousedev_hw_data {
 int dx, dy, dz;
 int x, y;
&lt; at &gt;&lt; at &gt; -76,6 +80,7 &lt; at &gt;&lt; at &gt; struct mousedev {
 int old_x[4], old_y[4];
 int frac_dx, frac_dy;
 unsigned long touch;
+int touch_dx, touch_dy;
 };
 
 enum mousedev_emul {
&lt; at &gt;&lt; at &gt; -143,6 +148,7 &lt; at &gt;&lt; at &gt; static void mousedev_touchpad_event(stru
 tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
 tmp += mousedev-&gt;frac_dx;
 mousedev-&gt;packet.dx = tmp / FRACTION_DENOM;
+mousedev-&gt;touch_dx += mousedev-&gt;packet.dx;
 mousedev-&gt;frac_dx =
 tmp - mousedev-&gt;packet.dx * FRACTION_DENOM;
 }
&lt; at &gt;&lt; at &gt; -158,6 +164,7 &lt; at &gt;&lt; at &gt; static void mousedev_touchpad_event(stru
 tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
 tmp += mousedev-&gt;frac_dy;
 mousedev-&gt;packet.dy = tmp / FRACTION_DENOM;
+mousedev-&gt;touch_dy += mousedev-&gt;packet.dy;
 mousedev-&gt;frac_dy = tmp -
 mousedev-&gt;packet.dy * FRACTION_DENOM;
 }
&lt; at &gt;&lt; at &gt; -320,6 +327,8 &lt; at &gt;&lt; at &gt; static void mousedev_touchpad_touch(stru
 {
 if (!value) {
 if (mousedev-&gt;touch &amp;&amp;
+    abs(mousedev-&gt;touch_dx) &lt; tap_move &amp;&amp;
+    abs(mousedev-&gt;touch_dy) &lt; tap_move &amp;&amp;
     time_before(jiffies,
 mousedev-&gt;touch + msecs_to_jiffies(tap_time))) {
 /*
&lt; at &gt;&lt; at &gt; -336,6 +345,7 &lt; at &gt;&lt; at &gt; static void mousedev_touchpad_touch(stru
 clear_bit(0, &amp;mousedev_mix-&gt;packet.buttons);
 }
 mousedev-&gt;touch = mousedev-&gt;pkt_count = 0;
+mousedev-&gt;touch_dx = mousedev-&gt;touch_dy = 0;
 mousedev-&gt;frac_dx = 0;
 mousedev-&gt;frac_dy = 0;
 
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:15</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6131">
    <title>[patch 6/8] i8042: add Blue FB5601 to noloop exception table</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6131</link>
    <description>From: "Stefan Bader" &lt;sbader3&lt; at &gt;googlemail.com&gt;

Signed-off-by: Stefan Bader &lt;stefan.bader&lt; at &gt;canonical.com&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/serio/i8042-x86ia64io.h |    8 ++++++++
 1 file changed, 8 insertions(+)

diff -puN drivers/input/serio/i8042-x86ia64io.h~i8042-add-blue-fb5601-to-noloop-execption-table drivers/input/serio/i8042-x86ia64io.h
--- a/drivers/input/serio/i8042-x86ia64io.h~i8042-add-blue-fb5601-to-noloop-execption-table
+++ a/drivers/input/serio/i8042-x86ia64io.h
&lt; at &gt;&lt; at &gt; -143,6 +143,14 &lt; at &gt;&lt; at &gt; static struct dmi_system_id __initdata i
 DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
 },
 },
+{
+.ident = "Blue FB5601",
+.matches = {
+DMI_MATCH(DMI_SYS_VENDOR, "blue"),
+DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
+DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
+},
+},
 { }
 };
 
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6130">
    <title>[patch 3/8] input: ads7846.c sparse lock annotation</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6130</link>
    <description>From: Harvey Harrison &lt;harvey.harrison&lt; at &gt;gmail.com&gt;

Signed-off-by: Harvey Harrison &lt;harvey.harrison&lt; at &gt;gmail.com&gt;
Cc: Dmitry Torokhov &lt;dtor&lt; at &gt;mail.ru&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/touchscreen/ads7846.c |    2 ++
 1 file changed, 2 insertions(+)

diff -puN drivers/input/touchscreen/ads7846.c~input-ads7846c-sparse-lock-annotation drivers/input/touchscreen/ads7846.c
--- a/drivers/input/touchscreen/ads7846.c~input-ads7846c-sparse-lock-annotation
+++ a/drivers/input/touchscreen/ads7846.c
&lt; at &gt;&lt; at &gt; -761,6 +761,8 &lt; at &gt;&lt; at &gt; static irqreturn_t ads7846_irq(int irq, 
 
 /* Must be called with ts-&gt;lock held */
 static void ads7846_disable(struct ads7846 *ts)
+__acquires(&amp;ts-&gt;lock)
+__releases(&amp;ts-&gt;lock)
 {
 if (ts-&gt;disabled)
 return;
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6129">
    <title>[patch 4/8] serio_raw: add support for translated (SERIO_I8042XL) ports</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6129</link>
    <description>From: "Niels de Vos" &lt;niels.devos&lt; at &gt;wincor-nixdorf.com&gt;

serio_raw only binds to non-translated devices. Enable serio_raw to
bind to normal (translated) keyboards which can have non-standard
extensions (like POS Keyboards). With this it is possible to send
commands to the device over /dev/serio_raw&lt;n&gt;.

Signed-off-by: Niels de Vos &lt;niels.devos&lt; at &gt;wincor-nixdorf.com&gt;
Cc: Dmitry Torokhov &lt;dmitry.torokhov&lt; at &gt;gmail.com&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/serio/serio_raw.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff -puN drivers/input/serio/serio_raw.c~serio_raw-add-support-for-translated-serio_i8042xl-ports drivers/input/serio/serio_raw.c
--- a/drivers/input/serio/serio_raw.c~serio_raw-add-support-for-translated-serio_i8042xl-ports
+++ a/drivers/input/serio/serio_raw.c
&lt; at &gt;&lt; at &gt; -378,6 +378,12 &lt; at &gt;&lt; at &gt; static struct serio_device_id serio_raw_
 .id= SERIO_ANY,
 .extra= SERIO_ANY,
 },
+{
+.type   = SERIO_8042_XL,
+.proto  = SERIO_ANY,
+.id     = SERIO_ANY,
+.extra  = SERIO_ANY,
+},
 { 0 }
 };
 
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6128">
    <title>[patch 8/8] input/mouse/alps.c: handle touchpoints buttons correctly</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6128</link>
    <description>From: Ulrich Dangel &lt;uli-kernel&lt; at &gt;spamt.net&gt;

When pressing any button belonging to the touchpoint, the generated click
events dont belong to the touchpoint but to the touchpad.

This patch fixes this behaviour, the events will be sent via the correct
device, so scrolling with touchpoint is possible.

The patch compiles cleanly and has been tested successfully on my machine.

Signed-off-by: Ulrich Dangel &lt;uli&lt; at &gt;spamt.net&gt;
Cc: Dmitry Torokhov &lt;dtor&lt; at &gt;mail.ru&gt;
Signed-off-by: Andrew Morton &lt;akpm&lt; at &gt;linux-foundation.org&gt;
---

 drivers/input/mouse/alps.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff -puN drivers/input/mouse/alps.c~input-mouse-alpsc-handle-touchpoints-buttons-correctly drivers/input/mouse/alps.c
--- a/drivers/input/mouse/alps.c~input-mouse-alpsc-handle-touchpoints-buttons-correctly
+++ a/drivers/input/mouse/alps.c
&lt; at &gt;&lt; at &gt; -131,18 +131,23 &lt; at &gt;&lt; at &gt; static void alps_process_packet(struct p
 ges = packet[2] &amp; 1;
 fin = packet[2] &amp; 2;
 
-input_report_key(dev, BTN_LEFT, left);
-input_report_key(dev, BTN_RIGHT, right);
-input_report_key(dev, BTN_MIDDLE, middle);
-
 if ((priv-&gt;i-&gt;flags &amp; ALPS_DUALPOINT) &amp;&amp; z == 127) {
 input_report_rel(dev2, REL_X,  (x &gt; 383 ? (x - 768) : x));
 input_report_rel(dev2, REL_Y, -(y &gt; 255 ? (y - 512) : y));
+
+input_report_key(dev2, BTN_LEFT, left);
+input_report_key(dev2, BTN_RIGHT, right);
+input_report_key(dev2, BTN_MIDDLE, middle);
+
 input_sync(dev);
 input_sync(dev2);
 return;
 }
 
+input_report_key(dev, BTN_LEFT, left);
+input_report_key(dev, BTN_RIGHT, right);
+input_report_key(dev, BTN_MIDDLE, middle);
+
 /* Convert hardware tap to a reasonable Z value */
 if (ges &amp;&amp; !fin) z = 40;
 
_
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>akpm&lt; at &gt;linux-foundation.org</dc:creator>
    <dc:date>2008-12-01T22:20:17</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6124">
    <title>Re: Logitech Alto Cordless</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6124</link>
    <description>Jiri Kosina pisze:
OK, got it. hid is builtin.
</description>
    <dc:creator>Julian Sikorski</dc:creator>
    <dc:date>2008-12-01T17:54:15</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6123">
    <title>Re: Logitech Alto Cordless</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6123</link>
    <description>Jiri Kosina pisze:
Hmm, the option is set, but there are no such modules here...
I am running 2.6.27.5-117.fc10.x86_64 kernel. Relevant lsusb output:
Bus 001 Device 014: ID 046d:c527 Logitech, Inc.

Julian

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Julian Sikorski</dc:creator>
    <dc:date>2008-12-01T16:46:49</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6122">
    <title>Re: Logitech Alto Cordless</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6122</link>
    <description>

In order to answer this question, we need to know what the keyboard is 
acutally sending when these keys are being pressed (and also product ID 
would be useful -- this can be obtained from lsusb output).

Assuming that Fedora has the CONFIG_HID_DEBUG kernel option turned on (I 
don't know whether this is true or not), could you please

rmmod usbhid
rmmod hid
modprobe hid debug=2
modprobe usbhid

press the keys, and send the dmesg output?

Thanks,

</description>
    <dc:creator>Jiri Kosina</dc:creator>
    <dc:date>2008-12-01T16:36:35</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6121">
    <title>Logitech Alto Cordless</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6121</link>
    <description>Hi,

during a discussion on fedora-devel-list, I was suggested to check if
the said keyboard is compliant with the standards before requesting
xkeyboard-config changes. The problem exists with two keys:
- Fn-F3, has MSIE logo on it, emits XF86HomePage, should emit XF86WWW
- Fn-F4, has a tune on it, emit XF86Tools, should XF86AudioMedia
This is under Fedora 10 x86_64, using evdev driver and evdev-managed
keyboard map.

Regards,
Julian
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Julian Sikorski</dc:creator>
    <dc:date>2008-12-01T13:21:00</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6120">
    <title>Re: locking in hidraw</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6120</link>
    <description>

Yes, it makes sense. Could you please fold this change together with the 
hidraw changes you are going to push with the autosuspend patches?

Thanks,

</description>
    <dc:creator>Jiri Kosina</dc:creator>
    <dc:date>2008-12-01T10:07:13</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6119">
    <title>Re: [PATCH] Fujitsu Amilo PA 1510 key-release events quirk</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6119</link>
    <description>

                               ^ const

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Andrew Morton</dc:creator>
    <dc:date>2008-11-30T07:42:30</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6118">
    <title>Re: [PATCH] Fujitsu Amilo PA 1510 key-release events quirk</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6118</link>
    <description>

It's best to make forced_release_keys static as well - there is no need
to build this array on the stack at runtime.  The compiler _could_
perform this optimisation itself andallegedly it will sometimes do so. 
Last time I checked it did not.

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Andrew Morton</dc:creator>
    <dc:date>2008-11-30T07:41:48</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6117">
    <title>Re: [PATCH] Fujitsu Amilo PA 1510 key-release events quirk</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6117</link>
    <description>

Please don't send more than one patch per email.  I shall comment on
the two patches in two separate replies.


Please also cc linux-input&lt; at &gt;vger.kernel.org on input-related patches.


oh my.  Please, no.  Just write a C function:

void atkbd_gen_release_event(unsigned int *keys, unsigned nr_keys)
{
...
}


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Andrew Morton</dc:creator>
    <dc:date>2008-11-30T07:38:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6116">
    <title>Re: New Force Feedback device support - GreenAsia 0x12</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6116</link>
    <description>

OK, so as the reports are not really identical, and in the future we might 
discover that there are many more other Greenasia devices which require a 
slightly different handling as well, I would rather prefer to have it as a 
separate driver, to avoid additions of here-and-there device-specific 
quirks to random places in the code. That's exactly what we are trying to 
avoid with the HID bus approach in the first place.

So I think separate driver is fine.

Thanks to both of you.

</description>
    <dc:creator>Jiri Kosina</dc:creator>
    <dc:date>2008-11-29T22:30:19</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6115">
    <title>PHP購物車資料庫網站專案</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6115</link>
    <description>山鉧科技網頁設計

○我們的宗旨：客戶的每ㄧ件小事情，都是山鉧的大事情

＆我們在推出企業形象網站包含前台網頁美工+後台管理程式

⊕限時限量專案價 只要$29,900

↑(在送ㄧ年100MB不限流量網站空間)

□我們做的不只是網站，而是您企業的入口

※ㄧ個好的企業網站資料即時更新的速度是很重要的

▼企業ｅ化的高品質團隊，打造您的網路門面

￥選擇山鉧成就您的夢想

～～～～～～～～～～～～～～～～～～～～～～～～～～
PS: 線上購物網站我們還可提供刷卡機制，
　　與線上列印帳單全省超商+郵局繳費......等金流服務機制
～～～～～～～～～～～～～～～～～～～～～～～～～～

歡迎來電洽詢黃專員（Sam）：0980119812 / 0938764395

～～～～～～～～～～～～～～～～～～～～～～～～～～
本公司另外提供關鍵字SEO排序服務
保證將您的網站在Yx / Gx ...排在第一頁
　　　　　　　　　　　　　　　　　　 歡迎來電詢問!!!
～～～～～～～～～～～～～～～～～～～～～～～～～～
</description>
    <dc:creator>王冠宇</dc:creator>
    <dc:date>2008-11-29T21:10:21</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.input/6114">
    <title>[PATCH] Input: Make MOUSE_PS2_LIFEBOOK depend on X86</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.input/6114</link>
    <description>As far as I know, all Fujitsu-Siemens Lifebook systems are x86-based.
So we might was well make MOUSE_PS2_LIFEBOOK depend on X86. This will
avoid surprising things like:

arch/arm/configs/s3c2410_defconfig:CONFIG_MOUSE_PS2_LIFEBOOK=y

(and several dozen similar ones.)

Signed-off-by: Jean Delvare &lt;khali&lt; at &gt;linux-fr.org&gt;
Cc: Dmitry Torokhov &lt;dmitry.torokhov&lt; at &gt;gmail.com&gt;
---
 drivers/input/mouse/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-2.6.28-rc6.orig/drivers/input/mouse/Kconfig2008-11-04 21:39:20.000000000 +0100
+++ linux-2.6.28-rc6/drivers/input/mouse/Kconfig2008-11-29 19:00:31.000000000 +0100
&lt; at &gt;&lt; at &gt; -70,7 +70,7 &lt; at &gt;&lt; at &gt; config MOUSE_PS2_SYNAPTICS
 config MOUSE_PS2_LIFEBOOK
 bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
 default y
-depends on MOUSE_PS2
+depends on MOUSE_PS2 &amp;&amp; X86
 help
   Say Y here if you have a Fujitsu B-series Lifebook PS/2
   TouchScreen connected to your system.


</description>
    <dc:creator>Jean Delvare</dc:creator>
    <dc:date>2008-11-29T18:11:30</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.kernel.input">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.kernel.input</link>
  </textinput>
</rdf:RDF>
