diff for duplicates of <4C01DEA4.1080704@samsung.com> diff --git a/a/1.txt b/N1/1.txt index cb5a60e..5f24754 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -14,426 +14,3 @@ On 5/30/2010 12:06 PM, Joonyoung Shim wrote: Sorry for bothering. Please use following patch because of typo of prior patch. - - ->From 6455c7c04da3a9af9adf0eef6cd1a596c5cd4df5 Mon Sep 17 00:00:00 2001 -From: Joonyoung Shim <jy0922.shim@samsung.com> -Date: Sun, 30 May 2010 10:58:51 +0900 -Subject: [PATCH 5/5] input: samsung-keypad - Add samsung keypad driver - -This patch adds support for keypad driver running on Samsung cpus. This -driver is tested on GONI and Aquila board using S5PC110 cpu. - -Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> -Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> ---- - drivers/input/keyboard/Kconfig | 9 + - drivers/input/keyboard/Makefile | 1 + - drivers/input/keyboard/samsung-keypad.c | 364 +++++++++++++++++++++++++++++++ - 3 files changed, 374 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/keyboard/samsung-keypad.c - -diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig -index d8fa5d7..bf6a50f 100644 ---- a/drivers/input/keyboard/Kconfig -+++ b/drivers/input/keyboard/Kconfig -@@ -342,6 +342,15 @@ config KEYBOARD_PXA930_ROTARY - To compile this driver as a module, choose M here: the - module will be called pxa930_rotary. - -+config KEYBOARD_SAMSUNG -+ tristate "Samsung keypad support" -+ depends on SAMSUNG_DEV_KEYPAD -+ help -+ Say Y here if you want to use the Samsung keypad. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called samsung-keypad. -+ - config KEYBOARD_STOWAWAY - tristate "Stowaway keyboard" - select SERIO -diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile -index 4596d0c..8f973ed 100644 ---- a/drivers/input/keyboard/Makefile -+++ b/drivers/input/keyboard/Makefile -@@ -32,6 +32,7 @@ obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o - obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o - obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o - obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o -+obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o - obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o - obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o - obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o -diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c -new file mode 100644 -index 0000000..fe8fc7d ---- /dev/null -+++ b/drivers/input/keyboard/samsung-keypad.c -@@ -0,0 +1,364 @@ -+/* -+ * samsung-keypad.c -- Samsung keypad driver -+ * -+ * Copyright (C) 2010 Samsung Electronics Co.Ltd -+ * Author: Joonyoung Shim <jy0922.shim@samsung.com> -+ * Author: Donghwa Lee <dh09.lee@samsung.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/delay.h> -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/input.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <plat/cpu.h> -+#include <plat/keypad.h> -+#include <plat/regs-keypad.h> -+ -+struct samsung_kp { -+ struct input_dev *input_dev; -+ struct timer_list timer; -+ struct clk *clk; -+ struct work_struct work; -+ void __iomem *base; -+ unsigned short *keycodes; -+ unsigned int row_shift; -+ unsigned int rows; -+ unsigned int cols; -+ unsigned int row_state[SAMSUNG_MAX_COLS]; -+ int irq; -+}; -+ -+static void samsung_kp_scan(struct samsung_kp *keypad, unsigned int *row_state) -+{ -+ unsigned int col; -+ unsigned int val; -+ -+ for (col = 0; col < keypad->cols; col++) { -+#if CONFIG_ARCH_S5PV210 -+ val = S5PV210_KEYIFCOLEN_MASK; -+ val &= ~(1 << col) << 8; -+#else -+ val = SAMSUNG_KEYIFCOL_MASK; -+ val &= ~(1 << col); -+#endif -+ writel(val, keypad->base + SAMSUNG_KEYIFCOL); -+ mdelay(1); -+ -+ val = readl(keypad->base + SAMSUNG_KEYIFROW); -+ row_state[col] = ~val & ((1 << keypad->rows) - 1); -+ } -+ -+ /* KEYIFCOL reg clear */ -+ writel(0, keypad->base + SAMSUNG_KEYIFCOL); -+} -+ -+static void samsung_kp_worker(struct work_struct *work) -+{ -+ struct samsung_kp *keypad = container_of(work, struct samsung_kp, work); -+ unsigned int row_state[SAMSUNG_MAX_COLS]; -+ unsigned int val; -+ unsigned int changed; -+ unsigned int pressed; -+ unsigned int key_down = 0; -+ int col, row; -+ -+ clk_enable(keypad->clk); -+ -+ val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); -+ -+ /* interrupt clear */ -+ writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR); -+ -+ val = readl(keypad->base + SAMSUNG_KEYIFCON); -+ val &= ~(SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN); -+ writel(val, keypad->base + SAMSUNG_KEYIFCON); -+ -+ samsung_kp_scan(keypad, row_state); -+ -+ for (col = 0; col < keypad->cols; col++) { -+ changed = row_state[col] ^ keypad->row_state[col]; -+ key_down |= row_state[col]; -+ if (!changed) -+ continue; -+ -+ for (row = 0; row < keypad->rows; row++) { -+ if (!(changed & (1 << row))) -+ continue; -+ -+ pressed = row_state[col] & (1 << row); -+ -+ dev_dbg(&keypad->input_dev->dev, -+ "key %s, row: %d, col: %d\n", -+ pressed ? "pressed" : "released", row, col); -+ -+ val = MATRIX_SCAN_CODE(row, col, keypad->row_shift); -+ -+ input_report_key(keypad->input_dev, -+ keypad->keycodes[val], pressed); -+ input_sync(keypad->input_dev); -+ } -+ } -+ memcpy(keypad->row_state, row_state, sizeof(row_state)); -+ -+ if (key_down) -+ mod_timer(&keypad->timer, jiffies + HZ / 20); -+ else { -+ /* enable interrupt bit */ -+ val = readl(keypad->base + SAMSUNG_KEYIFCON); -+ val |= (SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN); -+ writel(val, keypad->base + SAMSUNG_KEYIFCON); -+ enable_irq(keypad->irq); -+ } -+ clk_disable(keypad->clk); -+} -+ -+static irqreturn_t samsung_kp_interrupt(int irq, void *dev_id) -+{ -+ struct samsung_kp *keypad = dev_id; -+ -+ if (!work_pending(&keypad->work)) { -+ disable_irq_nosync(keypad->irq); -+ schedule_work(&keypad->work); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void samsung_kp_timer(unsigned long data) -+{ -+ struct samsung_kp *keypad = (struct samsung_kp *)data; -+ -+ schedule_work(&keypad->work); -+} -+ -+static int __devinit samsung_kp_probe(struct platform_device *pdev) -+{ -+ const struct samsung_kp_platdata *pdata; -+ const struct matrix_keymap_data *keymap_data; -+ struct samsung_kp *keypad; -+ struct resource *res; -+ struct input_dev *input_dev; -+ unsigned short *keycodes; -+ unsigned int row_shift; -+ unsigned int val; -+ int ret; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data defined\n"); -+ return -EINVAL; -+ } -+ -+ keymap_data = pdata->keymap_data; -+ if (!keymap_data) { -+ dev_err(&pdev->dev, "no keymap data defined\n"); -+ return -EINVAL; -+ } -+ -+ if ((pdata->rows <= 0) || (pdata->rows > SAMSUNG_MAX_ROWS)) -+ return -EINVAL; -+ -+ if ((pdata->cols <= 0) || (pdata->cols > SAMSUNG_MAX_COLS)) -+ return -EINVAL; -+ -+ /* initialize the gpio */ -+ if (pdata->cfg_gpio) -+ pdata->cfg_gpio(pdata->rows, pdata->cols); -+ -+ row_shift = get_count_order(pdata->cols); -+ keypad = kzalloc(sizeof(*keypad), GFP_KERNEL); -+ keycodes = kzalloc((pdata->rows << row_shift) * sizeof(*keycodes), -+ GFP_KERNEL); -+ input_dev = input_allocate_device(); -+ if (!keypad || !keycodes || !input_dev) { -+ ret = -ENOMEM; -+ goto err_free_mem; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ ret = -ENODEV; -+ goto err_free_mem; -+ } -+ -+ keypad->base = ioremap(res->start, resource_size(res)); -+ if (!keypad->base) { -+ ret = -EBUSY; -+ goto err_free_mem; -+ } -+ -+ keypad->clk = clk_get(&pdev->dev, "keypad"); -+ if (IS_ERR(keypad->clk)) { -+ dev_err(&pdev->dev, "failed to get keypad clk\n"); -+ ret = PTR_ERR(keypad->clk); -+ goto err_unmap_base; -+ } -+ clk_enable(keypad->clk); -+ -+ keypad->input_dev = input_dev; -+ keypad->keycodes = keycodes; -+ keypad->row_shift = row_shift; -+ keypad->rows = pdata->rows; -+ keypad->cols = pdata->cols; -+ -+ INIT_WORK(&keypad->work, samsung_kp_worker); -+ -+ setup_timer(&keypad->timer, samsung_kp_timer, (unsigned long)keypad); -+ -+ /* enable interrupt and wakeup bit */ -+ val = SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN | SAMSUNG_WAKEUPEN; -+ writel(val, keypad->base + SAMSUNG_KEYIFCON); -+ -+ /* KEYIFCOL reg clear */ -+ writel(0, keypad->base + SAMSUNG_KEYIFCOL); -+ -+ keypad->irq = platform_get_irq(pdev, 0); -+ if (keypad->irq < 0) { -+ ret = keypad->irq; -+ goto err_disable_clk; -+ } -+ -+ ret = request_irq(keypad->irq, samsung_kp_interrupt, 0, -+ dev_name(&pdev->dev), keypad); -+ -+ if (ret) -+ goto err_disable_clk; -+ -+ input_dev->name = pdev->name; -+ input_dev->id.bustype = BUS_HOST; -+ input_dev->dev.parent = &pdev->dev; -+ -+ input_dev->evbit[0] = BIT_MASK(EV_KEY); -+ if (pdata->rep) -+ input_dev->evbit[0] |= BIT_MASK(EV_REP); -+ -+ input_dev->keycode = keycodes; -+ input_dev->keycodesize = sizeof(*keycodes); -+ input_dev->keycodemax = pdata->rows << row_shift; -+ -+ matrix_keypad_build_keymap(keymap_data, row_shift, -+ input_dev->keycode, input_dev->keybit); -+ -+ ret = input_register_device(keypad->input_dev); -+ if (ret) -+ goto err_free_irq; -+ -+ platform_set_drvdata(pdev, keypad); -+ clk_disable(keypad->clk); -+ -+ return 0; -+ -+err_free_irq: -+ free_irq(keypad->irq, keypad); -+err_disable_clk: -+ clk_disable(keypad->clk); -+ clk_put(keypad->clk); -+err_unmap_base: -+ iounmap(keypad->base); -+err_free_mem: -+ input_free_device(input_dev); -+ kfree(keycodes); -+ kfree(keypad); -+ -+ return ret; -+} -+ -+static int __devexit samsung_kp_remove(struct platform_device *pdev) -+{ -+ struct samsung_kp *keypad = platform_get_drvdata(pdev); -+ -+ free_irq(keypad->irq, keypad); -+ cancel_work_sync(&keypad->work); -+ del_timer_sync(&keypad->timer); -+ -+ platform_set_drvdata(pdev, NULL); -+ input_unregister_device(keypad->input_dev); -+ -+ clk_disable(keypad->clk); -+ clk_put(keypad->clk); -+ -+ iounmap(keypad->base); -+ kfree(keypad->keycodes); -+ kfree(keypad); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int samsung_kp_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct samsung_kp *keypad = platform_get_drvdata(pdev); -+ -+ disable_irq(keypad->irq); -+ -+ return 0; -+} -+ -+static int samsung_kp_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct samsung_kp *keypad = platform_get_drvdata(pdev); -+ unsigned int val; -+ -+ clk_enable(keypad->clk); -+ -+ /* enable interrupt and wakeup bit */ -+ val = SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN | SAMSUNG_WAKEUPEN; -+ writel(val, keypad->base + SAMSUNG_KEYIFCON); -+ -+ /* KEYIFCOL reg clear */ -+ writel(0, keypad->base + SAMSUNG_KEYIFCOL); -+ -+ enable_irq(keypad->irq); -+ clk_disable(keypad->clk); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops samsung_kp_pm_ops = { -+ .suspend = samsung_kp_suspend, -+ .resume = samsung_kp_resume, -+}; -+#endif -+ -+static struct platform_driver samsung_kp_driver = { -+ .probe = samsung_kp_probe, -+ .remove = __devexit_p(samsung_kp_remove), -+ .driver = { -+ .name = "samsung-keypad", -+ .owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .pm = &samsung_kp_pm_ops, -+#endif -+ }, -+}; -+ -+static int __init samsung_kp_init(void) -+{ -+ return platform_driver_register(&samsung_kp_driver); -+} -+ -+static void __exit samsung_kp_exit(void) -+{ -+ platform_driver_unregister(&samsung_kp_driver); -+} -+ -+module_init(samsung_kp_init); -+module_exit(samsung_kp_exit); -+ -+MODULE_DESCRIPTION("Samsung keypad driver"); -+MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); -+MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); -+MODULE_LICENSE("GPL"); --- -1.7.0.4 diff --git a/a/content_digest b/N1/content_digest index bf33ef4..bd56206 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,14 +1,9 @@ "ref\01275188784-23395-1-git-send-email-jy0922.shim@samsung.com\0" "ref\01275188784-23395-5-git-send-email-jy0922.shim@samsung.com\0" - "From\0Joonyoung Shim <jy0922.shim@samsung.com>\0" - "Subject\0Re: [PATCH v2 5/5] input: samsung-keypad - Add samsung keypad driver\0" + "From\0jy0922.shim@samsung.com (Joonyoung Shim)\0" + "Subject\0[PATCH v2 5/5] input: samsung-keypad - Add samsung keypad driver\0" "Date\0Sun, 30 May 2010 12:42:28 +0900\0" - "To\0ben-linux@fluff.org\0" - "Cc\0kyungmin.park@samsung.com" - linux-samsung-soc@vger.kernel.org - dmitry.torokhov@gmail.com - linux-arm-kernel@lists.infradead.org - " linux-input@vger.kernel.org\0" + "To\0linux-arm-kernel@lists.infradead.org\0" "\00:1\0" "b\0" "On 5/30/2010 12:06 PM, Joonyoung Shim wrote:\n" @@ -26,429 +21,6 @@ "> \n" "\n" "Sorry for bothering.\n" - "Please use following patch because of typo of prior patch.\n" - "\n" - "\n" - ">From 6455c7c04da3a9af9adf0eef6cd1a596c5cd4df5 Mon Sep 17 00:00:00 2001\n" - "From: Joonyoung Shim <jy0922.shim@samsung.com>\n" - "Date: Sun, 30 May 2010 10:58:51 +0900\n" - "Subject: [PATCH 5/5] input: samsung-keypad - Add samsung keypad driver\n" - "\n" - "This patch adds support for keypad driver running on Samsung cpus. This\n" - "driver is tested on GONI and Aquila board using S5PC110 cpu.\n" - "\n" - "Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>\n" - "Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>\n" - "---\n" - " drivers/input/keyboard/Kconfig | 9 +\n" - " drivers/input/keyboard/Makefile | 1 +\n" - " drivers/input/keyboard/samsung-keypad.c | 364 +++++++++++++++++++++++++++++++\n" - " 3 files changed, 374 insertions(+), 0 deletions(-)\n" - " create mode 100644 drivers/input/keyboard/samsung-keypad.c\n" - "\n" - "diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig\n" - "index d8fa5d7..bf6a50f 100644\n" - "--- a/drivers/input/keyboard/Kconfig\n" - "+++ b/drivers/input/keyboard/Kconfig\n" - "@@ -342,6 +342,15 @@ config KEYBOARD_PXA930_ROTARY\n" - " \t To compile this driver as a module, choose M here: the\n" - " \t module will be called pxa930_rotary.\n" - " \n" - "+config KEYBOARD_SAMSUNG\n" - "+\ttristate \"Samsung keypad support\"\n" - "+\tdepends on SAMSUNG_DEV_KEYPAD\n" - "+\thelp\n" - "+\t Say Y here if you want to use the Samsung keypad.\n" - "+\n" - "+\t To compile this driver as a module, choose M here: the\n" - "+\t module will be called samsung-keypad.\n" - "+\n" - " config KEYBOARD_STOWAWAY\n" - " \ttristate \"Stowaway keyboard\"\n" - " \tselect SERIO\n" - "diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile\n" - "index 4596d0c..8f973ed 100644\n" - "--- a/drivers/input/keyboard/Makefile\n" - "+++ b/drivers/input/keyboard/Makefile\n" - "@@ -32,6 +32,7 @@ obj-$(CONFIG_KEYBOARD_OPENCORES)\t+= opencores-kbd.o\n" - " obj-$(CONFIG_KEYBOARD_PXA27x)\t\t+= pxa27x_keypad.o\n" - " obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)\t+= pxa930_rotary.o\n" - " obj-$(CONFIG_KEYBOARD_QT2160)\t\t+= qt2160.o\n" - "+obj-$(CONFIG_KEYBOARD_SAMSUNG)\t\t+= samsung-keypad.o\n" - " obj-$(CONFIG_KEYBOARD_SH_KEYSC)\t\t+= sh_keysc.o\n" - " obj-$(CONFIG_KEYBOARD_STOWAWAY)\t\t+= stowaway.o\n" - " obj-$(CONFIG_KEYBOARD_SUNKBD)\t\t+= sunkbd.o\n" - "diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c\n" - "new file mode 100644\n" - "index 0000000..fe8fc7d\n" - "--- /dev/null\n" - "+++ b/drivers/input/keyboard/samsung-keypad.c\n" - "@@ -0,0 +1,364 @@\n" - "+/*\n" - "+ * samsung-keypad.c -- Samsung keypad driver\n" - "+ *\n" - "+ * Copyright (C) 2010 Samsung Electronics Co.Ltd\n" - "+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>\n" - "+ * Author: Donghwa Lee <dh09.lee@samsung.com>\n" - "+ *\n" - "+ * This program is free software; you can redistribute it and/or modify it\n" - "+ * under the terms of the GNU General Public License as published by the\n" - "+ * Free Software Foundation; either version 2 of the License, or (at your\n" - "+ * option) any later version.\n" - "+ */\n" - "+\n" - "+#include <linux/clk.h>\n" - "+#include <linux/delay.h>\n" - "+#include <linux/err.h>\n" - "+#include <linux/init.h>\n" - "+#include <linux/input.h>\n" - "+#include <linux/interrupt.h>\n" - "+#include <linux/io.h>\n" - "+#include <linux/module.h>\n" - "+#include <linux/platform_device.h>\n" - "+#include <linux/slab.h>\n" - "+#include <plat/cpu.h>\n" - "+#include <plat/keypad.h>\n" - "+#include <plat/regs-keypad.h>\n" - "+\n" - "+struct samsung_kp {\n" - "+\tstruct input_dev *input_dev;\n" - "+\tstruct timer_list timer;\n" - "+\tstruct clk *clk;\n" - "+\tstruct work_struct work;\n" - "+\tvoid __iomem *base;\n" - "+\tunsigned short *keycodes;\n" - "+\tunsigned int row_shift;\n" - "+\tunsigned int rows;\n" - "+\tunsigned int cols;\n" - "+\tunsigned int row_state[SAMSUNG_MAX_COLS];\n" - "+\tint irq;\n" - "+};\n" - "+\n" - "+static void samsung_kp_scan(struct samsung_kp *keypad, unsigned int *row_state)\n" - "+{\n" - "+\tunsigned int col;\n" - "+\tunsigned int val;\n" - "+\n" - "+\tfor (col = 0; col < keypad->cols; col++) {\n" - "+#if CONFIG_ARCH_S5PV210\n" - "+\t\tval = S5PV210_KEYIFCOLEN_MASK;\n" - "+\t\tval &= ~(1 << col) << 8;\n" - "+#else\n" - "+\t\tval = SAMSUNG_KEYIFCOL_MASK;\n" - "+\t\tval &= ~(1 << col);\n" - "+#endif\n" - "+\t\twritel(val, keypad->base + SAMSUNG_KEYIFCOL);\n" - "+\t\tmdelay(1);\n" - "+\n" - "+\t\tval = readl(keypad->base + SAMSUNG_KEYIFROW);\n" - "+\t\trow_state[col] = ~val & ((1 << keypad->rows) - 1);\n" - "+\t}\n" - "+\n" - "+\t/* KEYIFCOL reg clear */\n" - "+\twritel(0, keypad->base + SAMSUNG_KEYIFCOL);\n" - "+}\n" - "+\n" - "+static void samsung_kp_worker(struct work_struct *work)\n" - "+{\n" - "+\tstruct samsung_kp *keypad = container_of(work, struct samsung_kp, work);\n" - "+\tunsigned int row_state[SAMSUNG_MAX_COLS];\n" - "+\tunsigned int val;\n" - "+\tunsigned int changed;\n" - "+\tunsigned int pressed;\n" - "+\tunsigned int key_down = 0;\n" - "+\tint col, row;\n" - "+\n" - "+\tclk_enable(keypad->clk);\n" - "+\n" - "+\tval = readl(keypad->base + SAMSUNG_KEYIFSTSCLR);\n" - "+\n" - "+\t/* interrupt clear */\n" - "+\twritel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);\n" - "+\n" - "+\tval = readl(keypad->base + SAMSUNG_KEYIFCON);\n" - "+\tval &= ~(SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN);\n" - "+\twritel(val, keypad->base + SAMSUNG_KEYIFCON);\n" - "+\n" - "+\tsamsung_kp_scan(keypad, row_state);\n" - "+\n" - "+\tfor (col = 0; col < keypad->cols; col++) {\n" - "+\t\tchanged = row_state[col] ^ keypad->row_state[col];\n" - "+\t\tkey_down |= row_state[col];\n" - "+\t\tif (!changed)\n" - "+\t\t\tcontinue;\n" - "+\n" - "+\t\tfor (row = 0; row < keypad->rows; row++) {\n" - "+\t\t\tif (!(changed & (1 << row)))\n" - "+\t\t\t\tcontinue;\n" - "+\n" - "+\t\t\tpressed = row_state[col] & (1 << row);\n" - "+\n" - "+\t\t\tdev_dbg(&keypad->input_dev->dev,\n" - "+\t\t\t\t\"key %s, row: %d, col: %d\\n\",\n" - "+\t\t\t\tpressed ? \"pressed\" : \"released\", row, col);\n" - "+\n" - "+\t\t\tval = MATRIX_SCAN_CODE(row, col, keypad->row_shift);\n" - "+\n" - "+\t\t\tinput_report_key(keypad->input_dev,\n" - "+\t\t\t\t\tkeypad->keycodes[val], pressed);\n" - "+\t\t\tinput_sync(keypad->input_dev);\n" - "+\t\t}\n" - "+\t}\n" - "+\tmemcpy(keypad->row_state, row_state, sizeof(row_state));\n" - "+\n" - "+\tif (key_down)\n" - "+\t\tmod_timer(&keypad->timer, jiffies + HZ / 20);\n" - "+\telse {\n" - "+\t\t/* enable interrupt bit */\n" - "+\t\tval = readl(keypad->base + SAMSUNG_KEYIFCON);\n" - "+\t\tval |= (SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN);\n" - "+\t\twritel(val, keypad->base + SAMSUNG_KEYIFCON);\n" - "+\t\tenable_irq(keypad->irq);\n" - "+\t}\n" - "+\tclk_disable(keypad->clk);\n" - "+}\n" - "+\n" - "+static irqreturn_t samsung_kp_interrupt(int irq, void *dev_id)\n" - "+{\n" - "+\tstruct samsung_kp *keypad = dev_id;\n" - "+\n" - "+\tif (!work_pending(&keypad->work)) {\n" - "+\t\tdisable_irq_nosync(keypad->irq);\n" - "+\t\tschedule_work(&keypad->work);\n" - "+\t}\n" - "+\n" - "+\treturn IRQ_HANDLED;\n" - "+}\n" - "+\n" - "+static void samsung_kp_timer(unsigned long data)\n" - "+{\n" - "+\tstruct samsung_kp *keypad = (struct samsung_kp *)data;\n" - "+\n" - "+\tschedule_work(&keypad->work);\n" - "+}\n" - "+\n" - "+static int __devinit samsung_kp_probe(struct platform_device *pdev)\n" - "+{\n" - "+\tconst struct samsung_kp_platdata *pdata;\n" - "+\tconst struct matrix_keymap_data *keymap_data;\n" - "+\tstruct samsung_kp *keypad;\n" - "+\tstruct resource *res;\n" - "+\tstruct input_dev *input_dev;\n" - "+\tunsigned short *keycodes;\n" - "+\tunsigned int row_shift;\n" - "+\tunsigned int val;\n" - "+\tint ret;\n" - "+\n" - "+\tpdata = pdev->dev.platform_data;\n" - "+\tif (!pdata) {\n" - "+\t\tdev_err(&pdev->dev, \"no platform data defined\\n\");\n" - "+\t\treturn -EINVAL;\n" - "+\t}\n" - "+\n" - "+\tkeymap_data = pdata->keymap_data;\n" - "+\tif (!keymap_data) {\n" - "+\t\tdev_err(&pdev->dev, \"no keymap data defined\\n\");\n" - "+\t\treturn -EINVAL;\n" - "+\t}\n" - "+\n" - "+\tif ((pdata->rows <= 0) || (pdata->rows > SAMSUNG_MAX_ROWS))\n" - "+\t\treturn -EINVAL;\n" - "+\n" - "+\tif ((pdata->cols <= 0) || (pdata->cols > SAMSUNG_MAX_COLS))\n" - "+\t\treturn -EINVAL;\n" - "+\n" - "+\t/* initialize the gpio */\n" - "+\tif (pdata->cfg_gpio)\n" - "+\t\tpdata->cfg_gpio(pdata->rows, pdata->cols);\n" - "+\n" - "+\trow_shift = get_count_order(pdata->cols);\n" - "+\tkeypad = kzalloc(sizeof(*keypad), GFP_KERNEL);\n" - "+\tkeycodes = kzalloc((pdata->rows << row_shift) * sizeof(*keycodes),\n" - "+\t\t\tGFP_KERNEL);\n" - "+\tinput_dev = input_allocate_device();\n" - "+\tif (!keypad || !keycodes || !input_dev) {\n" - "+\t\tret = -ENOMEM;\n" - "+\t\tgoto err_free_mem;\n" - "+\t}\n" - "+\n" - "+\tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n" - "+\tif (!res) {\n" - "+\t\tret = -ENODEV;\n" - "+\t\tgoto err_free_mem;\n" - "+\t}\n" - "+\n" - "+\tkeypad->base = ioremap(res->start, resource_size(res));\n" - "+\tif (!keypad->base) {\n" - "+\t\tret = -EBUSY;\n" - "+\t\tgoto err_free_mem;\n" - "+\t}\n" - "+\n" - "+\tkeypad->clk = clk_get(&pdev->dev, \"keypad\");\n" - "+\tif (IS_ERR(keypad->clk)) {\n" - "+\t\tdev_err(&pdev->dev, \"failed to get keypad clk\\n\");\n" - "+\t\tret = PTR_ERR(keypad->clk);\n" - "+\t\tgoto err_unmap_base;\n" - "+\t}\n" - "+\tclk_enable(keypad->clk);\n" - "+\n" - "+\tkeypad->input_dev = input_dev;\n" - "+\tkeypad->keycodes = keycodes;\n" - "+\tkeypad->row_shift = row_shift;\n" - "+\tkeypad->rows = pdata->rows;\n" - "+\tkeypad->cols = pdata->cols;\n" - "+\n" - "+\tINIT_WORK(&keypad->work, samsung_kp_worker);\n" - "+\n" - "+\tsetup_timer(&keypad->timer, samsung_kp_timer, (unsigned long)keypad);\n" - "+\n" - "+\t/* enable interrupt and wakeup bit */\n" - "+\tval = SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN | SAMSUNG_WAKEUPEN;\n" - "+\twritel(val, keypad->base + SAMSUNG_KEYIFCON);\n" - "+\n" - "+\t/* KEYIFCOL reg clear */\n" - "+\twritel(0, keypad->base + SAMSUNG_KEYIFCOL);\n" - "+\n" - "+\tkeypad->irq = platform_get_irq(pdev, 0);\n" - "+\tif (keypad->irq < 0) {\n" - "+\t\tret = keypad->irq;\n" - "+\t\tgoto err_disable_clk;\n" - "+\t}\n" - "+\n" - "+\tret = request_irq(keypad->irq, samsung_kp_interrupt, 0,\n" - "+\t\t\tdev_name(&pdev->dev), keypad);\n" - "+\n" - "+\tif (ret)\n" - "+\t\tgoto err_disable_clk;\n" - "+\n" - "+\tinput_dev->name = pdev->name;\n" - "+\tinput_dev->id.bustype = BUS_HOST;\n" - "+\tinput_dev->dev.parent = &pdev->dev;\n" - "+\n" - "+\tinput_dev->evbit[0] = BIT_MASK(EV_KEY);\n" - "+\tif (pdata->rep)\n" - "+\t\tinput_dev->evbit[0] |= BIT_MASK(EV_REP);\n" - "+\n" - "+\tinput_dev->keycode = keycodes;\n" - "+\tinput_dev->keycodesize = sizeof(*keycodes);\n" - "+\tinput_dev->keycodemax = pdata->rows << row_shift;\n" - "+\n" - "+\tmatrix_keypad_build_keymap(keymap_data, row_shift,\n" - "+\t\t\tinput_dev->keycode, input_dev->keybit);\n" - "+\n" - "+\tret = input_register_device(keypad->input_dev);\n" - "+\tif (ret)\n" - "+\t\tgoto err_free_irq;\n" - "+\n" - "+\tplatform_set_drvdata(pdev, keypad);\n" - "+\tclk_disable(keypad->clk);\n" - "+\n" - "+\treturn 0;\n" - "+\n" - "+err_free_irq:\n" - "+\tfree_irq(keypad->irq, keypad);\n" - "+err_disable_clk:\n" - "+\tclk_disable(keypad->clk);\n" - "+\tclk_put(keypad->clk);\n" - "+err_unmap_base:\n" - "+\tiounmap(keypad->base);\n" - "+err_free_mem:\n" - "+\tinput_free_device(input_dev);\n" - "+\tkfree(keycodes);\n" - "+\tkfree(keypad);\n" - "+\n" - "+\treturn ret;\n" - "+}\n" - "+\n" - "+static int __devexit samsung_kp_remove(struct platform_device *pdev)\n" - "+{\n" - "+\tstruct samsung_kp *keypad = platform_get_drvdata(pdev);\n" - "+\n" - "+\tfree_irq(keypad->irq, keypad);\n" - "+\tcancel_work_sync(&keypad->work);\n" - "+\tdel_timer_sync(&keypad->timer);\n" - "+\n" - "+\tplatform_set_drvdata(pdev, NULL);\n" - "+\tinput_unregister_device(keypad->input_dev);\n" - "+\n" - "+\tclk_disable(keypad->clk);\n" - "+\tclk_put(keypad->clk);\n" - "+\n" - "+\tiounmap(keypad->base);\n" - "+\tkfree(keypad->keycodes);\n" - "+\tkfree(keypad);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+#ifdef CONFIG_PM\n" - "+static int samsung_kp_suspend(struct device *dev)\n" - "+{\n" - "+\tstruct platform_device *pdev = to_platform_device(dev);\n" - "+\tstruct samsung_kp *keypad = platform_get_drvdata(pdev);\n" - "+\n" - "+\tdisable_irq(keypad->irq);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int samsung_kp_resume(struct device *dev)\n" - "+{\n" - "+\tstruct platform_device *pdev = to_platform_device(dev);\n" - "+\tstruct samsung_kp *keypad = platform_get_drvdata(pdev);\n" - "+\tunsigned int val;\n" - "+\n" - "+\tclk_enable(keypad->clk);\n" - "+\n" - "+\t/* enable interrupt and wakeup bit */\n" - "+\tval = SAMSUNG_INT_F_EN | SAMSUNG_INT_R_EN | SAMSUNG_WAKEUPEN;\n" - "+\twritel(val, keypad->base + SAMSUNG_KEYIFCON);\n" - "+\n" - "+\t/* KEYIFCOL reg clear */\n" - "+\twritel(0, keypad->base + SAMSUNG_KEYIFCOL);\n" - "+\n" - "+\tenable_irq(keypad->irq);\n" - "+\tclk_disable(keypad->clk);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static const struct dev_pm_ops samsung_kp_pm_ops = {\n" - "+\t.suspend\t= samsung_kp_suspend,\n" - "+\t.resume\t\t= samsung_kp_resume,\n" - "+};\n" - "+#endif\n" - "+\n" - "+static struct platform_driver samsung_kp_driver = {\n" - "+\t.probe\t\t= samsung_kp_probe,\n" - "+\t.remove\t\t= __devexit_p(samsung_kp_remove),\n" - "+\t.driver\t\t= {\n" - "+\t\t.name\t= \"samsung-keypad\",\n" - "+\t\t.owner\t= THIS_MODULE,\n" - "+#ifdef CONFIG_PM\n" - "+\t\t.pm\t= &samsung_kp_pm_ops,\n" - "+#endif\n" - "+\t},\n" - "+};\n" - "+\n" - "+static int __init samsung_kp_init(void)\n" - "+{\n" - "+\treturn platform_driver_register(&samsung_kp_driver);\n" - "+}\n" - "+\n" - "+static void __exit samsung_kp_exit(void)\n" - "+{\n" - "+\tplatform_driver_unregister(&samsung_kp_driver);\n" - "+}\n" - "+\n" - "+module_init(samsung_kp_init);\n" - "+module_exit(samsung_kp_exit);\n" - "+\n" - "+MODULE_DESCRIPTION(\"Samsung keypad driver\");\n" - "+MODULE_AUTHOR(\"Joonyoung Shim <jy0922.shim@samsung.com>\");\n" - "+MODULE_AUTHOR(\"Donghwa Lee <dh09.lee@samsung.com>\");\n" - "+MODULE_LICENSE(\"GPL\");\n" - "-- \n" - 1.7.0.4 + Please use following patch because of typo of prior patch. -5c07d86e633c75146199a25bb3c3bc5e3fb442c9cce20c28053ca29b4b683c3f +20b557039551e19179c7bb37b5ff77c0a86163f03b80ed7dab1a88f9b8934049
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.