From 5a2a27bc83ee6875518167ce91f283f48734ff54 Mon Sep 17 00:00:00 2001
From: z3deverp <z3@vmsv-debian.(none)>
Date: Sun, 19 Jul 2009 21:13:41 +0900
Subject: [PATCH] sysfs control toggle key mode

---
 drivers/input/keyboard/sha_ponkbd.c |  100 ++++++++++++++++++++++++++++------
 1 files changed, 82 insertions(+), 18 deletions(-)

diff --git a/drivers/input/keyboard/sha_ponkbd.c b/drivers/input/keyboard/sha_ponkbd.c
index 9cb2e16..d5c2b9f 100755
--- a/drivers/input/keyboard/sha_ponkbd.c
+++ b/drivers/input/keyboard/sha_ponkbd.c
@@ -11,18 +11,12 @@
  *
  */
 
-#define SHA_PONKBD_TOGGLE	1	/* ALT,CTRL,SHIFT 0/1=normal/toggle */
-
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/input-polldev.h>
-#include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
 #include <mach/sha_pon.h>
 
 #define KB_ROWS			8
@@ -78,10 +72,11 @@ struct sha_ponkbd {
 	int kbdscan_togglekey[KB_COLS];
 	int kbdscan_toggle_state[KB_COLS];
 	int toggle_enable;
+	int toggle_sense;
+	int showkeys;
 };
 
 
-#if SHA_PONKBD_TOGGLE
 static void sha_pon_clear_toggle(struct sha_ponkbd *sha_ponkbd)
 {
 	unsigned int col, i;
@@ -93,7 +88,7 @@ static void sha_pon_clear_toggle(struct sha_ponkbd *sha_ponkbd)
 		sha_ponkbd->kbdscan_toggle_state[col] = 0;
 	}
 }
-#endif
+
 
 /*
  * Toggle-keys : Shift, Ctrl, Fn(Alt)
@@ -101,6 +96,7 @@ static void sha_pon_clear_toggle(struct sha_ponkbd *sha_ponkbd)
  * Pressing toggle-key, toggle mode ON/OFF.
  * Pressing toggle-key continuous and pressing NOT-toggle-key, turn mode to OFF after input.
  * 
+ * if toggle_sense == 0, stop toggle mode.
  */
 static void sha_pon_report_col(struct sha_ponkbd *sha_ponkbd,
 				unsigned int col, unsigned int rowd, unsigned int rowd_changed, unsigned int toggle_pressed)
@@ -116,14 +112,18 @@ static void sha_pon_report_col(struct sha_ponkbd *sha_ponkbd,
 		scancode = SCANCODE(row, col);
 		keycode = sha_ponkbd->keycode[scancode];
 		
-#if 0	/* print keycode for debug */
-		if( changed && pressed ) {
+		if( sha_ponkbd->showkeys && changed && pressed ) {
 			printk( KERN_WARNING "(sha_ponkbd: keycode=%d/0x%04x, col=%d, row=%d)\n", 
 					keycode, keycode, col, row );
 		}
-#endif
 
-#if SHA_PONKBD_TOGGLE
+		if( !sha_ponkbd->toggle_sense ) {
+			if( changed ) {
+				input_report_key(sha_ponkbd->poll_dev->input, keycode, pressed);
+			}
+			continue;
+		}
+
 		if(togglekey) {
 			if( changed && pressed ) {
 				input_report_key(sha_ponkbd->poll_dev->input, keycode, pressed);
@@ -149,12 +149,6 @@ static void sha_pon_report_col(struct sha_ponkbd *sha_ponkbd,
 				}
 			}
 		}
-#else
-		if( changed ) {
-			input_report_key(sha_ponkbd->poll_dev->input, keycode, pressed);
-		}
-#endif
-
 	}
 }
 
@@ -229,6 +223,59 @@ static void sha_pon_poll(struct input_polled_dev *dev)
 	input_sync(dev->input);
 }
 
+
+static ssize_t show_toggle(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sha_ponkbd *sha_ponkbd = dev_get_drvdata(dev);
+	
+	return sprintf( buf, "%d\n", sha_ponkbd->toggle_sense );
+}
+
+
+static ssize_t store_toggle(struct device *dev, struct device_attribute *attr, 
+			const char *buf, size_t count)
+{
+	struct sha_ponkbd *sha_ponkbd = dev_get_drvdata(dev);
+	int	flag, n;
+	
+	sha_pon_clear_toggle(sha_ponkbd);
+	
+	n = sscanf( buf, "%d", &flag );
+	if( n != 1 )
+		return -EINVAL;
+	
+	sha_ponkbd->toggle_sense = flag ? 1 : 0 ;
+	return strlen(buf);
+}
+
+
+static ssize_t show_showkeys(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sha_ponkbd *sha_ponkbd = dev_get_drvdata(dev);
+	
+	return sprintf( buf, "%d\n", sha_ponkbd->showkeys );
+}
+
+
+static ssize_t store_showkeys(struct device *dev, struct device_attribute *attr, 
+			const char *buf, size_t count)
+{
+	struct sha_ponkbd *sha_ponkbd = dev_get_drvdata(dev);
+	int	flag, n;
+	
+	n = sscanf( buf, "%d", &flag );
+	if( n != 1 )
+		return -EINVAL;
+	
+	sha_ponkbd->showkeys = flag ? 1 : 0 ;
+	return strlen(buf);
+}
+
+
+static DEVICE_ATTR( toggle, S_IRUGO|S_IWUSR, show_toggle, store_toggle);
+static DEVICE_ATTR( showkeys, S_IRUGO|S_IWUSR, show_showkeys, store_showkeys);
+
+
 static int __devinit sha_pon_probe(struct platform_device *pdev)
 {
 	struct sha_ponkbd *sha_ponkbd;
@@ -288,13 +335,27 @@ static int __devinit sha_pon_probe(struct platform_device *pdev)
 			}
 		}
 	}
+	sha_ponkbd->toggle_sense = 0;
+	sha_ponkbd->showkeys = 0;
 	
 	error = input_register_polled_device(sha_ponkbd->poll_dev);
 	if (error)
 		goto fail;
 
+	error = device_create_file(&pdev->dev, &dev_attr_toggle);
+	if (error)
+		goto fail_1;
+
+	error = device_create_file(&pdev->dev, &dev_attr_showkeys);
+	if (error)
+		goto fail_2;
+
 	return 0;
 
+ fail_2:
+	device_remove_file(&pdev->dev, &dev_attr_toggle);
+ fail_1:
+	input_unregister_polled_device(sha_ponkbd->poll_dev);
  fail:
 	input_free_polled_device(poll_dev);
  	kfree(sha_ponkbd);
@@ -305,6 +366,9 @@ static int __devexit sha_pon_remove(struct platform_device *pdev)
 {
 	struct sha_ponkbd *sha_ponkbd = platform_get_drvdata(pdev);
 
+	device_remove_file(&pdev->dev, &dev_attr_showkeys);
+	device_remove_file(&pdev->dev, &dev_attr_toggle);
+
 	input_unregister_polled_device(sha_ponkbd->poll_dev);
 	input_free_polled_device(sha_ponkbd->poll_dev);
 	kfree(sha_ponkbd);
-- 
1.4.4.4

