Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 1/2] Input: amikbd - Fix build if !CONFIG_HW_CONSOLE
From: Geert Uytterhoeven @ 2014-11-27  9:42 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, linux-m68k, Geert Uytterhoeven

If CONFIG_HW_CONSOLE is not set:

drivers/built-in.o: In function `amikbd_probe':
amikbd.c:(.init.text+0x3e4e): undefined reference to `key_maps'
amikbd.c:(.init.text+0x3dd4): undefined reference to `key_maps'

To fix this, extract the initialization of the console keyboard maps
into amikbd_init_console_keymaps(), protected by #ifdef
CONFIG_HW_CONSOLE.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
Discovered during randconfig builds.
---
 drivers/input/keyboard/amikbd.c | 46 ++++++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 096d6067ae1f890f..4f81e65d9e35cb7d 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -45,6 +45,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Amiga keyboard driver");
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_HW_CONSOLE
 static unsigned char amikbd_keycode[0x78] __initdata = {
 	[0]	 = KEY_GRAVE,
 	[1]	 = KEY_1,
@@ -144,6 +145,31 @@ static unsigned char amikbd_keycode[0x78] __initdata = {
 	[103]	 = KEY_RIGHTMETA
 };
 
+static void __init amikbd_init_console_keymaps(void)
+{
+	int i, j;
+
+	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
+		static u_short temp_map[NR_KEYS] __initdata;
+		if (!key_maps[i])
+			continue;
+		memset(temp_map, 0, sizeof(temp_map));
+		for (j = 0; j < 0x78; j++) {
+			if (!amikbd_keycode[j])
+				continue;
+			temp_map[j] = key_maps[i][amikbd_keycode[j]];
+		}
+		for (j = 0; j < NR_KEYS; j++) {
+			if (!temp_map[j])
+				temp_map[j] = 0xf200;
+		}
+		memcpy(key_maps[i], temp_map, sizeof(temp_map));
+	}
+}
+#else /* !CONFIG_HW_CONSOLE */
+static inline void amikbd_init_console_keymaps(void) {}
+#endif /* !CONFIG_HW_CONSOLE */
+
 static const char *amikbd_messages[8] = {
 	[0] = KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n",
 	[1] = KERN_WARNING "amikbd: keyboard lost sync\n",
@@ -186,7 +212,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *data)
 static int __init amikbd_probe(struct platform_device *pdev)
 {
 	struct input_dev *dev;
-	int i, j, err;
+	int i, err;
 
 	dev = input_allocate_device();
 	if (!dev) {
@@ -207,22 +233,8 @@ static int __init amikbd_probe(struct platform_device *pdev)
 	for (i = 0; i < 0x78; i++)
 		set_bit(i, dev->keybit);
 
-	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
-		static u_short temp_map[NR_KEYS] __initdata;
-		if (!key_maps[i])
-			continue;
-		memset(temp_map, 0, sizeof(temp_map));
-		for (j = 0; j < 0x78; j++) {
-			if (!amikbd_keycode[j])
-				continue;
-			temp_map[j] = key_maps[i][amikbd_keycode[j]];
-		}
-		for (j = 0; j < NR_KEYS; j++) {
-			if (!temp_map[j])
-				temp_map[j] = 0xf200;
-		}
-		memcpy(key_maps[i], temp_map, sizeof(temp_map));
-	}
+	amikbd_init_console_keymaps();
+
 	ciaa.cra &= ~0x41;	 /* serial data in, turn off TA */
 	err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd",
 			  dev);
-- 
1.9.1


^ permalink raw reply related

* Re: Aorus X3+ touchpad not working
From: Maximilien Levesque @ 2014-11-27 10:02 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Hans de Goede, Benjamin Tissoires, linux-input
In-Reply-To: <20141108203551.GA18000@dtor-glaptop>

Hi,
The bug is still present in 3.18rc6.
Many thanks,
Maximilien

On Sat, Nov 8, 2014 at 9:35 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Sat, Nov 08, 2014 at 11:12:34AM +0100, Hans de Goede wrote:
>> Hi,
>>
>> On 11/08/2014 09:41 AM, Dmitry Torokhov wrote:
>> > On Thu, Nov 06, 2014 at 03:51:48PM +0100, Hans de Goede wrote:
>> >> Hi,
>> >>
>> >> On 11/06/2014 03:13 PM, Maximilien Levesque wrote:
>> >>> Hi,
>> >>> Thanks for your time!
>> >>> Below is the output of dmesg with kernel boot parameter i8042.debug=1
>> >>> All the best,
>> >>
>> >> Thanks, I'm afraid reading raw i8042 is not my forte though, Dmitry, can
>> >> you take a look, and do you see why no ps/2 mouse (or touchpad) is seen ?
>> >
>> > ...
>> >
>> >>> [    1.901600] input: AT Translated Set 2 keyboard as
>> >>> /devices/platform/i8042/serio0/input/input4
>> >>> [    1.901749] i8042: [3] d4 -> i8042 (command)
>> >>> [    1.901809] i8042: [3] f2 -> i8042 (parameter)
>> >
>> > ...
>> > No ACK to GET_ID
>> >
>> >>> [    2.101556] i8042: [53] d4 -> i8042 (command)
>> >>> [    2.101622] i8042: [53] ed -> i8042 (parameter)
>> >
>> > Trying LEDs - no response - not a keyboard, atkbd signs out
>> >
>> >>> [    2.165646] usb 1-2: new low-speed USB device number 2 using xhci_hcd
>> >>> [    2.185660] usb 3-1: new high-speed USB device number 2 using ehci-pci
>> >>> [    2.205674] usb 4-1: new high-speed USB device number 2 using ehci-pci
>> >>> [    2.301725] i8042: [103] 60 -> i8042 (command)
>> >>> [    2.301796] i8042: [103] 45 -> i8042 (parameter)
>> >
>> > Close AUX port
>> >
>> >>> [    2.301911] i8042: [103] 60 -> i8042 (command)
>> >>> [    2.302025] i8042: [103] 47 -> i8042 (parameter)
>> >
>> > Enables AUX port again (to clear state - needed on some boxes)
>> >
>> >>> [    2.302094] i8042: [103] d4 -> i8042 (command)
>> >>> [    2.302212] i8042: [103] f2 -> i8042 (parameter)
>> >
>> > psmouse - GET_ID - silence. So we decide there is no mouse.
>>
>> Dmitry, thanks for the analysis.
>>
>> So if I understand things correctly, then the aux port also gets
>> probed for it having a second keyboard attached ?
>
> Basically every "free" serio port is tried by every serio driver, so, depending
> on link order and other factors psmouse driver can try both KBD and AUX port
> and atkbd can do the same.
>
>> I did not know
>> that, could it be that this confuses the touchpad?
>
> It should not as the first thing we try is GET_ID command which is the same for
> keyboard and mouse and we did not get any response.
>
>>
>> > Have we tried i8042.reset?
>>
>> No not yet. Maximilien, can you try booting with
>> i8042.reset=1 on the kernel commandline ?
>
> OK, so it looks like it did not work. I wonder if we could try resetting the
> mouse by sticking psmouse_reset before trying to isse the GETID command.
>
> Thanks.
>
> --
> Dmitry

^ permalink raw reply

* Re: [PATCH 2/2] Input: amikbd - Allocate temporary keymap buffer dynamically
From: Andreas Schwab @ 2014-11-27 11:17 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Dmitry Torokhov, linux-input, linux-m68k
In-Reply-To: <1417081340-2989-2-git-send-email-geert@linux-m68k.org>

Geert Uytterhoeven <geert@linux-m68k.org> writes:

> @@ -147,13 +148,18 @@ static unsigned char amikbd_keycode[0x78] __initdata = {
>  
>  static void __init amikbd_init_console_keymaps(void)
>  {
> +	unsigned short *temp_map;
> +	size_t temp_map_size = NR_KEYS * sizeof(*temp_map);
>  	int i, j;
>  
> +	temp_map = kmalloc(temp_map_size, GFP_KERNEL);
> +	if (!temp_map)
> +		return;
> +
>  	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
> -		static u_short temp_map[NR_KEYS] __initdata;
>  		if (!key_maps[i])
>  			continue;
> -		memset(temp_map, 0, sizeof(temp_map));
> +		memset(temp_map, 0, temp_map_size);
>  		for (j = 0; j < 0x78; j++) {
>  			if (!amikbd_keycode[j])
>  				continue;

How about allocating it on the stack?  With NR_KEYS == 256 that means
512 bytes, which should be ok, doesn't it?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH 1/3] HID: wacom: Consult the application usage when determining field type
From: Jiri Kosina @ 2014-11-27 13:45 UTC (permalink / raw)
  To: Jason Gerecke; +Cc: linux-input, benjamin.tissoires, pinglinux
In-Reply-To: <1416871934-14133-2-git-send-email-killertofu@gmail.com>

On Mon, 24 Nov 2014, Jason Gerecke wrote:

> It is not necessarily sufficient to look only at the physical and logical
> usages when determining if a field is for the pen or touch. Some fields
> are not contained in a sub-collection and thus only have an application
> usage. Not checking the application usage in such cases causes us to
> ignore the field entirely, which may lead to incorrect behavior.
> 
> Signed-off-by: Jason Gerecke <killertofu@gmail.com>

Applied.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* [PATCH] hid: export hid_report_len as an inline function in hid.h
From: Mathieu Magnaudet @ 2014-11-27 15:02 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires; +Cc: linux-input, linux-kernel

in several hid drivers it is necessary to calculate the length
of an hid_report. This patch exports the existing static function
hid_report_len of hid-core.c as an inline function in hid.h

Signed-off-by: Mathieu Magnaudet <mathieu.magnaudet@enac.fr>
---
 drivers/hid/hid-core.c        |  6 ------
 drivers/hid/hid-input.c       |  2 +-
 drivers/hid/hid-multitouch.c  |  2 +-
 drivers/hid/usbhid/hid-core.c |  3 +--
 drivers/hid/wacom_sys.c       |  8 +-------
 include/linux/hid.h           | 11 +++++++++++
 6 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0ad2ac0..c3d0ac1 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1282,12 +1282,6 @@ void hid_output_report(struct hid_report *report, __u8 *data)
 }
 EXPORT_SYMBOL_GPL(hid_output_report);
 
-static int hid_report_len(struct hid_report *report)
-{
-	/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
-	return ((report->size - 1) >> 3) + 1 + (report->id > 0);
-}
-
 /*
  * Allocator for buffer that is going to be passed to hid_output_report()
  */
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index be3eba8..e0a0f06 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1215,7 +1215,7 @@ static void hidinput_led_worker(struct work_struct *work)
 		return hid->ll_driver->request(hid, report, HID_REQ_SET_REPORT);
 
 	/* fall back to generic raw-output-report */
-	len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+	len = hid_report_len(report);
 	buf = hid_alloc_report_buf(report, GFP_KERNEL);
 	if (!buf)
 		return;
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 683cda6..f65e78b 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -827,7 +827,7 @@ static void mt_set_input_mode(struct hid_device *hdev)
 	r = re->report_id_hash[td->inputmode];
 	if (r) {
 		if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
-			report_len = ((r->size - 1) >> 3) + 1 + (r->id > 0);
+			report_len = hid_report_len(r);
 			buf = hid_alloc_report_buf(r, GFP_KERNEL);
 			if (!buf) {
 				hid_err(hdev, "failed to allocate buffer for report\n");
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 04e34b9..bfbe1be 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -340,8 +340,7 @@ static int hid_submit_out(struct hid_device *hid)
 	report = usbhid->out[usbhid->outtail].report;
 	raw_report = usbhid->out[usbhid->outtail].raw_report;
 
-	usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) +
-						 1 + (report->id > 0);
+	usbhid->urbout->transfer_buffer_length = hid_report_len(report);
 	usbhid->urbout->dev = hid_to_usb_dev(hid);
 	if (raw_report) {
 		memcpy(usbhid->outbuf, raw_report,
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index eb55316..358880b 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -1328,12 +1328,6 @@ static void wacom_calculate_res(struct wacom_features *features)
 						    features->unitExpo);
 }
 
-static int wacom_hid_report_len(struct hid_report *report)
-{
-	/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
-	return ((report->size - 1) >> 3) + 1 + (report->id > 0);
-}
-
 static size_t wacom_compute_pktlen(struct hid_device *hdev)
 {
 	struct hid_report_enum *report_enum;
@@ -1343,7 +1337,7 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev)
 	report_enum = hdev->report_enum + HID_INPUT_REPORT;
 
 	list_for_each_entry(report, &report_enum->report_list, list) {
-		size_t report_size = wacom_hid_report_len(report);
+		size_t report_size = hid_report_len(report);
 		if (report_size > size)
 			size = report_size;
 	}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d585d02..06c4607 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1087,6 +1087,17 @@ static inline void hid_hw_wait(struct hid_device *hdev)
 		hdev->ll_driver->wait(hdev);
 }
 
+/**
+ * hid_report_len - calculate the report length
+ *
+ * @report: the report we want to know the length
+ */
+static inline int hid_report_len(struct hid_report *report)
+{
+	/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
+	return ((report->size - 1) >> 3) + 1 + (report->id > 0);
+}
+
 int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
 		int interrupt);
 
-- 
1.9.3


^ permalink raw reply related

* Re: [PATCH 0/7] Fixes for ALPS trackstick
From: Dmitry Torokhov @ 2014-11-27 18:08 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Hans de Goede, Yunkang Tang, Vadim Klishko, linux-input,
	linux-kernel
In-Reply-To: <201411251208.31658@pali>

On November 25, 2014 3:08:31 AM PST, "Pali Rohár" <pali.rohar@gmail.com> wrote:
>On Thursday 20 November 2014 00:29:49 Pali Rohár wrote:
>> On Monday 17 November 2014 08:39:14 Pali Rohár wrote:
>> > On Friday 14 November 2014 21:59:31 Dmitry Torokhov wrote:
>> > > Hi Pali,
>> > > 
>> > > On Friday, November 14, 2014 08:38:19 PM Pali Rohár wrote:
>> > > > This patch series fix detection and identifying
>> > > > trackstick on machines with ALPS devices. Last patch
>> > > > split trackstick and bare PS/2 mouse packets between
>> > > > dev2 and dev3 input devices which make sure that driver
>> > > > will send only trackstick data to trackstick input
>> > > > device.
>> > > 
>> > > Thank you for splitting the change, unfortunately it is
>> > > now quite big to apply to 3.18. Any chance you could try
>> > > implementing what I suggested in
>> > > http://www.spinics.net/lists/linux-input/msg34029.html and
>> > > then we can do the more comprehensive solution in 3.19.
>> > > 
>> > > Thanks.
>> > 
>> > Hello, I think that patches 1/7 and 5/7 could do that job. I
>> > did not tested them alone (without other patches), but if
>> > you think that two patches are ok for 3.18 & stable I can
>> > test them...
>> 
>> Dmitry, ping.
>
>Dmitry: ping again.

Hi Pali,

I'm on vacation and unfortunately connection here is horrendous so I likely won't be able to do anything until after 12/03.

Sorry about that.


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

^ permalink raw reply

* Re: [git pull] Input updates for 3.18-rc4
From: ulrik.debie-os @ 2014-11-27 20:41 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Marcus Overhagen, Dmitry Torokhov, Hans de Goede,
	linux-kernel@vger.kernel.org, linux-input, Jiri Kosina
In-Reply-To: <CAN+gG=FkhofpNmpP6=3uBeywYRVceYViGoAG1Z5W6u1Bofm9tA@mail.gmail.com>

Hi Benjamin,

On Wed, Nov 26, 2014 at 09:33:26AM -0500, Benjamin Tissoires wrote:
> 
> Hi Ulrik,
> 
> On Tue, Nov 25, 2014 at 4:23 PM,  <ulrik.debie-os@e2big.org> wrote:
> > Hi,
> >
> > On Wed, Nov 19, 2014 at 11:21:31PM +0100, Marcus Overhagen wrote:
> >> Hi,
> >>
> >> when moving a single finger [3] seems to be one of 0x21, 0x25, 0x31, 0x35
> >> moving two fingers [3] seems to be mostly 0x22, 0x26, 0x32, 0x36  but
> >> also sometimes it's 0x42, 0x46, 0x52, 0x56.
> >> It seems to occationally seems to switch between these two groups
> >> after touching the pad with three or more fingers, but not every time.
> >>
> >> Moving three fingers I see[3] beeing  0x26, 0x36, 0x76, 0x66 (probably more)
> >>
> >> regards
> >> Marcus
> >
> >
> > Ok, after some digging through the packet dump kindly provided by Marcus,
> > it is clear that Documentation/input/elantech.txt is not correctly
> > representing anymore the packets of the v4 hardware. There should be some
> > 0 and 1's replaced by x because they are currently "don't know" and definitely
> > not always 0 or 1.
> >
> > Example:
> > He has 0x26,0x36,0x46,0x56,0x66,0x76 in packet[3], and the documentation had
> > the bits as:
> > id2 id1 id0   1   0   0   1   0
> >               X       X
> > The bits marked with X can thus be different. But when those are changed to
> > X==don't care then it is not trivial to differentiate them from the trackpoint
> > that has the following signature for that byte:
> > 0   0   ~sy  ~sx  0   1   1   0
> >
> >
> >
> > I'm considering the following change:
> > The test
> >
> >         t = get_unaligned_le32(&packet[0]);
> >
> >         switch (t & ~7U) {
> >         case 0x06000030U:
> >         case 0x16008020U:
> >         case 0x26800010U:
> >         case 0x36808000U:
> >
> > could be moved to elantech_packet_check_v3/4() instead of the
> > simpler test on the lowest nibble of packet[3] (and keep the etd->tp_dev check):
> >        if ((packet[3] & 0x0f) == 0x06 && etd->tp_dev)
> >                 return PACKET_TRACKPOINT;
> >
> > I'll think a little bit more on it. Based on the packet dump I have this
> > seems to allow a perfect discrimation between trackpoint and touchpad packets.
> >
> 
> Thanks for the progress on these. Do you think you will be able to get
> something in shape before the final 3.18?
> 
> Dmitry, can we either revert the current patches and reschedule them
> for 3.19 or at least apply one quick fix? I am starting to see a lot
> of people complaining about it, and I am wondering if adding this
> functionality in a -rc5 release was not a good idea :-/.

Dmitry has already requested Linus to pull the quick fix 
b54783f2de0c216115333eca1a8d3d5c3e75b 

I expect this fix from Dmitry to also help the person that you reported,
could you confirm that ? Basically when the hardware reports no trackpoint
present, it will then behave like before the trackpoint as enabled on v4.

I expect some responses from people soon in order to find out if there
is even a better way to fix it.

Thanks,
Kind regards,
Ulrik



> Cheers,
> Benjamin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCHv3 1/1] HID: add BETOP game controller force feedback support
From: Huang Bo @ 2014-11-28  1:20 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: linux-input, linux-kernel
In-Reply-To: <alpine.LNX.2.00.1411271004260.23174@pobox.suse.cz>

On 11/27/2014 05:05 PM, Jiri Kosina wrote:
> except ...
thanks firstly.
1. tested the BETOP2185 gamecontroller, it really not need it.
2. check with engineers of Betop, they design only one report descriptor.

so I modify it.



^ permalink raw reply

* RE: [BUG] [PATCH] next: cyapa: fix inop touchpad after resume on Acer C720
From: Dudley Du @ 2014-11-28  1:49 UTC (permalink / raw)
  To: Dmitry Torokhov, 'Jeremiah Mahler'; +Cc: linux-input@vger.kernel.org
In-Reply-To: <189CB621-DEBE-4C54-AE62-9441D50C7C55@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4102 bytes --]

Dmitry,

Yes, I remebered the discussion, and I said it was working.
At that time, I though it was the suggestion to my patches, so I merged the solution to my pathces,
and verified on my pathces. But did not run test on the patch you attached.
Sorry for the misunderstood and the troubles to you. :)

Regards,
Dudley

> -----Original Message-----
> From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> Sent: 2014年11月28日 2:16
> To: Dudley Du; 'Jeremiah Mahler'
> Cc: linux-kernel@vger.kernel.org; Dudley Du
> Subject: RE: [BUG] [PATCH] next: cyapa: fix inop touchpad after resume on Acer
> C720
>
> On November 26, 2014 9:45:49 PM PST, Dudley Du <dudley.dulixin@gmail.com>
> wrote:
> >Jeremiah,
> >
> >I didn't make the special patch for the linux-next before, so I don't
> >know why
> >this patch is there and have issue.
>
> That was the patch we've discussed some times back and you mentioned it was
> working for you so I applied it to next.
>
> I'll make sure to apply the fixup promptly.
>
> >Based on current code in the linux-next, I made below patch to fix this
> >issue.
> >Could you please try again with attached patch fix.
> >
> >Thanks,
> >Dudley
> >
> >> -----Original Message-----
> >> From: Jeremiah Mahler [mailto:jmmahler@gmail.com]
> >> Sent: 2014?11?27? 4:03
> >> To: Dudley Du
> >> Cc: linux-kernel@vger.kernel.org
> >> Subject: Re: [BUG] [PATCH] next: cyapa: fix inop touchpad after
> >resume on Acer
> >> C720
> >>
> >> Dudley,
> >>
> >> On Wed, Nov 26, 2014 at 06:16:00AM +0000, Dudley Du wrote:
> >> > More info: I did all testings based on kernel 3.14.0 on Acer C70.
> >> >
> >>
> >> I am testing with linux-next 3.18-rc6 on an Acer C720.
> >>
> >> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/
> >>
> >> > Thanks,
> >> > Dudley
> >> >
> >> []
> >>
> >> --
> >> - Jeremiah Mahler
> >
> >From bb717b1c1525ef6b889f0ef735d920eed9e76e72 Mon Sep 17 00:00:00 2001
> >From: Dudley Du <dudley.dulixin@gmail.com>
> >Date: Thu, 27 Nov 2014 13:35:09 +0800
> >Subject: [PATCH] input: cyapa: fix irq error issue in cyapa_resume
> >To: dmitry.torokhov@gmail.com,
> >    jmmahler@gmail.com
> >Cc: bleung@google.com,
> >    linux-input@vger.kernel.org
> >
> >This patch is aimed to fix the irq error happened on cyapa_resume when
> >doing suspend/resume testing.
> >The root cause of this issue is that the cyapa->irq has been removed
> >but
> >still used in the driver.
> >
> >Signed-off-by: Dudley Du <dudley.dulixin@gmail.com>
> >---
> > drivers/input/mouse/cyapa.c | 6 +++---
> > 1 file changed, 3 insertions(+), 3 deletions(-)
> >
> >diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
> >index c84a9eb..caaba7b 100644
> >--- a/drivers/input/mouse/cyapa.c
> >+++ b/drivers/input/mouse/cyapa.c
> >@@ -938,7 +938,7 @@ static int __maybe_unused cyapa_suspend(struct
> >device *dev)
> >  power_mode, error);
> >
> > if (device_may_wakeup(dev))
> >-cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0);
> >+cyapa->irq_wake = (enable_irq_wake(cyapa->client->irq) == 0);
> >
> > mutex_unlock(&input->mutex);
> >
> >@@ -956,7 +956,7 @@ static int __maybe_unused cyapa_resume(struct
> >device *dev)
> > mutex_lock(&input->mutex);
> >
> > if (device_may_wakeup(dev) && cyapa->irq_wake)
> >-disable_irq_wake(cyapa->irq);
> >+disable_irq_wake(cyapa->client->irq);
> >
> > power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF;
> > error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
> >@@ -964,7 +964,7 @@ static int __maybe_unused cyapa_resume(struct
> >device *dev)
> > dev_warn(dev, "resume: set power mode to %d failed: %d\n",
> >  power_mode, error);
> >
> >-enable_irq(cyapa->irq);
> >+enable_irq(cyapa->client->irq);
> >
> > mutex_unlock(&input->mutex);
> >
>
> Hi Dudley,
> Thanks.
>
> --
> Dmitry

This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 9011 bytes --]

^ permalink raw reply

* Re: [PATCH] Input: Initialize input_no by -1
From: Aniroop Mathur @ 2014-11-28 16:10 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input@vger.kernel.org, dtor
In-Reply-To: <1416931715-2902-1-git-send-email-aniroop.mathur@gmail.com>

Dear Mr. Torokhov and Linux Input Community,
Greetings of the day !!

Kindly update about below patch.
I have corrected the spaces and sent it on Tue, Nov 25, 2014.

Thanks,
Aniroop Mathur

On Tue, Nov 25, 2014 at 9:38 PM, Aniroop Mathur
<aniroop.mathur@gmail.com> wrote:
>
> This patch initializes input_no by -1 in order to avoid extra subtraction
> operation performed everytime for allocation of an input device.
>
> Signed-off-by: Aniroop Mathur <aniroop.mathur@gmail.com>
> ---
>  drivers/input/input.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 29ca0bb..01fe49e 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1774,7 +1774,7 @@ EXPORT_SYMBOL_GPL(input_class);
>   */
>  struct input_dev *input_allocate_device(void)
>  {
> -       static atomic_t input_no = ATOMIC_INIT(0);
> +       static atomic_t input_no = ATOMIC_INIT(-1);
>         struct input_dev *dev;
>
>         dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
> @@ -1789,7 +1789,7 @@ struct input_dev *input_allocate_device(void)
>                 INIT_LIST_HEAD(&dev->node);
>
>                 dev_set_name(&dev->dev, "input%ld",
> -                            (unsigned long) atomic_inc_return(&input_no) - 1);
> +                            (unsigned long) atomic_inc_return(&input_no));
>
>                 __module_get(THIS_MODULE);
>         }
> --
> 1.9.1
>

^ permalink raw reply

* [PATCH 1/1] HID: Wacom: Deletion of unnecessary checks before the function call "input_free_device"
From: SF Markus Elfring @ 2014-11-29 14:33 UTC (permalink / raw)
  To: Jiri Kosina, linux-input; +Cc: LKML, kernel-janitors, Coccinelle
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 29 Nov 2014 15:16:01 +0100

The input_free_device() function tests whether its argument is NULL and then
returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/hid/wacom_sys.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index eb55316..21ced00 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -1099,10 +1099,8 @@ static void wacom_free_inputs(struct wacom *wacom)
 {
 	struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
 
-	if (wacom_wac->input)
-		input_free_device(wacom_wac->input);
-	if (wacom_wac->pad_input)
-		input_free_device(wacom_wac->pad_input);
+	input_free_device(wacom_wac->input);
+	input_free_device(wacom_wac->pad_input);
 	wacom_wac->input = NULL;
 	wacom_wac->pad_input = NULL;
 }
-- 
2.1.3


^ permalink raw reply related

* [PATCH] Drivers:input:mousedev.c: Fixed trailing statement on the next line
From: Athira S @ 2014-11-29 15:39 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Athira S

Fixed checkpatch error:
trailing statements should be on next line

Signed-off-by: Athira S <athirasnamby@gmail.com>
---
 drivers/input/mousedev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index b604564..be2cc5c 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -248,7 +248,8 @@ static void mousedev_key_event(struct mousedev *mousedev,
 	case BTN_4:
 	case BTN_EXTRA:		index = 4; break;
 
-	default:		return;
+	default:
+	return;
 	}
 
 	if (value) {
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH] Drivers:input:mousedev.c: Fixed trailing statement on the next line
From: Belisko Marek @ 2014-11-29 16:02 UTC (permalink / raw)
  To: Athira S; +Cc: Dmitry Torokhov, linux-input, LKML
In-Reply-To: <1417275548-3431-1-git-send-email-athirasnamby@gmail.com>

On Sat, Nov 29, 2014 at 4:39 PM, Athira S <athirasnamby@gmail.com> wrote:
> Fixed checkpatch error:
> trailing statements should be on next line
>
> Signed-off-by: Athira S <athirasnamby@gmail.com>
> ---
>  drivers/input/mousedev.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
> index b604564..be2cc5c 100644
> --- a/drivers/input/mousedev.c
> +++ b/drivers/input/mousedev.c
> @@ -248,7 +248,8 @@ static void mousedev_key_event(struct mousedev *mousedev,
>         case BTN_4:
>         case BTN_EXTRA:         index = 4; break;
>
> -       default:                return;
> +       default:
> +       return;
           ^^^^ missing tab here
>         }
>
>         if (value) {
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

BR,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
twitter: #opennandra
web: http://open-nandra.com

^ permalink raw reply

* [PATCH] Drivers:input:mousedev.c: Fixed trailing statement on the next line
From: Athira S @ 2014-11-29 16:20 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Athira S

Fixed checkpatch error:
trailing statements should be on next line

signed-off-by: Athira S <athirasnamby@gmail.com>
---
 drivers/input/mousedev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index be2cc5c..28988f5 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -248,8 +248,8 @@ static void mousedev_key_event(struct mousedev *mousedev,
 	case BTN_4:
 	case BTN_EXTRA:		index = 4; break;
 
-	default:
-	return;
+	default:	
+				return;
 	}
 
 	if (value) {
-- 
1.9.1

^ permalink raw reply related

* Disable input device
From: Pali Rohár @ 2014-11-29 17:24 UTC (permalink / raw)
  To: Dmitry Torokhov, Sebastian Reichel, Pavel Machek, kernel list,
	linux-input, Henrik Rydberg

[-- Attachment #1: Type: Text/Plain, Size: 1089 bytes --]

Hello,

there is request to introduce some option (via sysfs) to disable 
one input device. Originally it was for tsc2005 touchscreen found 
on Nokia N900 cellphone. Use case is to completely disable 
touchscreen when phone is in pocket or when screen is locked via 
slide switch (to prevent random clicks).

But it would be better to have disable option for all input 
devices. Sometimes input device is not use and only consume 
power. Another case is when input device (e.g. keyboard or 
touchpad) is integrated into machine (e.g. on laptops) and user 
does not want to use it (so make sure that kernel does not send 
events to userspace).

I would like to ask, how to solve it?

What do you think about adding new sysfs file "disable" (accept 
values 1 or 0) for every input device? With "1" it cause that 
kernel will drop all events from specific input device and if 
driver provide some function is can be called (e.g. for power 
management or disabling device at hardware level).

Or do you prefer something other?

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH] Drivers:input:mousedev.c: Fixed trailing statement on the next line
From: Joe Perches @ 2014-11-29 17:54 UTC (permalink / raw)
  To: Athira S; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <1417278043-4870-1-git-send-email-athirasnamby@gmail.com>

On Sat, 2014-11-29 at 21:50 +0530, Athira S wrote:
> Fixed checkpatch error:
> trailing statements should be on next line
> 
> signed-off-by: Athira S <athirasnamby@gmail.com>
> ---
>  drivers/input/mousedev.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
> index be2cc5c..28988f5 100644
> --- a/drivers/input/mousedev.c
> +++ b/drivers/input/mousedev.c
> @@ -248,8 +248,8 @@ static void mousedev_key_event(struct mousedev *mousedev,
>  	case BTN_4:
>  	case BTN_EXTRA:		index = 4; break;
>  
> -	default:
> -	return;
> +	default:	
> +				return;

Please run your suggested patches though
scripts/checkpatch.pl before sending them.

Don't send patches on top of your own
unapplied patches.  Use the original and
create a new patch.

Probably none of this needs to be changed.



^ permalink raw reply

* [PATCH v2 1/2] Input: amikbd - Fix build if !CONFIG_HW_CONSOLE
From: Geert Uytterhoeven @ 2014-11-30  9:30 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, linux-m68k, Geert Uytterhoeven

If CONFIG_HW_CONSOLE is not set:

drivers/built-in.o: In function `amikbd_probe':
amikbd.c:(.init.text+0x3e4e): undefined reference to `key_maps'
amikbd.c:(.init.text+0x3dd4): undefined reference to `key_maps'

To fix this, extract the initialization of the console keyboard maps
into amikbd_init_console_keymaps(), protected by #ifdef
CONFIG_HW_CONSOLE.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
Discovered during randconfig builds.

v2:
  - No changes
---
 drivers/input/keyboard/amikbd.c | 46 ++++++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 096d6067ae1f890f..4f81e65d9e35cb7d 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -45,6 +45,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Amiga keyboard driver");
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_HW_CONSOLE
 static unsigned char amikbd_keycode[0x78] __initdata = {
 	[0]	 = KEY_GRAVE,
 	[1]	 = KEY_1,
@@ -144,6 +145,31 @@ static unsigned char amikbd_keycode[0x78] __initdata = {
 	[103]	 = KEY_RIGHTMETA
 };
 
+static void __init amikbd_init_console_keymaps(void)
+{
+	int i, j;
+
+	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
+		static u_short temp_map[NR_KEYS] __initdata;
+		if (!key_maps[i])
+			continue;
+		memset(temp_map, 0, sizeof(temp_map));
+		for (j = 0; j < 0x78; j++) {
+			if (!amikbd_keycode[j])
+				continue;
+			temp_map[j] = key_maps[i][amikbd_keycode[j]];
+		}
+		for (j = 0; j < NR_KEYS; j++) {
+			if (!temp_map[j])
+				temp_map[j] = 0xf200;
+		}
+		memcpy(key_maps[i], temp_map, sizeof(temp_map));
+	}
+}
+#else /* !CONFIG_HW_CONSOLE */
+static inline void amikbd_init_console_keymaps(void) {}
+#endif /* !CONFIG_HW_CONSOLE */
+
 static const char *amikbd_messages[8] = {
 	[0] = KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n",
 	[1] = KERN_WARNING "amikbd: keyboard lost sync\n",
@@ -186,7 +212,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *data)
 static int __init amikbd_probe(struct platform_device *pdev)
 {
 	struct input_dev *dev;
-	int i, j, err;
+	int i, err;
 
 	dev = input_allocate_device();
 	if (!dev) {
@@ -207,22 +233,8 @@ static int __init amikbd_probe(struct platform_device *pdev)
 	for (i = 0; i < 0x78; i++)
 		set_bit(i, dev->keybit);
 
-	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
-		static u_short temp_map[NR_KEYS] __initdata;
-		if (!key_maps[i])
-			continue;
-		memset(temp_map, 0, sizeof(temp_map));
-		for (j = 0; j < 0x78; j++) {
-			if (!amikbd_keycode[j])
-				continue;
-			temp_map[j] = key_maps[i][amikbd_keycode[j]];
-		}
-		for (j = 0; j < NR_KEYS; j++) {
-			if (!temp_map[j])
-				temp_map[j] = 0xf200;
-		}
-		memcpy(key_maps[i], temp_map, sizeof(temp_map));
-	}
+	amikbd_init_console_keymaps();
+
 	ciaa.cra &= ~0x41;	 /* serial data in, turn off TA */
 	err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd",
 			  dev);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 2/2] Input: amikbd - Allocate temporary keymap buffer on the stack
From: Geert Uytterhoeven @ 2014-11-30  9:30 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, linux-m68k, Geert Uytterhoeven
In-Reply-To: <1417339820-5285-1-git-send-email-geert@linux-m68k.org>

Allocate the temporary buffer needed for initialization of the console
keyboard maps (512 bytes, as NR_KEYS = 256) on the stack instead of
statically, to reduce kernel size.

add/remove: 0/1 grow/shrink: 0/0 up/down: 0/-512 (-512)
function                                     old     new   delta
temp_map                                     512       -    -512

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v2:
  - Allocate temp_map[] on the stack instead of using kmalloc().
---
 drivers/input/keyboard/amikbd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 4f81e65d9e35cb7d..60580d8104b9f970 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -147,10 +147,10 @@ static unsigned char amikbd_keycode[0x78] __initdata = {
 
 static void __init amikbd_init_console_keymaps(void)
 {
+	unsigned short temp_map[NR_KEYS];
 	int i, j;
 
 	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
-		static u_short temp_map[NR_KEYS] __initdata;
 		if (!key_maps[i])
 			continue;
 		memset(temp_map, 0, sizeof(temp_map));
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH 1/2] Input: add regulator haptic driver
From: Jaewon Kim @ 2014-12-01  1:30 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kukjin Kim, Dmitry Torokhov, Chanwoo Choi, linux-kernel,
	linux-input, linux-samsung-soc, Hyunhee Kim
In-Reply-To: <20141128125051.GA3643@sirena.org.uk>

Hi Mark,

2014년 11월 28일 21:50에 Mark Brown 이(가) 쓴 글:
> On Thu, Nov 20, 2014 at 10:31:39PM +0900, Jaewon Kim wrote:
>
>> +	haptic->regulator = devm_regulator_get(&pdev->dev, "haptic");
>> +	if (IS_ERR(haptic->regulator)) {
>> +		dev_err(&pdev->dev, "failed to get regulator\n");
>> +		return PTR_ERR(haptic->regulator);
>> +	}
> This needs to be _get_exclusive() - the driver will be broken if
> something else shares the regualtor since it relies on both enabling and
> disabling the regulator and on setting the voltage for effects.  It's
> not like a power supply where leaving the device powered when it could
> be off is going to have no effect, if the power is left on then the
> haptic motor will continue to operate.

Thanks to review my patch.

Haptic regulator has to only be used in this driver.
So, it is right to change like your advice.
I will fix next version.

Thanks
Jaewon Kim.

^ permalink raw reply

* [PATCH v4 0/2] Add regulator-haptic driver
From: Jaewon Kim @ 2014-12-01  2:11 UTC (permalink / raw)
  To: Dmitry Torokhov, Kukjin Kim
  Cc: linux-kernel, linux-samsung-soc, linux-input, Jaewon Kim

This patch series adds regulator-haptic driver.
The regulator-haptic has haptic motor and it is controlled by
voltage of regulator via force feedback framework.

Changes in v4:
 - _regulator_get() -> _regulator_get_exclusive()

Changes in v3:
 - fix typo in Documentation
 - add define in header file

Changes in v2:
 - remove driver owner
 - merge enable/disable function
 - support platform data
 - fix wrong suspends_state check in regulator_haptic_resume()


Jaewon Kim (2):
  Input: add regulator haptic driver
  ARM: dts: Add regulator-haptic device node for exynos3250-rinato

 .../devicetree/bindings/input/regulator-haptic.txt |   21 ++
 arch/arm/boot/dts/exynos3250-rinato.dts            |    7 +
 drivers/input/misc/Kconfig                         |   11 +
 drivers/input/misc/Makefile                        |    1 +
 drivers/input/misc/regulator-haptic.c              |  247 ++++++++++++++++++++
 include/linux/input/regulator-haptic.h             |   31 +++
 6 files changed, 318 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/regulator-haptic.txt
 create mode 100644 drivers/input/misc/regulator-haptic.c
 create mode 100644 include/linux/input/regulator-haptic.h

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v4 1/2] Input: add regulator haptic driver
From: Jaewon Kim @ 2014-12-01  2:11 UTC (permalink / raw)
  To: Dmitry Torokhov, Kukjin Kim
  Cc: linux-kernel, linux-samsung-soc, linux-input, Jaewon Kim,
	Hyunhee Kim
In-Reply-To: <1417399873-19575-1-git-send-email-jaewon02.kim@samsung.com>

This patch adds support for haptic driver controlled by
voltage of regulator. And this driver support for
Force Feedback interface from input framework

Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
Signed-off-by: Hyunhee Kim <hyunhee.kim@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 .../devicetree/bindings/input/regulator-haptic.txt |   21 ++
 drivers/input/misc/Kconfig                         |   11 +
 drivers/input/misc/Makefile                        |    1 +
 drivers/input/misc/regulator-haptic.c              |  247 ++++++++++++++++++++
 include/linux/input/regulator-haptic.h             |   31 +++
 5 files changed, 311 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/regulator-haptic.txt
 create mode 100644 drivers/input/misc/regulator-haptic.c
 create mode 100644 include/linux/input/regulator-haptic.h

diff --git a/Documentation/devicetree/bindings/input/regulator-haptic.txt b/Documentation/devicetree/bindings/input/regulator-haptic.txt
new file mode 100644
index 0000000..3ed1c7e
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/regulator-haptic.txt
@@ -0,0 +1,21 @@
+* Regulator Haptic Device Tree Bindings
+
+Required Properties:
+ - compatible : Should be "regulator-haptic"
+ - haptic-supply : Power supply to the haptic motor.
+	[*] refer Documentation/devicetree/bindings/regulator/regulator.txt
+
+ - max-microvolt : The maximum voltage value supplied to the haptic motor.
+		[The unit of the voltage is a micro]
+
+ - min-microvolt : The minimum voltage value supplied to the haptic motor.
+		[The unit of the voltage is a micro]
+
+Example:
+
+	haptics {
+		compatible = "regulator-haptic";
+		haptic-supply = <&motor_regulator>;
+		max-microvolt = <2700000>;
+		min-microvolt = <1100000>;
+	};
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 23297ab..e5e556d 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -394,6 +394,17 @@ config INPUT_CM109
 	  To compile this driver as a module, choose M here: the module will be
 	  called cm109.
 
+config INPUT_REGULATOR_HAPTIC
+	tristate "regulator haptics support"
+	select INPUT_FF_MEMLESS
+	help
+	  This option enables device driver support for the haptic controlled
+	  by regulator. This driver supports ff-memless interface
+	  from input framework.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called regulator-haptic.
+
 config INPUT_RETU_PWRBUTTON
 	tristate "Retu Power button Driver"
 	depends on MFD_RETU
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 19c7603..1f135af 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY)	+= pmic8xxx-pwrkey.o
 obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
+obj-$(CONFIG_INPUT_REGULATOR_HAPTIC)	+= regulator-haptic.o
 obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
diff --git a/drivers/input/misc/regulator-haptic.c b/drivers/input/misc/regulator-haptic.c
new file mode 100644
index 0000000..6bc8e45
--- /dev/null
+++ b/drivers/input/misc/regulator-haptic.c
@@ -0,0 +1,247 @@
+/*
+ * Regulator haptic driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Jaewon Kim <jaewon02.kim@samsung.com>
+ * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+#include <linux/input/regulator-haptic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#define MAX_MAGNITUDE_SHIFT	16
+
+struct regulator_haptic {
+	struct device *dev;
+	struct input_dev *input_dev;
+	struct regulator *regulator;
+	struct work_struct work;
+
+	bool enabled;
+	bool suspend_state;
+	unsigned int max_volt;
+	unsigned int min_volt;
+	unsigned int intensity;
+	unsigned int magnitude;
+};
+
+static void regulator_haptic_enable(struct regulator_haptic *haptic, bool state)
+{
+	int error;
+
+	if (haptic->enabled == state)
+		return;
+
+	if (state)
+		error = regulator_enable(haptic->regulator);
+	else
+		error = regulator_disable(haptic->regulator);
+	if (error) {
+		dev_err(haptic->dev, "cannot enable regulator\n");
+		return;
+	}
+
+	haptic->enabled = state;
+}
+
+static void regulator_haptic_work(struct work_struct *work)
+{
+	struct regulator_haptic *haptic = container_of(work,
+					struct regulator_haptic, work);
+	int error;
+
+	error = regulator_set_voltage(haptic->regulator,
+			haptic->intensity + haptic->min_volt, haptic->max_volt);
+	if (error) {
+		dev_err(haptic->dev, "cannot set regulator voltage\n");
+		return;
+	}
+
+	if (haptic->magnitude)
+		regulator_haptic_enable(haptic, true);
+	else
+		regulator_haptic_enable(haptic, false);
+}
+
+static int regulator_haptic_play_effect(struct input_dev *input, void *data,
+					struct ff_effect *effect)
+{
+	struct regulator_haptic *haptic = input_get_drvdata(input);
+	u64 volt_mag_multi;
+
+	haptic->magnitude = effect->u.rumble.strong_magnitude;
+	if (!haptic->magnitude)
+		haptic->magnitude = effect->u.rumble.weak_magnitude;
+
+
+	volt_mag_multi = (u64)(haptic->max_volt - haptic->min_volt) *
+					haptic->magnitude;
+	haptic->intensity = (unsigned int)(volt_mag_multi >>
+					MAX_MAGNITUDE_SHIFT);
+
+	schedule_work(&haptic->work);
+
+	return 0;
+}
+
+static void regulator_haptic_close(struct input_dev *input)
+{
+	struct regulator_haptic *haptic = input_get_drvdata(input);
+
+	cancel_work_sync(&haptic->work);
+	regulator_haptic_enable(haptic, false);
+}
+
+#ifdef CONFIG_OF
+static int regulator_haptic_parse_dt(struct regulator_haptic *haptic)
+{
+	struct device_node *node = haptic->dev->of_node;
+	int error;
+
+	error = of_property_read_u32(node, "max-microvolt", &haptic->max_volt);
+	if (error) {
+		dev_err(haptic->dev, "cannot parse max-microvolt\n");
+		return error;
+	}
+
+	error = of_property_read_u32(node, "min-microvolt", &haptic->min_volt);
+	if (error) {
+		dev_err(haptic->dev, "cannot parse min-microvolt\n");
+		return error;
+	}
+
+	return 0;
+}
+#else
+static int regulator_haptic_parse_dt(struct regulator_haptic *haptic)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
+static int regulator_haptic_probe(struct platform_device *pdev)
+{
+	struct regulator_haptic *haptic;
+	struct regulator_haptic_data *data;
+	struct input_dev *input_dev;
+	int error;
+
+	haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL);
+	if (!haptic)
+		return -ENOMEM;
+
+	haptic->dev = &pdev->dev;
+	haptic->enabled = false;
+	haptic->suspend_state = false;
+	INIT_WORK(&haptic->work, regulator_haptic_work);
+
+	if (pdev->dev.of_node) {
+		error = regulator_haptic_parse_dt(haptic);
+		if (error) {
+			dev_err(&pdev->dev, "failed to parse device tree\n");
+			return error;
+		}
+	} else {
+		data = dev_get_platdata(&pdev->dev);
+		if (data) {
+			dev_err(&pdev->dev, "failed to get platdata\n");
+			return -EINVAL;
+		}
+
+		haptic->regulator = data->regulator;
+		haptic->max_volt = data->max_volt;
+		haptic->min_volt = data->min_volt;
+	}
+
+	haptic->regulator = devm_regulator_get_exclusive(&pdev->dev, "haptic");
+	if (IS_ERR(haptic->regulator)) {
+		dev_err(&pdev->dev, "failed to get regulator\n");
+		return PTR_ERR(haptic->regulator);
+	}
+
+	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return  -ENOMEM;
+
+	haptic->input_dev = input_dev;
+	haptic->input_dev->name = "regulator-haptic";
+	haptic->input_dev->dev.parent = &pdev->dev;
+	haptic->input_dev->close = regulator_haptic_close;
+	input_set_drvdata(haptic->input_dev, haptic);
+	input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);
+
+	error = input_ff_create_memless(input_dev, NULL,
+			      regulator_haptic_play_effect);
+	if (error) {
+		dev_err(&pdev->dev, "failed to create force-feedback\n");
+		return error;
+	}
+
+	error = input_register_device(haptic->input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		return error;
+	}
+
+	platform_set_drvdata(pdev, haptic);
+
+	return 0;
+}
+
+static int __maybe_unused regulator_haptic_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct regulator_haptic *haptic = platform_get_drvdata(pdev);
+
+	if (haptic->enabled) {
+		regulator_haptic_enable(haptic, false);
+		haptic->suspend_state = true;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused regulator_haptic_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct regulator_haptic *haptic = platform_get_drvdata(pdev);
+
+	if (haptic->suspend_state) {
+		regulator_haptic_enable(haptic, true);
+		haptic->suspend_state = false;
+	}
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(regulator_haptic_pm_ops,
+		regulator_haptic_suspend, regulator_haptic_resume);
+
+static struct of_device_id regulator_haptic_dt_match[] = {
+	{ .compatible = "regulator-haptic" },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver regulator_haptic_driver = {
+	.probe		= regulator_haptic_probe,
+	.driver		= {
+		.name		= "regulator-haptic",
+		.of_match_table = regulator_haptic_dt_match,
+		.pm		= &regulator_haptic_pm_ops,
+	},
+};
+module_platform_driver(regulator_haptic_driver);
+
+MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
+MODULE_AUTHOR("Hyunhee Kim <hyunhee.kim@samsung.com>");
+MODULE_DESCRIPTION("Regulator haptic driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/input/regulator-haptic.h b/include/linux/input/regulator-haptic.h
new file mode 100644
index 0000000..05ae038
--- /dev/null
+++ b/include/linux/input/regulator-haptic.h
@@ -0,0 +1,31 @@
+/*
+ * Regulator Haptic Platform Data
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Jaewon Kim <jaewon02.kim@samsung.com>
+ * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _REGULATOR_HAPTIC_H
+#define _REGULATOR_HAPTIC_H
+
+/*
+ * struct regulator_haptic_data - Platform device data
+ *
+ * @regulator: Power supply to the haptic motor
+ * @max_volt: maximum voltage value supplied to the haptic motor.
+ * 		<The unit of the voltage is a micro>
+ * @min_volt: minimum voltage value supplied to the haptic motor.
+ * 		<The unit of the voltage is a micro>
+ */
+struct regulator_haptic_data {
+	struct regulator *regulator;
+	unsigned int max_volt;
+	unsigned int min_volt;
+};
+
+#endif /* _REGULATOR_HAPTIC_H */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 2/2] ARM: dts: Add regulator-haptic device node for exynos3250-rinato
From: Jaewon Kim @ 2014-12-01  2:11 UTC (permalink / raw)
  To: Dmitry Torokhov, Kukjin Kim
  Cc: linux-kernel, linux-samsung-soc, linux-input, Jaewon Kim
In-Reply-To: <1417399873-19575-1-git-send-email-jaewon02.kim@samsung.com>

This patch adds regulator-haptic device node controlled by regulator.

Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 arch/arm/boot/dts/exynos3250-rinato.dts |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 84380fa..da03005 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -104,6 +104,13 @@
 			};
 		};
 	};
+
+	haptics {
+		compatible = "regulator-haptic";
+		haptic-supply = <&motor_reg>;
+		min-microvolt = <1100000>;
+		max-microvolt = <2700000>;
+	};
 };
 
 &adc {
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH v4 0/6] Touchscreen performance related fixes
From: Vignesh R @ 2014-12-01  9:53 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Benoit Cousson, Tony Lindgren, Russell King, Jonathan Cameron,
	Hartmut Knaack, richardcochran-Re5JQEeQqe8AvxtiuMwx3w,
	Dmitry Torokhov, Lee Jones, Lars-Peter Clausen, Peter Meerwald,
	Samuel Ortiz, Felipe Balbi, Brad Griffis, Sanjeev Sharma,
	Paul Gortmaker, Jan Kardell, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20141124115116.GA14997-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>

Hi Sebastian,

On Monday 24 November 2014 05:21 PM, Sebastian Andrzej Siewior wrote:
> * Vignesh R | 2014-11-14 10:37:25 [+0530]:
> 
>> This series of patches fix TSC defects related to lag in touchscreen
>> performance and cursor jump at touch release. The lag was result of
>> udelay in TSC interrupt handler. Cursor jump due to false pen-up event.
>> The patches implement Advisory 1.0.31 in silicon errata of am335x-evm
> am335x not -evm. The am335x-evm is a board (with its own advisory
> document) built around the SoC.
> 
> Just testing the v4. I can use now IIO and touchscren at the same time.
> back at v1 I reported that it does not work, this has been fixed now.
> I had it running for a few minutes, now I see one of WARN_ON() beeing
> triggered (I've cut a few numbers so don't wonder about PID 2 and so on):
> 

I fixed the issue that was triggering the WARN_ON(). I think it would be
better if you tested these patches, before I posted them on the
mainline. I don't want to clutter the list with too main versions. Here
is the link to the tree with latest changes:

git clone -b tsc-devel git://git.ti.com/kernel/tsc-adc.git
(tsc-devel branch)

Please test the above tree and let me know the results.
I will post new version(v5) if there are no issues wrt IIO and TSC
working at the same time.

The cursor jump at touch release has been fixed. But I do see random
cursor movement when dragging on the screen. This is not due to false
pen-up events. My patches do not aim at fixing them. (the aim is to
remove udelay in irq handler and fix false pen-ups).
With these changes, false pen-ups have been eliminated and there is a
significant improvement in the performance of TSC. I feel these patches
can go in, if there are no other serious issues.

I will work on random cursor jump in a separate patch series.

Regards
Vignesh

^ permalink raw reply

* Re: [PATCH v4 0/6] Touchscreen performance related fixes
From: Sebastian Andrzej Siewior @ 2014-12-01  9:59 UTC (permalink / raw)
  To: Vignesh R
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Benoit Cousson, Tony Lindgren, Russell King, Jonathan Cameron,
	Hartmut Knaack, richardcochran-Re5JQEeQqe8AvxtiuMwx3w,
	Dmitry Torokhov, Lee Jones, Lars-Peter Clausen, Peter Meerwald,
	Samuel Ortiz, Felipe Balbi, Brad Griffis, Sanjeev Sharma,
	Paul Gortmaker, Jan Kardell, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, linux-arm-kerne
In-Reply-To: <547C3A95.30605-l0cyMroinI0@public.gmane.org>

On 12/01/2014 10:53 AM, Vignesh R wrote:
> Hi Sebastian,

Hi Vignesh,

> I fixed the issue that was triggering the WARN_ON(). I think it would be
> better if you tested these patches, before I posted them on the
> mainline. I don't want to clutter the list with too main versions. Here
> is the link to the tree with latest changes:

awesome, thank you.

> 
> git clone -b tsc-devel git://git.ti.com/kernel/tsc-adc.git
> (tsc-devel branch)

I will and let you know.

> Please test the above tree and let me know the results.
> I will post new version(v5) if there are no issues wrt IIO and TSC
> working at the same time.

Cool. Were you able to get in touch with someone who has a 5-wire touch?

> Regards
> Vignesh
> 

Sebastian

^ permalink raw reply

* [PATCH] driver: input: touchscreen: add Raydium i2c touchscreen driver
From: jeffrey.lin @ 2014-12-01 10:17 UTC (permalink / raw)
  To: dmitry.torokhov, rydberg, shc_work, bleung, lee.jones,
	charliemooney
  Cc: KP.li, linux-kernel, linux-input, jeffrey.lin

From: "jeffrey.lin" <jeffrey.lin@rad-ic.com>

This patch is porting Raydium I2C touch driver. Developer can enable
raydium touch driver by modifying define "CONFIG_TOUCHSCREEN_RM_TS".

Change-Id: I5f33cfdf0e895de6e7d535c11dd4b3ce8b49fa48
Signed-off-by: jeffrey.lin@rad-ic.com
---
 drivers/input/touchscreen/Kconfig      |  12 +
 drivers/input/touchscreen/Makefile     |   1 +
 drivers/input/touchscreen/rm31100_ts.c | 968 +++++++++++++++++++++++++++++++++
 include/linux/input/rm31100_ts.h       |  60 ++
 4 files changed, 1041 insertions(+)
 create mode 100644 drivers/input/touchscreen/rm31100_ts.c
 create mode 100644 include/linux/input/rm31100_ts.h

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 3ce9181..d0324d2 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -955,4 +955,16 @@ config TOUCHSCREEN_ZFORCE
 	  To compile this driver as a module, choose M here: the
 	  module will be called zforce_ts.
 
+config TOUCHSCREEN_RM_TS
+	tristate "Raydium I2C Touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have Raydium series I2C touchscreen,
+	  such as RM31100 , connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rm31100_ts.
+
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 687d5a7..aae4af2 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -78,3 +78,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
 obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
+obj-$(CONFIG_TOUCHSCREEN_RM_TS)	+= rm31100_ts.o
diff --git a/drivers/input/touchscreen/rm31100_ts.c b/drivers/input/touchscreen/rm31100_ts.c
new file mode 100644
index 0000000..6cb09a4
--- /dev/null
+++ b/drivers/input/touchscreen/rm31100_ts.c
@@ -0,0 +1,968 @@
+/* Source for:
+ * Raydium rm31100_ts Prototype touchscreen driver.
+ * drivers/input/touchscreen/rm31100_ts.c
+ *
+ * Copyright (C) 2012,
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * 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.
+ *
+ * Raydium reserves the right to make changes without further notice
+ * to the materials described herein. Raydium does not assume any
+ * liability arising out of the application described herein.
+ *
+ * Contact Raydium Semiconductor Corporation at www.rad-ic.com
+ *
+ * History:
+ *			(C) 2012 Raydium - Update for GPL distribution
+ *			(C) 2009 Enea - Original prototype
+ *
+ */
+#include <linux/async.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/input/rm31100_ts.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+/*#include <plat/gpio-cfg.h>*/
+#ifdef CONFIG_MISC_DEV
+#include <linux/miscdevice.h>
+#endif
+/*#include <asm/uaccess.h> copy_to_user() */
+#include <linux/uaccess.h>
+
+#define rm31100	0x0
+#define rm3110x	0x1
+
+#define INVALID_DATA	0xff
+#define MAX_REPORT_TOUCHED_POINTS	10
+
+#define TOUCHSCREEN_TIMEOUT	(msecs_to_jiffies(10))
+#define INITIAL_DELAY		(msecs_to_jiffies(25000))
+
+#define EVAL_REPORT_RATE    1
+
+#define I2C_CLIENT_ADDR         0x39
+#define I2C_DMA_CLIENT_ADDR     0x5A
+#undef CONFIG_PM
+struct rm31100_ts_data {
+	u8 x_index;
+	u8 y_index;
+	u8 z_index;
+	u8 id_index;
+	u8 touch_index;
+	u8 data_reg;
+	u8 status_reg;
+	u8 data_size;
+	u8 touch_bytes;
+	u8 update_data;
+	u8 touch_meta_data;
+	u8 finger_size;
+};
+
+static struct rm31100_ts_data devices[] = {
+	[0] = {
+		.x_index = 2,
+		.y_index = 4,
+		.z_index = 6,
+		.id_index = 1,
+		.data_reg = 0x1,
+		.status_reg = 0,
+		.update_data = 0x0,/*0x4*/
+		.touch_bytes = 6,
+		.touch_meta_data = 1,
+		.finger_size = 70,
+	},
+};
+
+struct rm31100_ts {
+	struct i2c_client *client;
+	struct input_dev *input;
+	struct delayed_work work;
+	struct rm3110x_ts_platform_data *pdata;
+	struct rm31100_ts_data *dd;
+	u8 *touch_data;
+	u8 device_id;
+	u8 prev_touches;
+	bool is_suspended;
+	bool int_pending;
+	struct mutex sus_lock;
+	struct mutex access_lock;
+	u32 pen_irq;
+};
+
+struct rm31100_ts *pts;
+/*
+static inline u16 join_bytes(u8 a, u8 b)
+{
+	u16 ab = 0;
+	ab = ab | a;
+	ab = ab << 8 | b;
+	return ab;
+}
+*/
+static s32 rm31100_ts_write_reg_u8(struct i2c_client *client, u8 reg, u8 val)
+{
+	s32 data;
+
+	data = i2c_smbus_write_byte_data(client, reg, val);
+	if (data < 0)
+		dev_err(&client->dev, "error %d in writing reg 0x%x\n",
+						 data, reg);
+
+	return data;
+}
+
+static s32 rm31100_ts_read_reg_u8(struct i2c_client *client, u8 reg)
+{
+	s32 data;
+
+	data = i2c_smbus_read_byte_data(client, reg);
+	if (data < 0)
+		dev_err(&client->dev, "error %d in reading reg 0x%x\n",
+						 data, reg);
+
+	return data;
+}
+
+static int rm31100_ts_read(struct i2c_client *client, u8 reg, u8 *buf, int num)
+{
+	struct i2c_msg xfer_msg[2];
+
+	xfer_msg[0].addr = client->addr;
+	xfer_msg[0].len = 1;
+	xfer_msg[0].flags = 0;
+	xfer_msg[0].buf = &reg;
+
+	xfer_msg[1].addr = client->addr;
+	xfer_msg[1].len = num;
+	xfer_msg[1].flags = I2C_M_RD;
+	xfer_msg[1].buf = buf;
+
+	return i2c_transfer(client->adapter, xfer_msg, 2);
+}
+
+static int rm31100_ts_write(struct i2c_client *client, u8 *buf, int num)
+{
+	struct i2c_msg xfer_msg[1];
+
+	xfer_msg[0].addr = client->addr;
+	xfer_msg[0].len = num;
+	xfer_msg[0].flags = 0;
+	xfer_msg[0].buf = buf;
+
+	return i2c_transfer(client->adapter, xfer_msg, 1);
+}
+
+#ifdef CONFIG_MISC_DEV
+static int dev_open(struct inode *inode, struct file *filp)
+{
+	mutex_lock(&pts->access_lock);
+	return 0;
+}
+
+static int dev_release(struct inode *inode, struct file *filp)
+{
+	mutex_unlock(&pts->access_lock);
+	return 0;
+}
+static ssize_t
+dev_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
+{
+	u8 *kbuf;
+	struct i2c_msg xfer_msg;
+	/*static char out[] = "1234567890";*/
+	/*static int idx;*//*= 0; remove by checkpatch*/
+	int i;
+
+	kbuf = kmalloc(count, GFP_KERNEL);
+	if (kbuf == NULL)
+		return -ENOMEM;
+
+	/*xfer_msg.addr = pts->client->addr;*/
+	xfer_msg.addr = I2C_CLIENT_ADDR;
+	xfer_msg.len = count;
+	xfer_msg.flags = I2C_M_RD;
+	xfer_msg.buf = kbuf;
+
+	i2c_transfer(pts->client->adapter, &xfer_msg, 1);
+
+	if (copy_to_user(buf, kbuf, count) == 0)
+		return count;
+	else
+		return -EFAULT;
+}
+
+static ssize_t
+dev_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
+{
+	u8 *kbuf;
+	ssize_t status = 0;
+	int i;
+
+	kbuf = kmalloc(count, GFP_KERNEL);
+	if (kbuf == NULL) {
+		dev_err("kmalloc() fail\n");
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(kbuf, buf, count) == 0) {
+		pts->client->addr = I2C_CLIENT_ADDR;
+		if (rm31100_ts_write(pts->client, kbuf, count) < 0)
+			status = -EFAULT;
+		else
+			status = count;
+	} else {
+		dev_err("copy_from_user() fail\n");
+		status = -EFAULT;
+	}
+
+	kfree(kbuf);
+	return status;
+}
+
+static struct file_operations dev_fops = {
+	.owner = THIS_MODULE,
+	.open = dev_open,
+	.release = dev_release,
+	.read = dev_read,
+	.write = dev_write,
+	/*.unlocked_ioctl = dev_ioctl,*/
+};
+
+static struct miscdevice raydium_ts_miscdev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "raydium_ts",
+	.fops = &dev_fops,
+};
+#endif
+
+
+ssize_t show(struct device_driver *drv, char *buff)
+{
+	struct i2c_msg xfer_msg;
+	int num = 10;
+	char buf[100];
+	/*int i;*/
+
+	xfer_msg.addr = pts->client->addr;
+	xfer_msg.len = num;
+	xfer_msg.flags = I2C_M_RD;
+	xfer_msg.buf = buf;
+	pts->client->addr = I2C_CLIENT_ADDR;
+	i2c_transfer(pts->client->adapter, &xfer_msg, 1);
+
+	return 0;
+}
+
+ssize_t store(struct device_driver *drv, const char *buf, size_t count)
+{
+	/*unsigned char pkt[] = { 0xF2, 5, 1, 1 };*/
+	unsigned char pkt[] = { 0xF1, 5, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+
+	pts->client->addr = I2C_CLIENT_ADDR;
+	rm31100_ts_write(pts->client, pkt, sizeof(pkt));
+
+	return sizeof(pkt);
+}
+
+DRIVER_ATTR(myAttr, 0x777, show, store);
+
+static void report_data(struct rm31100_ts *ts, u16 x, u16 y, u8 pressure, u8 id)
+{
+	if (ts->pdata->swap_xy)
+		swap(x, y);
+
+	/* handle inverting coordinates */
+	if (ts->pdata->invert_x)
+		x = ts->pdata->res_x - x;
+	if (ts->pdata->invert_y)
+		y = ts->pdata->res_y - y;
+/*
+	input_report_abs(ts->input, ABS_MT_TRACKING_ID, id);
+	input_report_abs(ts->input, ABS_MT_POSITION_X, x);
+	input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
+	input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, pressure);
+	input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, ts->dd->finger_size);
+	input_mt_sync(ts->input);
+*/
+/*For protocol B*/
+	input_mt_slot(ts->input_dev, id);
+	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
+	input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
+	input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
+	input_report_abs(ts->input_dev, ABS_MT_PRESSURE, pressure);
+/*
+	dev_dbg("%s(): id =%2hhd, x =%4hd, y =%4hd, pressure = %hhd\n",
+		__func__, id, x, y, pressure);
+*/
+}
+
+static void process_rm31100_data(struct RM31100_ts *ts)
+{
+	u8 id, pressure, touches, i;
+	u16 x, y;
+
+	touches = ts->touch_data[ts->dd->touch_index];
+
+	if (touches > 0) {
+		for (i = 0; i < touches; i++) {
+			id = ts->touch_data[i * ts->dd->touch_bytes +
+				ts->dd->id_index];
+			pressure = ts->touch_data[i * ts->dd->touch_bytes +
+				ts->dd->z_index];
+			/*
+			x = join_bytes(ts->touch_data[i * ts->dd->touch_bytes +
+				ts->dd->x_index + 1],
+			ts->touch_data[i * ts->dd->touch_bytes +
+				ts->dd->x_index]);
+			y = join_bytes(ts->touch_data[i * ts->dd->touch_bytes +
+				ts->dd->y_index + 1],
+			ts->touch_data[i * ts->dd->touch_bytes +
+				ts->dd->y_index]);
+			*/
+			x = get_unaligned_le16(ts->touch_data[i * ts->dd->
+				touch_bytes + ts->dd->x_index]);
+			y = get_unaligned_le16(ts->touch_data[i * ts->dd->
+				touch_bytes + ts->dd->y_index]);
+			report_data(ts, x, y, pressure, id);
+		}
+	} else
+		input_mt_sync(ts->input);
+
+	ts->prev_touches = touches;
+	input_report_key(ts->input, BTN_TOUCH, 1);
+	input_sync(ts->input);
+}
+
+static void rm31100_ts_xy_worker(struct work_struct *work)
+{
+	int rc;
+	u8 DMAAddress[4];
+	struct rm31100_ts *ts;
+#if EVAL_REPORT_RATE
+	static struct timeval tv_start;
+	struct timeval tv_now;
+	static int cnt = -1;
+	int us;
+#endif /* EVAL_REPORT_RATE*/
+
+	/*dev_dbg("****rm31100_ts_xy_worker******\n");*/
+	mutex_lock(&ts->sus_lock);
+	if (ts->is_suspended == true) {
+		dev_dbg(&ts->client->dev, "TS is supended\n");
+		ts->int_pending = true;
+		mutex_unlock(&ts->sus_lock);
+		return;
+	}
+	mutex_unlock(&ts->sus_lock);
+
+	mutex_lock(&ts->access_lock);
+	/* read data from DATA_REG */
+	/*RM31100 DMA Mode*/
+	/*T010 OR w001+T012*/
+	DMAAddress[0] = 0x0F;
+	DMAAddress[1] = 0x00;
+	DMAAddress[2] = 0x20;
+	DMAAddress[3] = 0x81;/* Turn on DMA Mode*/
+	ts->client->addr = I2C_DMA_CLIENT_ADDR;
+	rc = rm31100_ts_write(ts->client, DMAAddress, 0x04);
+	if (rc < 0) {
+		dev_err(&ts->client->dev, "write failed\n");
+		goto schedule;
+	}
+	ts->client->addr = I2C_CLIENT_ADDR;
+	rc = rm31100_ts_read(ts->client, ts->dd->data_reg, ts->touch_data,
+	ts->dd->data_size);
+
+	if (rc < 0) {
+		dev_err(&ts->client->dev, "read failed\n");
+		goto schedule;
+	}
+
+	if (ts->touch_data[ts->dd->touch_index] == INVALID_DATA)
+		goto schedule;
+
+	/* write to STATUS_REG to release lock */
+	rc = rm31100_ts_write_reg_u8(ts->client,
+		ts->dd->status_reg, ts->dd->update_data);
+	if (rc < 0) {
+		dev_err(&ts->client->dev, "write failed, try once more\n");
+
+		rc = rm31100_ts_write_reg_u8(ts->client,
+			ts->dd->status_reg, ts->dd->update_data);
+		if (rc < 0)
+			dev_err(&ts->client->dev, "write failed, exiting\n");
+	}
+
+	process_rm31100_data(ts);
+
+#if EVAL_REPORT_RATE
+	cnt++;
+
+	if (cnt == 0)/* first time this function is executed.*/
+		do_gettimeofday(&tv_start);
+	else if (cnt == 100) {
+		do_gettimeofday(&tv_now);
+		us = 1000000 * (tv_now.tv_sec - tv_start.tv_sec)
+			+ tv_now.tv_usec - tv_start.tv_usec;
+		tv_start.tv_sec = tv_now.tv_sec;
+		tv_start.tv_usec = tv_now.tv_usec;
+		cnt = 0;
+	}
+#endif /* EVAL_REPORT_RATE*/
+schedule:
+
+	mutex_unlock(&ts->access_lock);
+	/*dev_dbg("****Leave rm31100_ts_xy_worker******\n");*/
+}
+
+static irqreturn_t rm31100_ts_irq(int irq, void *dev_id)
+{
+	struct rm31100_ts *ts = dev_id;
+
+/*For protocol B*/
+	input_sync(g_input_dev);
+
+	rm31100_ts_xy_worker(&ts->work);
+	return IRQ_HANDLED;
+}
+
+static int rm31100_ts_init_ts(struct i2c_client *client, struct rm31100_ts *ts)
+{
+	struct input_dev *input_device;
+	int rc = 0;
+
+	ts->dd = &devices[ts->device_id];
+
+	if (!ts->pdata->nfingers) {
+		dev_err(&client->dev, "Touches information not specified\n");
+		return -EINVAL;
+	}
+
+	if (ts->device_id == rm3110x) {
+		if (ts->pdata->nfingers > 2) {
+			dev_err(&client->dev, "Touches >=1 & <= 2\n");
+			return -EINVAL;
+		}
+		ts->dd->data_size = ts->dd->touch_bytes;
+		ts->dd->touch_index = 0x0;
+	} else if (ts->device_id == rm31100) {
+		if (ts->pdata->nfingers > 10) {
+			dev_err(&client->dev, "Touches >=1 & <= 10\n");
+			return -EINVAL;
+		}
+		ts->dd->data_size = ts->pdata->nfingers * ts->dd->touch_bytes +
+						ts->dd->touch_meta_data;
+		ts->dd->touch_index = 0x0;
+	}
+	/* w001 */
+	else {
+		ts->dd->data_size = ts->pdata->nfingers * ts->dd->touch_bytes +
+		ts->dd->touch_meta_data;
+		ts->dd->touch_index = 0x0;
+	}
+
+	ts->touch_data = kzalloc(ts->dd->data_size, GFP_KERNEL);
+	if (!ts->touch_data) {
+		pr_err("%s: Unable to allocate memory\n", __func__);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int rm31100_ts_suspend(struct device *dev)
+{
+	struct rm31100_ts *ts = dev_get_drvdata(dev);
+	int rc = 0, i;
+
+	if (device_may_wakeup(dev)) {
+		/* mark suspend flag */
+		mutex_lock(&ts->sus_lock);
+		ts->is_suspended = true;
+		mutex_unlock(&ts->sus_lock);
+
+		enable_irq_wake(ts->pen_irq);
+	} else {
+		disable_irq_nosync(ts->pen_irq);
+/*For protocol B*/
+	for (i = 0; i < MAX_REPORT_TOUCHED_POINTS; i++) {
+		input_mt_slot(ts->input_dev, i);
+
+		input_mt_report_slot_state(
+			ts->input_dev,
+			MT_TOOL_FINGER, false);
+
+		input_report_key(
+			ts->input_dev,
+			BTN_TOOL_RUBBER, false);
+	}
+	input_sync(ts->input_dev);
+
+		if (rc) {
+			/* missed the worker, write to STATUS_REG to
+			   acknowledge interrupt */
+			rc = rm31100_ts_write_reg_u8(ts->client,
+				ts->dd->status_reg, ts->dd->update_data);
+			if (rc < 0) {
+				dev_err(&ts->client->dev,
+					"write failed, try once more\n");
+
+				rc = rm31100_ts_write_reg_u8(ts->client,
+					ts->dd->status_reg,
+					ts->dd->update_data);
+				if (rc < 0)
+					dev_err(&ts->client->dev,
+						"write failed, exiting\n");
+			}
+
+			enable_irq(ts->pen_irq);
+		}
+
+		gpio_free(ts->pdata->irq_gpio);
+
+		if (ts->pdata->power_on) {
+			rc = ts->pdata->power_on(0);
+			if (rc) {
+				dev_err(dev, "unable to goto suspend\n");
+				return rc;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int rm31100_ts_resume(struct device *dev)
+{
+	struct rm31100_ts *ts = dev_get_drvdata(dev);
+
+	int rc = 0;
+
+	if (device_may_wakeup(dev)) {
+		disable_irq_wake(ts->pen_irq);
+
+		mutex_lock(&ts->sus_lock);
+		ts->is_suspended = false;
+
+		if (ts->int_pending == true)
+			ts->int_pending = false;
+
+		mutex_unlock(&ts->sus_lock);
+
+	} else {
+		if (ts->pdata->power_on) {
+			rc = ts->pdata->power_on(1);
+			if (rc) {
+				dev_err(dev, "unable to resume\n");
+				return rc;
+			}
+		}
+
+		/* configure touchscreen interrupt gpio */
+		rc = gpio_request(ts->pdata->irq_gpio, "rm31100_irq_gpio");
+		if (rc) {
+			pr_err("%s: unable to request gpio %d\n",
+				__func__, ts->pdata->irq_gpio);
+			goto err_power_off;
+		}
+		if (ts->pdata->irq_cfg) {
+			s3c_gpio_cfgpin(ts->pdata->irq_gpio,
+				ts->pdata->irq_cfg);
+			s3c_gpio_setpull(ts->pdata->irq_gpio,
+				S3C_GPIO_PULL_NONE);
+		}
+
+		rc = gpio_direction_input(ts->pdata->irq_gpio);
+		if (rc) {
+			pr_err("%s: unable to set direction for gpio %d\n",
+				__func__, ts->pdata->irq_gpio);
+			goto err_gpio_free;
+		}
+
+		enable_irq(ts->pen_irq);
+
+		/* Clear the status register of the TS controller */
+		rc = rm31100_ts_write_reg_u8(ts->client,
+			ts->dd->status_reg, ts->dd->update_data);
+		if (rc < 0) {
+			dev_err(&ts->client->dev,
+				"write failed, try once more\n");
+
+			rc = rm31100_ts_write_reg_u8(ts->client,
+				ts->dd->status_reg,
+				ts->dd->update_data);
+			if (rc < 0)
+				dev_err(&ts->client->dev,
+					"write failed, exiting\n");
+		}
+	}
+
+	return 0;
+err_gpio_free:
+	gpio_free(ts->pdata->irq_gpio);
+err_power_off:
+	if (ts->pdata->power_on)
+		rc = ts->pdata->power_on(0);
+	return rc;
+}
+
+static struct dev_pm_ops rm31100_ts_pm_ops = {
+	.suspend = rm31100_ts_suspend,
+	.resume = rm31100_ts_resume,
+};
+#endif
+
+static int rm_input_dev_create(struct rm31100_ts *ts)
+{
+	struct input_dev *input_device;
+	int rc = 0;
+	ts->prev_touches = 0;
+
+	input_device = input_allocate_device();
+	if (!input_device) {
+		rc = -ENOMEM;
+		goto error_alloc_dev;
+	}
+
+	ts->input = input_device;
+	input_device->name = "raydium_ts"/*ts->pdata->ts_name*/;
+	input_device->id.bustype = BUS_I2C;
+	input_device->dev.parent = &client->dev;
+	input_set_drvdata(input_device, ts);
+
+	__set_bit(EV_ABS, input_device->evbit);
+	__set_bit(INPUT_PROP_DIRECT, input_device->propbit);
+	/*__set_bit(EV_SYN, input_device->evbit);*/
+	/*__set_bit(BTN_TOUCH, input_device->keybit);*/
+
+
+	if (ts->device_id == rm31100) {
+		/* set up virtual key */
+		__set_bit(EV_KEY, input_device->evbit);
+		/* set dummy key to make driver work with virtual keys */
+		input_set_capability(input_device, EV_KEY, KEY_PROG1);
+	}
+	/*For protocol B*/
+	input_mt_init_slots(input_device,
+		MAX_REPORT_TOUCHED_POINTS,
+		0);
+	input_set_abs_params(input_device, ABS_MT_POSITION_X,
+		ts->pdata->dis_min_x, ts->pdata->dis_max_x, 0, 0);
+	input_set_abs_params(input_device, ABS_MT_POSITION_Y,
+		ts->pdata->dis_min_y, ts->pdata->dis_max_y, 0, 0);
+	input_set_abs_params(input_device, ABS_MT_PRESSURE,
+		0, 0xFF, 0, 0);
+	/*input_set_abs_params(input_device, ABS_MT_TRACKING_ID,
+			ts->pdata->min_tid, ts->pdata->max_tid, 0, 0);*/
+	rc = input_register_device(input_device);
+	if (rc)
+		goto error_unreg_device;
+
+	return 0;
+
+error_unreg_device:
+error_wq_create:
+	input_free_device(input_device);
+error_alloc_dev:
+	kfree(ts->touch_data);
+	return rc;
+}
+
+static int rm31100_initialize(struct i2c_client *client)
+{
+	struct rm31100_ts *ts = i2c_get_clientdata(client);
+	int rc = 0, retry_cnt = 0, temp_reg;
+	/* power on the device */
+	if (ts->pdata->power_on) {
+		rc = ts->pdata->power_on(1);
+		if (rc) {
+			pr_err("%s: Unable to power on the device\n", __func__);
+			goto error_dev_setup;
+		}
+	}
+
+	/* read one byte to make sure i2c device exists */
+	if (ts->device_id == rm3110x)
+		temp_reg = 0x01;
+	else if (ts->device_id == rm31100)
+		temp_reg = 0x00;
+	else
+		temp_reg = 0x05;
+
+	rc = rm31100_ts_read_reg_u8(client, temp_reg);
+	if (rc < 0) {
+		dev_err(&client->dev, "i2c sanity check failed\n");
+		goto error_power_on;
+	}
+
+	rc = rm31100_ts_init_ts(client, ts);
+	if (rc < 0) {
+		dev_err(&client->dev, "rm31100_ts init failed\n");
+		goto error_mutex_destroy;
+	}
+
+	if (ts->pdata->resout_gpio < 0)
+		goto config_irq_gpio;
+
+	/* configure touchscreen reset out gpio */
+	rc = gpio_request(ts->pdata->resout_gpio, "rm31100_resout_gpio");
+	if (rc) {
+		pr_err("%s: unable to request gpio %d\n",
+			__func__, ts->pdata->resout_gpio);
+		goto error_uninit_ts;
+	}
+
+	rc = gpio_direction_output(ts->pdata->resout_gpio, 0);
+	if (rc) {
+		pr_err("%s: unable to set direction for gpio %d\n",
+			__func__, ts->pdata->resout_gpio);
+		goto error_resout_gpio_dir;
+	}
+	/* reset gpio stabilization time */
+	msleep(20);
+
+	return 0;
+error_resout_gpio_dir:
+	if (ts->pdata->resout_gpio >= 0)
+		gpio_free(ts->pdata->resout_gpio);
+error_uninit_ts:
+	input_unregister_device(ts->input);
+	kfree(ts->touch_data);
+error_mutex_destroy:
+	mutex_destroy(&ts->sus_lock);
+	mutex_destroy(&ts->access_lock);
+error_power_on:
+/*	if (ts->pdata->power_on)
+		ts->pdata->power_on(0);*/
+error_dev_setup:
+	if (ts->pdata->dev_setup)
+		ts->pdata->dev_setup(0);
+
+}
+
+static void rm_initialize_async(void *data, async_cookie_t cookie)
+{
+	struct rm31100_ts *ts = data;
+	struct i2c_client *client = ts->client;
+	unsigned long irqflags;
+	int err = 0;
+
+	mutex_lock(&ts->sus_lock);
+
+	err = rm31100_initialize(client);
+	if (err < 0) {
+		dev_err(&client->dev, "probe failed! unbind device.\n");
+		goto error_free_mem;
+	}
+
+	err = rm_input_dev_create(ts);
+	if (err) {
+		dev_err(&client->dev, "%s crated failed, %d\n", __func__, err);
+		goto err_release;
+	}
+
+	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;
+
+	err = request_threaded_irq(ts->pen_irq, NULL,
+				   rm31100_ts_irq,
+				   irqflags | IRQF_ONESHOT,
+				   ts->client->dev.driver->name, ts);
+	if (err) {
+		dev_err(&client->dev, "Failed to register interrupt\n");
+		goto err_release;
+	}
+
+	mutex_unlock(&ts->sus_lock);
+
+	return;
+err_release:
+error_free_mem:
+	kfree(ts);
+	mutex_unlock(&ts->sus_lock);
+	rm31100_ts_remove(client);
+	return;
+}
+
+
+/*static int __devinit rm31100_ts_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)*/
+static int rm31100_ts_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct rm31100_ts *ts;
+	struct rm3110x_ts_platform_data *pdata = client->dev.platform_data;
+	int rc/*, temp_reg*/;
+
+	if (!pdata) {
+		dev_err(&client->dev, "platform data is required!\n");
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter,
+		I2C_FUNC_SMBUS_READ_WORD_DATA)) {
+		dev_err(&client->dev, "I2C functionality not supported\n");
+		return -EIO;
+	}
+	/* Make sure there is something at this address */
+	if (i2c_smbus_xfer(client->adapter, client->addr, 0,
+		I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0)
+		return -ENODEV;
+
+	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+	pts = ts;
+
+	/* Enable runtime PM ops, start in ACTIVE mode */
+	rc = pm_runtime_set_active(&client->dev);
+	if (rc < 0)
+		dev_warn(&client->dev, "unable to set runtime pm state\n");
+	pm_runtime_enable(&client->dev);
+
+	ts->client = client;
+	ts->pdata = pdata;
+	i2c_set_clientdata(client, ts);
+	ts->device_id = id->driver_data;
+
+	if (ts->pdata->dev_setup) {
+		rc = ts->pdata->dev_setup(1);
+		if (rc < 0) {
+			dev_err(&client->dev, "dev setup failed\n");
+			goto error_touch_data_alloc;
+		}
+	}
+
+
+	ts->is_suspended = false;
+	ts->int_pending = false;
+	mutex_init(&ts->sus_lock);
+	mutex_init(&ts->access_lock);
+
+	async_schedule(rm_initialize_async, ts);
+
+	device_init_wakeup(&client->dev, ts->pdata->wakeup);
+	return 0;
+error_reg_misc_dev:
+error_req_irq_fail:
+
+error_resout_gpio_dir:
+	if (ts->pdata->resout_gpio >= 0)
+		gpio_free(ts->pdata->resout_gpio);
+error_uninit_ts:
+	input_unregister_device(ts->input);
+	kfree(ts->touch_data);
+error_mutex_destroy:
+	mutex_destroy(&ts->sus_lock);
+	mutex_destroy(&ts->access_lock);
+error_power_on:
+/*	if (ts->pdata->power_on)
+		ts->pdata->power_on(0);*/
+error_dev_setup:
+	if (ts->pdata->dev_setup)
+		ts->pdata->dev_setup(0);
+error_touch_data_alloc:
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_disable(&client->dev);
+	kfree(ts);
+	return rc;
+}
+
+/*static int __devexit RM31100_ts_remove(struct i2c_client *client)*/
+static int __exit rm31100_ts_remove(struct i2c_client *client)
+{
+	struct rm31100_ts *ts = i2c_get_clientdata(client);
+
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_disable(&client->dev);
+
+	device_init_wakeup(&client->dev, 0);
+	free_irq(ts->pen_irq, ts);
+
+	gpio_free(ts->pdata->irq_gpio);
+
+	if (ts->pdata->resout_gpio >= 0)
+		gpio_free(ts->pdata->resout_gpio);
+	input_unregister_device(ts->input);
+
+	mutex_destroy(&ts->sus_lock);
+	mutex_destroy(&ts->access_lock);
+
+	if (ts->pdata->power_on)
+		ts->pdata->power_on(0);
+
+	if (ts->pdata->dev_setup)
+		ts->pdata->dev_setup(0);
+
+	kfree(ts->touch_data);
+	kfree(ts);
+
+	return 0;
+}
+
+static const struct i2c_device_id rm31100_ts_id[] = {
+	{"RM31100", rm31100},
+	{"RM3110x", rm3110x},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, RM31100_ts_id);
+
+
+static struct i2c_driver rm31100_ts_driver = {
+	.driver = {
+		.name = "raydium_ts",/*rm31100_ts*/
+		.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm = &rm31100_ts_pm_ops,
+#endif
+	},
+	.probe = rm31100_ts_probe,
+	/*.remove		= __devexit_p(RM31100_ts_remove),*/
+	.remove = __exit_p(rm31100_ts_remove),
+	.id_table = rm31100_ts_id,
+};
+
+static int __init rm31100_ts_init(void)
+{
+	int rc;
+	int rc2;
+
+	rc = i2c_add_driver(&rm31100_ts_driver);
+
+	rc2 = driver_create_file(&rm31100_ts_driver.driver,
+		&driver_attr_myAttr);
+
+	return rc;
+}
+/* Making this as late init to avoid power fluctuations
+ * during LCD initialization.
+ */
+late_initcall(RM31100_ts_init);
+
+static void __exit rm31100_ts_exit(void)
+{
+	return i2c_del_driver(&RM31100_ts_driver);
+}
+module_exit(RM31100_ts_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("rm31100-rm3110x touchscreen controller driver");
+MODULE_AUTHOR("Raydium");
+MODULE_ALIAS("platform:rm31100_ts");
diff --git a/include/linux/input/rm31100_ts.h b/include/linux/input/rm31100_ts.h
new file mode 100644
index 0000000..2397436
--- /dev/null
+++ b/include/linux/input/rm31100_ts.h
@@ -0,0 +1,60 @@
+/* Header file for:
+ * Raydium rm31100 Prototype touchscreen driver.
+ *
+ * Copyright (C) 2012, Raydium Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * 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.
+ *
+ * Raydium reserves the right to make changes without further notice
+ * to the materials described herein. Raydium does not assume any
+ * liability arising out of the application described herein.
+ *
+ * Contact Raydium Semiconductor at www.rad-ic.com
+ *
+ * History:
+ *			(C) 2012 Raydium - Update for GPL distribution
+ *			(C) 2009 Enea - Original prototype
+ *
+ */
+#ifndef __RM3110xTS_H__
+#define __RM3110xTS_H__
+
+
+/* rm3110x platform data
+ */
+struct rm3110x_ts_platform_data {
+	int (*power_on)(int on);
+	int (*dev_setup)(bool on);
+	const char *ts_name;
+	u32 dis_min_x; /* display resoltion */
+	u32 dis_max_x;
+	u32 dis_min_y;
+	u32 dis_max_y;
+	u32 min_touch; /* no.of touches supported */
+	u32 max_touch;
+	u32 min_tid; /* track id */
+	u32 max_tid;
+	u32 min_width;/* size of the finger */
+	u32 max_width;
+	u32 res_x; /* TS resolution */
+	u32 res_y;
+	u32 swap_xy;
+	u32 flags;
+	u16 invert_x;
+	u16 invert_y;
+	u8 nfingers;
+	u32 irq_gpio;
+	int resout_gpio;
+	bool wakeup;
+	u32 irq_cfg;
+};
+
+#endif
-- 
2.1.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox