From: Joonyoung Shim <jy0922.shim@samsung.com>
To: ben-linux@fluff.org
Cc: kyungmin.park@samsung.com, linux-samsung-soc@vger.kernel.org,
dmitry.torokhov@gmail.com, linux-arm-kernel@lists.infradead.org,
linux-input@vger.kernel.org
Subject: Re: [PATCH v2 5/5] input: samsung-keypad - Add samsung keypad driver
Date: Sun, 30 May 2010 12:42:28 +0900 [thread overview]
Message-ID: <4C01DEA4.1080704@samsung.com> (raw)
In-Reply-To: <1275188784-23395-5-git-send-email-jy0922.shim@samsung.com>
On 5/30/2010 12:06 PM, Joonyoung Shim wrote:
> 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
>
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
WARNING: multiple messages have this Message-ID (diff)
From: jy0922.shim@samsung.com (Joonyoung Shim)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 5/5] input: samsung-keypad - Add samsung keypad driver
Date: Sun, 30 May 2010 12:42:28 +0900 [thread overview]
Message-ID: <4C01DEA4.1080704@samsung.com> (raw)
In-Reply-To: <1275188784-23395-5-git-send-email-jy0922.shim@samsung.com>
On 5/30/2010 12:06 PM, Joonyoung Shim wrote:
> 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
>
Sorry for bothering.
Please use following patch because of typo of prior patch.
next prev parent reply other threads:[~2010-05-30 3:42 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-30 3:06 [PATCH v2 1/5] ARM: SAMSUNG: Add keypad device support Joonyoung Shim
2010-05-30 3:06 ` Joonyoung Shim
2010-05-30 3:06 ` [PATCH v2 2/5] ARM: S5PV210: Add keypad device helpers Joonyoung Shim
2010-05-30 3:06 ` Joonyoung Shim
2010-05-30 3:06 ` [PATCH v2 3/5] ARM: S5PV210: Add keypad device to the GONI board Joonyoung Shim
2010-05-30 3:06 ` Joonyoung Shim
2010-05-30 3:06 ` [PATCH v2 4/5] ARM: S5PV210: Add keypad device to the Aquila board Joonyoung Shim
2010-05-30 3:06 ` Joonyoung Shim
2010-05-30 3:06 ` [PATCH v2 5/5] input: samsung-keypad - Add samsung keypad driver Joonyoung Shim
2010-05-30 3:06 ` Joonyoung Shim
2010-05-30 3:39 ` Marek Vasut
2010-05-30 3:39 ` Marek Vasut
2010-05-30 3:44 ` Ben Dooks
2010-05-30 3:44 ` Ben Dooks
2010-05-30 3:42 ` Joonyoung Shim [this message]
2010-05-30 3:42 ` Joonyoung Shim
2010-05-30 3:42 ` Ben Dooks
2010-05-30 3:42 ` Ben Dooks
2010-05-30 4:35 ` Joonyoung Shim
2010-05-30 4:35 ` Joonyoung Shim
2010-06-03 1:00 ` Ben Dooks
2010-06-03 1:00 ` Ben Dooks
2010-06-03 4:47 ` Joonyoung Shim
2010-06-03 4:47 ` Joonyoung Shim
2010-06-07 7:30 ` Marek Szyprowski
2010-06-07 7:30 ` Marek Szyprowski
2010-05-30 3:42 ` [PATCH v2 1/5] ARM: SAMSUNG: Add keypad device support Marek Vasut
2010-05-30 3:42 ` Marek Vasut
2010-05-30 4:46 ` Jassi Brar
2010-05-30 4:46 ` Jassi Brar
2010-05-30 4:51 ` Ben Dooks
2010-05-30 4:51 ` Ben Dooks
2010-05-30 5:04 ` Jassi Brar
2010-05-30 5:04 ` Jassi Brar
2010-05-30 5:21 ` Ben Dooks
2010-05-30 5:21 ` Ben Dooks
2010-05-31 9:44 ` Mark Brown
2010-05-31 9:44 ` Mark Brown
2010-05-30 8:52 ` Dmitry Torokhov
2010-05-30 8:52 ` Dmitry Torokhov
2010-05-31 1:14 ` Joonyoung Shim
2010-05-31 1:14 ` Joonyoung Shim
2010-05-31 0:06 ` Kukjin Kim
2010-05-31 0:06 ` Kukjin Kim
2010-05-31 0:15 ` Marek Vasut
2010-05-31 0:15 ` Marek Vasut
2010-05-31 1:09 ` Joonyoung Shim
2010-05-31 1:09 ` Joonyoung Shim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C01DEA4.1080704@samsung.com \
--to=jy0922.shim@samsung.com \
--cc=ben-linux@fluff.org \
--cc=dmitry.torokhov@gmail.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.