add jogball
authorswj <swj@rock-chips.com>
Fri, 10 Sep 2010 15:52:13 +0000 (08:52 -0700)
committerswj <swj@rock-chips.com>
Fri, 10 Sep 2010 15:52:13 +0000 (08:52 -0700)
arch/arm/mach-rk2818/board-infoit50.c [changed mode: 0755->0644]
drivers/input/Kconfig
drivers/input/Makefile
drivers/input/jogball/Kconfig [new file with mode: 0644]
drivers/input/jogball/Makefile [new file with mode: 0644]
drivers/input/jogball/rk2818_jogball.c [new file with mode: 0644]

old mode 100755 (executable)
new mode 100644 (file)
index 32e8436..eef8b3d
@@ -368,6 +368,28 @@ struct rk2818_gpio_expander_info  extgpio_tca6424_settinginfo[] = {
                .pin_type           = GPIO_OUT,
                .pin_value                      = GPIO_LOW,
        },
+       {
+               .gpio_num               = TCA6424_P06,  //jog down up left right  p06 p07 p10 p11
+               .pin_type           = GPIO_IN,
+               //.pin_value                    = GPIO_LOW,
+       }, 
+       {
+               .gpio_num               = TCA6424_P07,
+               .pin_type           = GPIO_IN,
+               //.pin_value                    = GPIO_LOW,
+       }, 
+       {
+               .gpio_num               = TCA6424_P10,
+               .pin_type           = GPIO_IN,
+               //.pin_value                    = GPIO_LOW,
+       }, 
+       
+       {
+               .gpio_num               = TCA6424_P11,
+               .pin_type           = GPIO_IN,
+               //.pin_value                    = GPIO_LOW,
+       }, 
+       
        {
                .gpio_num               = TCA6424_P12,// 3G PowerOn
                .pin_type           = GPIO_OUT,
index a082b068f41d8a9d32867da068269ed6e98ec282..6e8cf060fe0ecd453b6f3c2ff9ae8643db2a9fda 100644 (file)
@@ -182,6 +182,9 @@ source "drivers/input/touchscreen/Kconfig"
 source "drivers/input/misc/Kconfig"
 
 source "drivers/input/gsensor/Kconfig"
+
+source "drivers/input/jogball/Kconfig"
+
 endif
 
 menu "Hardware I/O ports"
index 05f9813786df5582dcb4da368bd9d89fc020b955..b5a3c9b48fdd763356a3928ffc26a022e52b7547 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_INPUT_TABLET)    += tablet/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)        += touchscreen/
 obj-$(CONFIG_INPUT_MISC)       += misc/
 obj-$(CONFIG_G_SENSOR_DEVICE)  += gsensor/
+obj-$(CONFIG_INPUT_JOGBALL)    += jogball/
 
 obj-$(CONFIG_INPUT_APMPOWER)   += apm-power.o
 obj-$(CONFIG_INPUT_KEYRESET)   += keyreset.o
diff --git a/drivers/input/jogball/Kconfig b/drivers/input/jogball/Kconfig
new file mode 100644 (file)
index 0000000..d679f9e
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Touchscreen driver configuration
+#
+menuconfig INPUT_JOGBALL
+       bool "Jogball"
+       help
+         Say Y here, and a list of supported jogball will be displayed.
+         This option doesn't affect the kernel.
+
+         If unsure, say Y.
+
+if INPUT_JOGBALL
+
+config RK28_JOGBALL
+       tristate "RK28 Jogball"
+       depends on INPUT_JOGBALL        
+       help
+           say Y here if you have a jogball interface .  
+           
+endif
diff --git a/drivers/input/jogball/Makefile b/drivers/input/jogball/Makefile
new file mode 100644 (file)
index 0000000..cf99825
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the touchscreen drivers.
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_RK28_JOGBALL)             += rk2818_jogball.o
diff --git a/drivers/input/jogball/rk2818_jogball.c b/drivers/input/jogball/rk2818_jogball.c
new file mode 100644 (file)
index 0000000..d76e5e1
--- /dev/null
@@ -0,0 +1,468 @@
+/*\r
+ * linux/drivers/input/keyboard/rk28_jogball.c\r
+ *\r
+ * Driver for the rk28 matrix keyboard controller.\r
+ *\r
+ * Created: 2009-11-28\r
+ * Author:     TY <ty@rockchip.com>\r
+ *\r
+ * This driver program support to AD key which use for rk28 chip\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ */\r
+\r
+#include <linux/kernel.h>\r
+#include <linux/module.h>\r
+#include <linux/init.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/input.h>\r
+#include <linux/device.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/clk.h>\r
+#include <linux/err.h>\r
+#include <linux/delay.h>\r
+#include <linux/time.h>\r
+\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <linux/irq.h>\r
+\r
+\r
+#ifdef CONFIG_ANDROID_POWER\r
+#include <linux/android_power.h>\r
+\r
+static android_early_suspend_t jogball_early_suspend;\r
+#endif\r
+\r
+/* Debug */\r
+#define JB_DEBUG 1\r
+\r
+#ifdef JB_DEBUG\r
+#define DBG    printk\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+\r
+#define JB_KEY_UP           103\r
+#define JB_KEY_DOWN         108\r
+#define JB_KEY_LEFT         105\r
+#define JB_KEY_RIGHT        106\r
+\r
+#define JOGBALL_PHYS_NAME      "rk28_jogball/input0"\r
+\r
+#define JOGBALL_KEY_UP_IO       TCA6424_P06\r
+#define JOGBALL_KEY_DOWN_IO     TCA6424_P07\r
+#define JOGBALL_KEY_LEFT_IO     TCA6424_P10\r
+#define JOGBALL_KEY_RIGHT_IO    TCA6424_P11\r
+\r
+#define JOGBALL_MAX_CNT 2\r
+\r
+static volatile int jogball_cnt_up = 0;\r
+static volatile int jogball_cnt_down = 0;\r
+static volatile int jogball_cnt_left = 0;\r
+static volatile int jogball_cnt_right = 0;\r
+\r
+//key code tab\r
+static unsigned char initkey_code[ ] = \r
+{\r
+       JB_KEY_UP, JB_KEY_DOWN, JB_KEY_LEFT, JB_KEY_RIGHT\r
+};\r
+\r
+struct rk28_jogball \r
+{\r
+       struct input_dev *input_dev;\r
+       unsigned char keycodes[5];\r
+};\r
+\r
+struct rk28_jogball *prockjogball;\r
+\r
+//static void rk28_jogball_up_ISR(void)\r
+\r
+static int rk28_jogball_disable_irq(void )\r
+{\r
+       //DBG("IN jogball suspend !!\n");\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_UP_IO));\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_DOWN_IO));\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_LEFT_IO));\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_RIGHT_IO));\r
+       \r
+       return 0;\r
+}\r
+\r
+static int rk28_jogball_enable_irq(void)\r
+{\r
+       //DBG("IN jogball resume !!\n");\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_UP_IO));\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_DOWN_IO));\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_LEFT_IO));\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_RIGHT_IO));\r
+\r
+    return 0;\r
+}\r
+static irqreturn_t rk28_jogball_up_ISR(int irq, void *dev_id)\r
+{      \r
+       \r
+        rk28_jogball_disable_irq( );\r
+       jogball_cnt_up++;\r
+\r
+       if (jogball_cnt_up > JOGBALL_MAX_CNT){\r
+               //printk("jogball: up\n");\r
+               \r
+               input_report_key(prockjogball->input_dev, JB_KEY_UP, 1);\r
+               input_sync(prockjogball->input_dev);\r
+               input_report_key(prockjogball->input_dev, JB_KEY_UP, 0);\r
+               input_sync(prockjogball->input_dev);\r
+\r
+               jogball_cnt_up = 0;\r
+               jogball_cnt_down = 0;\r
+               jogball_cnt_left = 0;\r
+               jogball_cnt_right = 0;\r
+       }\r
+       \r
+       //gpio_irq_enable(JOGBALL_KEY_UP_IO);\r
+       //enable_irq (gpio_to_irq(JOGBALL_KEY_UP_IO));\r
+        rk28_jogball_enable_irq( );\r
+       return IRQ_HANDLED;\r
+}\r
+\r
+//static void rk28_jogball_down_ISR(void)\r
+static irqreturn_t rk28_jogball_down_ISR(int irq, void *dev_id)\r
+{\r
+        rk28_jogball_disable_irq( );\r
+        //disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_DOWN_IO));\r
+       jogball_cnt_down++;\r
+       \r
+       if (jogball_cnt_down > JOGBALL_MAX_CNT){\r
+               //printk("jogball: down\n");\r
+               \r
+               input_report_key(prockjogball->input_dev, JB_KEY_DOWN, 1);\r
+               input_sync(prockjogball->input_dev);\r
+               input_report_key(prockjogball->input_dev, JB_KEY_DOWN, 0);\r
+               input_sync(prockjogball->input_dev);\r
+               \r
+               jogball_cnt_up = 0;\r
+               jogball_cnt_down = 0;\r
+               jogball_cnt_left = 0;\r
+               jogball_cnt_right = 0;\r
+       }\r
+       \r
+       //gpio_irq_enable(JOGBALL_KEY_DOWN_IO);\r
+       //enable_irq (gpio_to_irq(JOGBALL_KEY_DOWN_IO));\r
+        rk28_jogball_enable_irq( );\r
+       return IRQ_HANDLED;\r
+}\r
+\r
+//static void rk28_jogball_left_ISR(void)\r
+static irqreturn_t rk28_jogball_left_ISR(int irq, void *dev_id)\r
+{\r
+        rk28_jogball_disable_irq( );\r
+       //disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_LEFT_IO));\r
+       jogball_cnt_left++;\r
+\r
+       if (jogball_cnt_left > JOGBALL_MAX_CNT){\r
+               //printk("jogball: left\n");\r
+               \r
+               input_report_key(prockjogball->input_dev, JB_KEY_LEFT, 1);\r
+               input_sync(prockjogball->input_dev);\r
+               input_report_key(prockjogball->input_dev, JB_KEY_LEFT, 0);\r
+               input_sync(prockjogball->input_dev);\r
+\r
+               jogball_cnt_up = 0;\r
+               jogball_cnt_down = 0;\r
+               jogball_cnt_left = 0;\r
+               jogball_cnt_right = 0;\r
+       }\r
+       \r
+       //gpio_irq_enable(JOGBALL_KEY_LEFT_IO);\r
+       //enable_irq (gpio_to_irq(JOGBALL_KEY_LEFT_IO));\r
+        rk28_jogball_enable_irq( );\r
+       return IRQ_HANDLED;\r
+}\r
+\r
+//static void rk28_jogball_right_ISR(void)\r
+static irqreturn_t rk28_jogball_right_ISR(int irq, void *dev_id)\r
+{\r
+        rk28_jogball_disable_irq( );\r
+       //disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_RIGHT_IO));\r
+       jogball_cnt_right++;\r
+\r
+       if (jogball_cnt_right > JOGBALL_MAX_CNT){\r
+               //printk("jogball: right\n");\r
+               \r
+               input_report_key(prockjogball->input_dev, JB_KEY_RIGHT, 1);\r
+               input_sync(prockjogball->input_dev);\r
+               input_report_key(prockjogball->input_dev, JB_KEY_RIGHT, 0);\r
+               input_sync(prockjogball->input_dev);\r
+\r
+               jogball_cnt_up = 0;\r
+               jogball_cnt_down = 0;\r
+               jogball_cnt_left = 0;\r
+               jogball_cnt_right = 0;\r
+       }\r
+       \r
+       //gpio_irq_enable(JOGBALL_KEY_RIGHT_IO);\r
+       //enable_irq (gpio_to_irq(JOGBALL_KEY_RIGHT_IO));\r
+        rk28_jogball_enable_irq( );\r
+       return IRQ_HANDLED;\r
+}\r
+\r
+\r
+\r
+#ifdef CONFIG_ANDROID_POWER\r
+\r
+void rk28_jogball_early_suspend(android_early_suspend_t *h)\r
+{\r
+    DBG("IN jogball early suspend !!\n\n\n");\r
+}\r
+\r
+void rk28_jogball_early_resume(android_early_suspend_t *h)\r
+{\r
+    DBG("IN jogball early resume !!\n\n\n");\r
+}\r
+\r
+#endif\r
+\r
+void rk28_jogball_shutdown(struct platform_device *dev)\r
+{\r
+    DBG("IN jogball early shutdown !!\n\n\n");\r
+}\r
+\r
+static int rk28_jogball_probe(struct platform_device *pdev)\r
+{\r
+  #if 1\r
+      int    error, i;\r
+       struct rk28_jogball *jogball = NULL;\r
+       struct input_dev *input_dev = NULL;\r
+\r
+       printk("***************rk28_jogball_probe...\n");\r
+       \r
+       jogball = kzalloc(sizeof(struct rk28_jogball), GFP_KERNEL);\r
+       if (jogball == NULL)\r
+       {\r
+           printk("Alloc memory for rk28_jogball failed.\n");\r
+           return -ENOMEM;\r
+       }\r
+       \r
+       /* Create and register the input driver. */\r
+       input_dev = input_allocate_device();\r
+       if (!input_dev || !jogball) \r
+       {\r
+               printk("failed to allocate input device.\n");\r
+               error = -ENOMEM;\r
+               goto failed1;\r
+       }\r
+       \r
+       memcpy(jogball->keycodes, initkey_code, sizeof(jogball->keycodes));\r
+       input_dev->name = "jogball";\r
+       input_dev->dev.parent = &pdev->dev;\r
+       input_dev->phys = JOGBALL_PHYS_NAME;\r
+       input_dev->keycode = jogball->keycodes;\r
+       input_dev->keycodesize = sizeof(unsigned char);\r
+       input_dev->keycodemax = ARRAY_SIZE(initkey_code);\r
+       for (i = 0; i < ARRAY_SIZE(initkey_code); i++)\r
+               set_bit(initkey_code[i], input_dev->keybit);\r
+       clear_bit(0, input_dev->keybit);\r
+    input_dev->evbit[0] = BIT_MASK(EV_KEY);\r
+    \r
+       jogball->input_dev = input_dev;\r
+       input_set_drvdata(input_dev, jogball);\r
+\r
+       platform_set_drvdata(pdev, jogball);\r
+\r
+       prockjogball = jogball;\r
+\r
+       /* Register the input device */\r
+       error = input_register_device(input_dev);\r
+       if (error) \r
+       {\r
+               printk("failed to register input device.\n");\r
+               goto failed2;\r
+       }\r
+       printk(" irq register for input device.\n");\r
+       #if 1   //ÉêÇëEXTERN GPIO INTERRUPT\r
+       //JOG_UP_PORT\r
+       \r
+\r
+       error = gpio_request(JOGBALL_KEY_UP_IO,"Jog up");\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_UP_PORT IRQ err=%d\n", error);\r
+               goto failed3;\r
+       }\r
+       gpio_direction_input(JOGBALL_KEY_UP_IO);        \r
+       error = request_irq(gpio_to_irq(JOGBALL_KEY_UP_IO),rk28_jogball_up_ISR,IRQ_TYPE_EDGE_RISING,NULL,jogball);\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_UP_PORT irq\n");\r
+               goto failed4;\r
+       }       \r
+       //JOG_DOWN_PORT\r
+       error = gpio_request(JOGBALL_KEY_DOWN_IO,"jog down");\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_DOWN_PORT IRQ err=%d\n", error);\r
+               goto failed5;\r
+       }\r
+       gpio_direction_input(JOGBALL_KEY_DOWN_IO);\r
+       //gpio_pull_updown(JOG_DOWN_PORT,GPIOPullUp);\r
+       error = request_irq(gpio_to_irq(JOGBALL_KEY_DOWN_IO),rk28_jogball_down_ISR,IRQ_TYPE_EDGE_RISING,NULL,jogball);\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_DOWN_PORT irq\n");\r
+               goto failed6;\r
+       }       \r
+       //JOG_LEFT_PORT\r
+       error = gpio_request(JOGBALL_KEY_LEFT_IO,"jog left");\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_LEFT_PORT IRQ err=%d\n", error);\r
+               goto failed7;\r
+       }\r
+       gpio_direction_input(JOGBALL_KEY_LEFT_IO);\r
+       //gpio_pull_updown(JOG_LEFT_PORT,GPIOPullUp);\r
+       error = request_irq(gpio_to_irq(JOGBALL_KEY_LEFT_IO),rk28_jogball_left_ISR,IRQ_TYPE_EDGE_RISING,NULL,jogball);\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_LEFT_PORT irq\n");\r
+               goto failed8;\r
+       }       \r
+       //JOG_RIGHT_PORT\r
+       error = gpio_request(JOGBALL_KEY_RIGHT_IO,NULL);\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_RIGHT_PORT IRQ err=%d\n", error);\r
+               goto failed9;\r
+       }\r
+       gpio_direction_input(JOGBALL_KEY_RIGHT_IO);\r
+       //gpio_pull_updown(JOG_RIGHT_PORT,GPIOPullUp);\r
+       error = request_irq(gpio_to_irq(JOGBALL_KEY_RIGHT_IO),rk28_jogball_right_ISR,IRQ_TYPE_EDGE_RISING,NULL,jogball);\r
+       if(error)\r
+       {\r
+               printk("unable to request JOG_RIGHT_PORT irq\n");\r
+               goto failed10;\r
+       }                       \r
+#endif\r
+\r
+#ifdef CONFIG_ANDROID_POWER\r
+    jogball_early_suspend.suspend = rk28_jogball_early_suspend;\r
+    jogball_early_suspend.resume = rk28_jogball_early_resume;\r
+    jogball_early_suspend.level = 0x2;\r
+    android_register_early_suspend(&jogball_early_suspend);\r
+#endif\r
+#endif\r
+       printk("******************rk28_jogball_probe end\n");\r
+       return 0;\r
+#if 1\r
+failed10:\r
+       free_irq(gpio_to_irq(JOGBALL_KEY_RIGHT_IO),NULL);\r
+failed9:\r
+       gpio_free(JOGBALL_KEY_RIGHT_IO);\r
+failed8:\r
+       free_irq(gpio_to_irq(JOGBALL_KEY_LEFT_IO),NULL);\r
+failed7:\r
+       gpio_free(JOGBALL_KEY_LEFT_IO);\r
+failed6:               \r
+       free_irq(gpio_to_irq(JOGBALL_KEY_DOWN_IO),NULL);\r
+failed5:\r
+       gpio_free(JOGBALL_KEY_DOWN_IO);\r
+failed4:\r
+       free_irq(gpio_to_irq(JOGBALL_KEY_UP_IO),NULL);\r
+failed3:\r
+       gpio_free(JOGBALL_KEY_UP_IO);\r
+       \r
+       input_unregister_device(jogball->input_dev);\r
+\r
+failed2:\r
+    platform_set_drvdata(pdev, NULL);\r
+    input_free_device(input_dev);\r
+\r
+failed1:\r
+       kfree(jogball);\r
+       \r
+       return error;\r
+#endif\r
+}\r
+\r
+static int __devexit rk28_jogball_remove(struct platform_device *pdev)\r
+{\r
+       struct rk28_jogball *jogball = platform_get_drvdata(pdev);\r
+\r
+    platform_set_drvdata(pdev, NULL);\r
+    \r
+       input_unregister_device(jogball->input_dev);\r
+       input_free_device(jogball->input_dev);\r
+       kfree(jogball);\r
+       \r
+       return 0;\r
+}\r
+\r
+#ifdef CONFIG_PM\r
+\r
+static int rk28_jogball_suspend(struct platform_device *pdev, pm_message_t state)\r
+{\r
+       DBG("IN jogball suspend !!\n");\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_UP_IO));\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_DOWN_IO));\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_LEFT_IO));\r
+       disable_irq_nosync (gpio_to_irq(JOGBALL_KEY_RIGHT_IO));\r
+       \r
+       return 0;\r
+}\r
+\r
+static int rk28_jogball_resume(struct platform_device *pdev)\r
+{\r
+       DBG("IN jogball resume !!\n");\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_UP_IO));\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_DOWN_IO));\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_LEFT_IO));\r
+       enable_irq (gpio_to_irq(JOGBALL_KEY_RIGHT_IO));\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+#endif\r
+\r
+static struct platform_driver rk28_jogball_driver = \r
+{\r
+       .probe          = rk28_jogball_probe,\r
+       .remove         = __devexit_p(rk28_jogball_remove),\r
+       .driver         = {\r
+               .name   = "rk28_jogball",\r
+               .owner  = THIS_MODULE,\r
+       },\r
+       .shutdown   = rk28_jogball_shutdown,\r
+#ifdef CONFIG_PM\r
+   .suspend    = rk28_jogball_suspend,\r
+   .resume     = rk28_jogball_resume,\r
+#endif\r
+};\r
+\r
+ int __init rk28_jogball_init(void)\r
+{\r
+       int ret;\r
+\r
+       printk("****************JOGBALL inital\n");\r
+       ret = platform_driver_register(&rk28_jogball_driver);\r
+       if (ret < 0){\r
+               printk("register rk28_jogball_driver failed!!\n");\r
+       }\r
+       printk("********************JOGBALL inital end\n");\r
+       return ret;\r
+}\r
+\r
+static void __exit rk28_jogball_exit(void)\r
+{\r
+       platform_driver_unregister(&rk28_jogball_driver);\r
+}\r
+\r
+late_initcall(rk28_jogball_init);\r
+module_exit(rk28_jogball_exit);\r
+\r
+MODULE_DESCRIPTION("rk28 jogball Controller Driver");\r
+MODULE_AUTHOR("Yi Tang && Yongle Lai");\r
+MODULE_LICENSE("GPL");\r
+\r
+\r