linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
@ 2009-09-09 11:11 jsgood.yang
  2009-09-09 11:21 ` Kyungmin Park
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: jsgood.yang @ 2009-09-09 11:11 UTC (permalink / raw)
  To: dmitry.torokhov, ben-linux, linux-input, linux-arm-kernel
  Cc: Jinsung Yang, Kyeongil Kim

From: Jinsung Yang <jsgood.yang@samsung.com>

Add support for Samsung matrix keypad driver

Signed-off-by: Jinsung Yang <jsgood.yang@samsung.com>
Signed-off-by: Kyeongil Kim <ki0351.kim@samsung.com>
---
 drivers/input/keyboard/Kconfig      |    6 +
 drivers/input/keyboard/Makefile     |    1 +
 drivers/input/keyboard/s3c-keypad.c |  446 +++++++++++++++++++++++++++++++++++
 3 files changed, 453 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/keyboard/s3c-keypad.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index a6b989a..4a04553 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -361,4 +361,10 @@ config KEYBOARD_XTKBD
 	  To compile this driver as a module, choose M here: the
 	  module will be called xtkbd.
 
+config KEYBOARD_S3C
+	tristate "Samsung S3C keypad support"
+	depends on PLAT_S3C
+	help
+	  Enable support for Samsung S3C keypad interface.
+
 endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b5b5eae..21331b8 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
 obj-$(CONFIG_KEYBOARD_TOSA)		+= tosakbd.o
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
+obj-$(CONFIG_KEYBOARD_S3C)		+= s3c-keypad.o
diff --git a/drivers/input/keyboard/s3c-keypad.c b/drivers/input/keyboard/s3c-keypad.c
new file mode 100644
index 0000000..9436a4c
--- /dev/null
+++ b/drivers/input/keyboard/s3c-keypad.c
@@ -0,0 +1,446 @@
+/*
+ * linux/drivers/input/keyboard/s3c-keypad.c
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ *
+ * Author: Jinsung Yang <jsgood.yang@samsung.com>
+ * Author: Kyeongil Kim <ki0351.kim@samsung.com>
+ *
+ * Driver for Samsung SoC matrix keypad controller.
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/keypad.h>
+#include <plat/regs-keypad.h>
+
+#undef DEBUG
+
+#define S3C_KEYPAD_MAX_ROWS 16
+#define S3C_KEYPAD_MAX_COLS 8
+
+struct s3c_keypad {
+	struct s3c_platform_keypad *pdata;
+	unsigned short keycodes[S3C_KEYPAD_MAX_ROWS * S3C_KEYPAD_MAX_COLS];
+	struct input_dev *dev;
+	struct timer_list timer;
+	void __iomem *regs;
+	struct clk *clk;
+	int irq;
+	unsigned int prevmask_low;
+	unsigned int prevmask_high;
+	unsigned int keyifcon;
+	unsigned int keyiffc;
+};
+
+static int s3c_keypad_scan(struct s3c_keypad *keypad, u32 *keymask_low,
+				u32 *keymask_high)
+{
+	struct s3c_platform_keypad *pdata = keypad->pdata;
+	int i, j = 0;
+	u32 cval, rval, cfg;
+
+	for (i = 0; i < pdata->nr_cols; i++) {
+		cval = readl(keypad->regs + S3C_KEYIFCOL);
+		cval |= S3C_KEYIF_COL_DMASK;
+		cval &= ~(1 << i);
+		writel(cval, keypad->regs + S3C_KEYIFCOL);
+		udelay(pdata->delay);
+
+		rval = ~(readl(keypad->regs + S3C_KEYIFROW)) &
+			S3C_KEYIF_ROW_DMASK;
+
+		if ((i * pdata->nr_rows) < pdata->max_masks)
+			*keymask_low |= (rval << (i * pdata->nr_rows));
+		else {
+			*keymask_high |= (rval << (j * pdata->nr_rows));
+			j++;
+		}
+	}
+
+	cfg = readl(keypad->regs + S3C_KEYIFCOL);
+	cfg &= ~S3C_KEYIF_COL_MASK_ALL;
+	writel(cfg, keypad->regs + S3C_KEYIFCOL);
+
+	return 0;
+}
+
+static void s3c_keypad_timer_handler(unsigned long data)
+{
+	struct s3c_keypad *keypad = (struct s3c_keypad *)data;
+	struct s3c_platform_keypad *pdata = keypad->pdata;
+	struct input_dev *input = keypad->dev;
+	u32 keymask_low = 0, keymask_high = 0;
+	u32 press_mask_low, press_mask_high;
+	u32 release_mask_low, release_mask_high, code, cfg;
+	int i;
+
+	s3c_keypad_scan(keypad, &keymask_low, &keymask_high);
+
+	if (keymask_low != keypad->prevmask_low) {
+		press_mask_low = ((keymask_low ^ keypad->prevmask_low) &
+					keymask_low);
+		release_mask_low = ((keymask_low ^ keypad->prevmask_low) &
+					keypad->prevmask_low);
+
+		i = 0;
+		while (press_mask_low) {
+			if (press_mask_low & 1) {
+				code = keypad->keycodes[i];
+				input_report_key(input, code, 1);
+				dev_dbg(&input->dev, "low pressed: %d\n", i);
+			}
+			press_mask_low >>= 1;
+			i++;
+		}
+
+		i = 0;
+		while (release_mask_low) {
+			if (release_mask_low & 1) {
+				code = keypad->keycodes[i];
+				input_report_key(input, code, 0);
+				dev_dbg(&input->dev, "low released: %d\n", i);
+			}
+			release_mask_low >>= 1;
+			i++;
+		}
+		keypad->prevmask_low = keymask_low;
+	}
+
+	if (keymask_high != keypad->prevmask_high) {
+		press_mask_high = ((keymask_high ^ keypad->prevmask_high) &
+					keymask_high);
+		release_mask_high = ((keymask_high ^ keypad->prevmask_high) &
+					keypad->prevmask_high);
+
+		i = 0;
+		while (press_mask_high) {
+			if (press_mask_high & 1) {
+				code = keypad->keycodes[i + pdata->max_masks];
+				input_report_key(input, code, 1);
+				dev_dbg(&input->dev, "high pressed: %d %d\n",
+					keypad->keycodes[i + pdata->max_masks],
+					i);
+			}
+			press_mask_high >>= 1;
+			i++;
+		}
+
+		i = 0;
+		while (release_mask_high) {
+			if (release_mask_high & 1) {
+				code = keypad->keycodes[i + pdata->max_masks];
+				input_report_key(input, code, 0);
+				dev_dbg(&input->dev, "high released: %d\n",
+					keypad->keycodes[i + pdata->max_masks]);
+			}
+			release_mask_high >>= 1;
+			i++;
+		}
+		keypad->prevmask_high = keymask_high;
+	}
+
+	if (keymask_low | keymask_high) {
+		mod_timer(&keypad->timer, jiffies + HZ / 10);
+	} else {
+		cfg = readl(keypad->regs + S3C_KEYIFCON);
+		cfg &= ~S3C_KEYIF_CON_MASK_ALL;
+		cfg |= (S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN |
+				S3C_KEYIF_DF_EN | S3C_KEYIF_FC_EN);
+		writel(cfg, keypad->regs + S3C_KEYIFCON);
+	}
+}
+
+static irqreturn_t s3c_keypad_irq(int irq, void *dev_id)
+{
+	struct s3c_keypad *keypad = dev_id;
+	u32 cfg;
+
+	/* disable keypad interrupt and schedule for keypad timer handler */
+	cfg = readl(keypad->regs + S3C_KEYIFCON);
+	cfg &= ~(S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN);
+	writel(cfg, keypad->regs + S3C_KEYIFCON);
+
+	keypad->timer.expires = jiffies + (HZ / 100);
+	mod_timer(&keypad->timer, keypad->timer.expires);
+
+	/* clear the keypad interrupt status */
+	writel(S3C_KEYIF_STSCLR_CLEAR, keypad->regs + S3C_KEYIFSTSCLR);
+
+	return IRQ_HANDLED;
+}
+
+static int s3c_keypad_open(struct input_dev *dev)
+{
+	struct s3c_keypad *keypad = input_get_drvdata(dev);
+	u32 cfg;
+
+	clk_enable(keypad->clk);
+
+	/* init keypad h/w block */
+	cfg = readl(keypad->regs + S3C_KEYIFCON);
+	cfg &= ~S3C_KEYIF_CON_MASK_ALL;
+	cfg |= (S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN |
+			S3C_KEYIF_DF_EN | S3C_KEYIF_FC_EN);
+	writel(cfg, keypad->regs + S3C_KEYIFCON);
+
+	cfg = readl(keypad->regs + S3C_KEYIFFC);
+	cfg |= S3C_KEYIF_FILTER_VAL;
+	writel(cfg, keypad->regs + S3C_KEYIFFC);
+
+	cfg = readl(keypad->regs + S3C_KEYIFCOL);
+	cfg &= ~S3C_KEYIF_COL_MASK_ALL;
+	writel(cfg, keypad->regs + S3C_KEYIFCOL);
+
+	return 0;
+}
+
+static void s3c_keypad_close(struct input_dev *dev)
+{
+	struct s3c_keypad *keypad = input_get_drvdata(dev);
+
+	clk_disable(keypad->clk);
+}
+
+static int __devinit s3c_keypad_probe(struct platform_device *pdev)
+{
+	struct s3c_platform_keypad *pdata;
+	struct s3c_keypad *keypad;
+	struct input_dev *input;
+	struct resource *res;
+	int error = 0, irq, i;
+
+	pdata = pdev->dev.platform_data;
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -EINVAL;
+	}
+
+	keypad = kzalloc(sizeof(struct s3c_keypad), GFP_KERNEL);
+	if (keypad == NULL) {
+		dev_err(&pdev->dev, "failed to allocate driver data\n");
+		return -ENOMEM;
+	}
+
+	keypad->pdata = pdata;
+	if (!pdata->keymap) {
+		dev_err(&pdev->dev, "failed to get keymap array\n");
+		goto err_keymap;
+	}
+
+	memcpy(keypad->keycodes, pdata->keymap,
+			sizeof(pdata->keymap[0]) * pdata->max_keys);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to get I/O memory\n");
+		error = -ENXIO;
+		goto err_keymap;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request I/O memory\n");
+		error = -EBUSY;
+		goto err_keymap;
+	}
+
+	keypad->regs = ioremap(res->start, resource_size(res));
+	if (keypad->regs == NULL) {
+		dev_err(&pdev->dev, "failed to remap I/O memory\n");
+		error = -ENXIO;
+		goto err_map_io;
+	}
+
+	keypad->clk = clk_get(&pdev->dev, "keypad");
+	if (IS_ERR(keypad->clk)) {
+		dev_err(&pdev->dev, "failed to get keypad clock\n");
+		error = PTR_ERR(keypad->clk);
+		goto err_clk;
+	}
+
+	/* Create and register the input driver. */
+	input = input_allocate_device();
+	if (!input) {
+		dev_err(&pdev->dev, "failed to allocate input device\n");
+		error = -ENOMEM;
+		goto err_alloc_input;
+	}
+
+	input->name = pdev->name;
+	input->id.bustype = BUS_HOST;
+	input->open = s3c_keypad_open;
+	input->close = s3c_keypad_close;
+	input->dev.parent = &pdev->dev;
+	input->keycode = keypad->keycodes;
+	input->keycodesize = sizeof(keypad->keycodes[0]);
+	input->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+	keypad->dev = input;
+	input_set_drvdata(input, keypad);
+
+	__set_bit(EV_KEY, input->evbit);
+	__set_bit(EV_REP, input->evbit);
+
+	for (i = 0; i < pdata->max_keys; i++)
+		__set_bit(keypad->keycodes[i] & KEY_MAX, input->keybit);
+
+	__clear_bit(KEY_RESERVED, input->keybit);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get keypad irq\n");
+		error = -ENXIO;
+		goto err_get_irq;
+	}
+
+	platform_set_drvdata(pdev, keypad);
+
+	error = request_irq(irq, s3c_keypad_irq, IRQF_DISABLED,
+			    pdev->name, keypad);
+	if (error) {
+		dev_err(&pdev->dev, "failed to request IRQ\n");
+		goto err_req_irq;
+	}
+
+	keypad->irq = irq;
+	setup_timer(&keypad->timer, s3c_keypad_timer_handler,
+			(unsigned long)keypad);
+
+	/* Register the input device */
+	error = input_register_device(input);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		goto err_reg_input;
+	}
+
+	device_init_wakeup(&pdev->dev, 1);
+	dev_info(&pdev->dev, "Samsung Keypad Interface driver loaded\n");
+
+	return 0;
+
+err_reg_input:
+	free_irq(irq, pdev);
+
+err_req_irq:
+	platform_set_drvdata(pdev, NULL);
+
+err_get_irq:
+	input_free_device(input);
+
+err_alloc_input:
+	clk_put(keypad->clk);
+
+err_clk:
+	iounmap(keypad->regs);
+
+err_map_io:
+	release_mem_region(res->start, resource_size(res));
+
+err_keymap:
+	kfree(keypad);
+
+	return error;
+}
+
+static int __devexit s3c_keypad_remove(struct platform_device *pdev)
+{
+	struct s3c_keypad *keypad = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	free_irq(keypad->irq, pdev);
+	clk_put(keypad->clk);
+
+	input_unregister_device(keypad->dev);
+	iounmap(keypad->regs);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(keypad);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_keypad_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct s3c_keypad *keypad = platform_get_drvdata(pdev);
+
+	keypad->keyifcon = readl(keypad->regs + S3C_KEYIFCON);
+	keypad->keyiffc = readl(keypad->regs + S3C_KEYIFFC);
+
+	disable_irq(IRQ_KEYPAD);
+	clk_disable(keypad->clk);
+
+	return 0;
+}
+
+static int s3c_keypad_resume(struct platform_device *dev)
+{
+	struct s3c_keypad *keypad = platform_get_drvdata(pdev);
+
+	clk_enable(keypad->clock);
+
+	writel(keypad->keyifcon, keypad->regs + S3C_KEYIFCON);
+	writel(keypad->keyiffc, keypad->regs + S3C_KEYIFFC);
+
+	enable_irq(IRQ_KEYPAD);
+
+	return 0;
+}
+#else
+#define s3c_keypad_suspend NULL
+#define s3c_keypad_resume  NULL
+#endif /* CONFIG_PM */
+
+static struct dev_pm_ops s3c_keypad_dev_pm_ops = {
+	.suspend	= s3c_keypad_suspend,
+	.resume		= s3c_keypad_resume,
+};
+
+static struct platform_driver s3c_keypad_driver = {
+	.probe		= s3c_keypad_probe,
+	.remove		= s3c_keypad_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "s3c-keypad",
+		.pm	= &s3c_keypad_dev_pm_ops,
+	},
+};
+
+static int __init s3c_keypad_init(void)
+{
+	return platform_driver_register(&s3c_keypad_driver);
+}
+
+static void __exit s3c_keypad_exit(void)
+{
+	platform_driver_unregister(&s3c_keypad_driver);
+}
+
+module_init(s3c_keypad_init);
+module_exit(s3c_keypad_exit);
+
+MODULE_AUTHOR("Kyeongil, Kim <ki0351.kim@samsung.com>");
+MODULE_AUTHOR("Jinsung, Yang <jsgood.yang@samsung.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Keypad Interface Driver for Samsung SoC");
+
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
  2009-09-09 11:11 [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support jsgood.yang
@ 2009-09-09 11:21 ` Kyungmin Park
  2009-09-09 11:31   ` Jinsung Yang
  2009-09-09 11:52 ` Mark Brown
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Kyungmin Park @ 2009-09-09 11:21 UTC (permalink / raw)
  To: jsgood.yang
  Cc: dmitry.torokhov, ben-linux, linux-input, linux-arm-kernel,
	Kyeongil Kim

Hi,

Simple typo at CONFIG_PM parameters. see below

Thank you,
Kyungmin Park

On Wed, Sep 9, 2009 at 8:11 PM,  <jsgood.yang@samsung.com> wrote:
> From: Jinsung Yang <jsgood.yang@samsung.com>
>
> Add support for Samsung matrix keypad driver
>
> Signed-off-by: Jinsung Yang <jsgood.yang@samsung.com>
> Signed-off-by: Kyeongil Kim <ki0351.kim@samsung.com>
> ---
>  drivers/input/keyboard/Kconfig      |    6 +
>  drivers/input/keyboard/Makefile     |    1 +
>  drivers/input/keyboard/s3c-keypad.c |  446 +++++++++++++++++++++++++++++++++++
>  3 files changed, 453 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/input/keyboard/s3c-keypad.c
>
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index a6b989a..4a04553 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -361,4 +361,10 @@ config KEYBOARD_XTKBD
>          To compile this driver as a module, choose M here: the
>          module will be called xtkbd.
>
> +config KEYBOARD_S3C
> +       tristate "Samsung S3C keypad support"
> +       depends on PLAT_S3C
> +       help
> +         Enable support for Samsung S3C keypad interface.
> +
>  endif
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index b5b5eae..21331b8 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_KEYBOARD_STOWAWAY)               += stowaway.o
>  obj-$(CONFIG_KEYBOARD_SUNKBD)          += sunkbd.o
>  obj-$(CONFIG_KEYBOARD_TOSA)            += tosakbd.o
>  obj-$(CONFIG_KEYBOARD_XTKBD)           += xtkbd.o
> +obj-$(CONFIG_KEYBOARD_S3C)             += s3c-keypad.o
> diff --git a/drivers/input/keyboard/s3c-keypad.c b/drivers/input/keyboard/s3c-keypad.c
> new file mode 100644
> index 0000000..9436a4c
> --- /dev/null
> +++ b/drivers/input/keyboard/s3c-keypad.c
> @@ -0,0 +1,446 @@
> +/*
> + * linux/drivers/input/keyboard/s3c-keypad.c
> + *
> + * Copyright (C) 2009 Samsung Electronics
> + *
> + * Author: Jinsung Yang <jsgood.yang@samsung.com>
> + * Author: Kyeongil Kim <ki0351.kim@samsung.com>
> + *
> + * Driver for Samsung SoC matrix keypad controller.
> + *
> + * 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/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/input.h>
> +#include <linux/platform_device.h>
> +#include <linux/miscdevice.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +
> +#include <mach/hardware.h>
> +#include <asm/irq.h>
> +
> +#include <plat/keypad.h>
> +#include <plat/regs-keypad.h>
> +
> +#undef DEBUG
> +
> +#define S3C_KEYPAD_MAX_ROWS 16
> +#define S3C_KEYPAD_MAX_COLS 8
> +
> +struct s3c_keypad {
> +       struct s3c_platform_keypad *pdata;
> +       unsigned short keycodes[S3C_KEYPAD_MAX_ROWS * S3C_KEYPAD_MAX_COLS];
> +       struct input_dev *dev;
> +       struct timer_list timer;
> +       void __iomem *regs;
> +       struct clk *clk;
> +       int irq;
> +       unsigned int prevmask_low;
> +       unsigned int prevmask_high;
> +       unsigned int keyifcon;
> +       unsigned int keyiffc;
> +};
> +
> +static int s3c_keypad_scan(struct s3c_keypad *keypad, u32 *keymask_low,
> +                               u32 *keymask_high)
> +{
> +       struct s3c_platform_keypad *pdata = keypad->pdata;
> +       int i, j = 0;
> +       u32 cval, rval, cfg;
> +
> +       for (i = 0; i < pdata->nr_cols; i++) {
> +               cval = readl(keypad->regs + S3C_KEYIFCOL);
> +               cval |= S3C_KEYIF_COL_DMASK;
> +               cval &= ~(1 << i);
> +               writel(cval, keypad->regs + S3C_KEYIFCOL);
> +               udelay(pdata->delay);
> +
> +               rval = ~(readl(keypad->regs + S3C_KEYIFROW)) &
> +                       S3C_KEYIF_ROW_DMASK;
> +
> +               if ((i * pdata->nr_rows) < pdata->max_masks)
> +                       *keymask_low |= (rval << (i * pdata->nr_rows));
> +               else {
> +                       *keymask_high |= (rval << (j * pdata->nr_rows));
> +                       j++;
> +               }
> +       }
> +
> +       cfg = readl(keypad->regs + S3C_KEYIFCOL);
> +       cfg &= ~S3C_KEYIF_COL_MASK_ALL;
> +       writel(cfg, keypad->regs + S3C_KEYIFCOL);
> +
> +       return 0;
> +}
> +
> +static void s3c_keypad_timer_handler(unsigned long data)
> +{
> +       struct s3c_keypad *keypad = (struct s3c_keypad *)data;
> +       struct s3c_platform_keypad *pdata = keypad->pdata;
> +       struct input_dev *input = keypad->dev;
> +       u32 keymask_low = 0, keymask_high = 0;
> +       u32 press_mask_low, press_mask_high;
> +       u32 release_mask_low, release_mask_high, code, cfg;
> +       int i;
> +
> +       s3c_keypad_scan(keypad, &keymask_low, &keymask_high);
> +
> +       if (keymask_low != keypad->prevmask_low) {
> +               press_mask_low = ((keymask_low ^ keypad->prevmask_low) &
> +                                       keymask_low);
> +               release_mask_low = ((keymask_low ^ keypad->prevmask_low) &
> +                                       keypad->prevmask_low);
> +
> +               i = 0;
> +               while (press_mask_low) {
> +                       if (press_mask_low & 1) {
> +                               code = keypad->keycodes[i];
> +                               input_report_key(input, code, 1);
> +                               dev_dbg(&input->dev, "low pressed: %d\n", i);
> +                       }
> +                       press_mask_low >>= 1;
> +                       i++;
> +               }
> +
> +               i = 0;
> +               while (release_mask_low) {
> +                       if (release_mask_low & 1) {
> +                               code = keypad->keycodes[i];
> +                               input_report_key(input, code, 0);
> +                               dev_dbg(&input->dev, "low released: %d\n", i);
> +                       }
> +                       release_mask_low >>= 1;
> +                       i++;
> +               }
> +               keypad->prevmask_low = keymask_low;
> +       }
> +
> +       if (keymask_high != keypad->prevmask_high) {
> +               press_mask_high = ((keymask_high ^ keypad->prevmask_high) &
> +                                       keymask_high);
> +               release_mask_high = ((keymask_high ^ keypad->prevmask_high) &
> +                                       keypad->prevmask_high);
> +
> +               i = 0;
> +               while (press_mask_high) {
> +                       if (press_mask_high & 1) {
> +                               code = keypad->keycodes[i + pdata->max_masks];
> +                               input_report_key(input, code, 1);
> +                               dev_dbg(&input->dev, "high pressed: %d %d\n",
> +                                       keypad->keycodes[i + pdata->max_masks],
> +                                       i);
> +                       }
> +                       press_mask_high >>= 1;
> +                       i++;
> +               }
> +
> +               i = 0;
> +               while (release_mask_high) {
> +                       if (release_mask_high & 1) {
> +                               code = keypad->keycodes[i + pdata->max_masks];
> +                               input_report_key(input, code, 0);
> +                               dev_dbg(&input->dev, "high released: %d\n",
> +                                       keypad->keycodes[i + pdata->max_masks]);
> +                       }
> +                       release_mask_high >>= 1;
> +                       i++;
> +               }
> +               keypad->prevmask_high = keymask_high;
> +       }
> +
> +       if (keymask_low | keymask_high) {
> +               mod_timer(&keypad->timer, jiffies + HZ / 10);
> +       } else {
> +               cfg = readl(keypad->regs + S3C_KEYIFCON);
> +               cfg &= ~S3C_KEYIF_CON_MASK_ALL;
> +               cfg |= (S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN |
> +                               S3C_KEYIF_DF_EN | S3C_KEYIF_FC_EN);
> +               writel(cfg, keypad->regs + S3C_KEYIFCON);
> +       }
> +}
> +
> +static irqreturn_t s3c_keypad_irq(int irq, void *dev_id)
> +{
> +       struct s3c_keypad *keypad = dev_id;
> +       u32 cfg;
> +
> +       /* disable keypad interrupt and schedule for keypad timer handler */
> +       cfg = readl(keypad->regs + S3C_KEYIFCON);
> +       cfg &= ~(S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN);
> +       writel(cfg, keypad->regs + S3C_KEYIFCON);
> +
> +       keypad->timer.expires = jiffies + (HZ / 100);
> +       mod_timer(&keypad->timer, keypad->timer.expires);
> +
> +       /* clear the keypad interrupt status */
> +       writel(S3C_KEYIF_STSCLR_CLEAR, keypad->regs + S3C_KEYIFSTSCLR);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int s3c_keypad_open(struct input_dev *dev)
> +{
> +       struct s3c_keypad *keypad = input_get_drvdata(dev);
> +       u32 cfg;
> +
> +       clk_enable(keypad->clk);
> +
> +       /* init keypad h/w block */
> +       cfg = readl(keypad->regs + S3C_KEYIFCON);
> +       cfg &= ~S3C_KEYIF_CON_MASK_ALL;
> +       cfg |= (S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN |
> +                       S3C_KEYIF_DF_EN | S3C_KEYIF_FC_EN);
> +       writel(cfg, keypad->regs + S3C_KEYIFCON);
> +
> +       cfg = readl(keypad->regs + S3C_KEYIFFC);
> +       cfg |= S3C_KEYIF_FILTER_VAL;
> +       writel(cfg, keypad->regs + S3C_KEYIFFC);
> +
> +       cfg = readl(keypad->regs + S3C_KEYIFCOL);
> +       cfg &= ~S3C_KEYIF_COL_MASK_ALL;
> +       writel(cfg, keypad->regs + S3C_KEYIFCOL);
> +
> +       return 0;
> +}
> +
> +static void s3c_keypad_close(struct input_dev *dev)
> +{
> +       struct s3c_keypad *keypad = input_get_drvdata(dev);
> +
> +       clk_disable(keypad->clk);
> +}
> +
> +static int __devinit s3c_keypad_probe(struct platform_device *pdev)
> +{
> +       struct s3c_platform_keypad *pdata;
> +       struct s3c_keypad *keypad;
> +       struct input_dev *input;
> +       struct resource *res;
> +       int error = 0, irq, i;
> +
> +       pdata = pdev->dev.platform_data;
> +       if (pdata == NULL) {
> +               dev_err(&pdev->dev, "no platform data\n");
> +               return -EINVAL;
> +       }
> +
> +       keypad = kzalloc(sizeof(struct s3c_keypad), GFP_KERNEL);
> +       if (keypad == NULL) {
> +               dev_err(&pdev->dev, "failed to allocate driver data\n");
> +               return -ENOMEM;
> +       }
> +
> +       keypad->pdata = pdata;
> +       if (!pdata->keymap) {
> +               dev_err(&pdev->dev, "failed to get keymap array\n");
> +               goto err_keymap;
> +       }
> +
> +       memcpy(keypad->keycodes, pdata->keymap,
> +                       sizeof(pdata->keymap[0]) * pdata->max_keys);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (res == NULL) {
> +               dev_err(&pdev->dev, "failed to get I/O memory\n");
> +               error = -ENXIO;
> +               goto err_keymap;
> +       }
> +
> +       res = request_mem_region(res->start, resource_size(res), pdev->name);
> +       if (res == NULL) {
> +               dev_err(&pdev->dev, "failed to request I/O memory\n");
> +               error = -EBUSY;
> +               goto err_keymap;
> +       }
> +
> +       keypad->regs = ioremap(res->start, resource_size(res));
> +       if (keypad->regs == NULL) {
> +               dev_err(&pdev->dev, "failed to remap I/O memory\n");
> +               error = -ENXIO;
> +               goto err_map_io;
> +       }
> +
> +       keypad->clk = clk_get(&pdev->dev, "keypad");
> +       if (IS_ERR(keypad->clk)) {
> +               dev_err(&pdev->dev, "failed to get keypad clock\n");
> +               error = PTR_ERR(keypad->clk);
> +               goto err_clk;
> +       }
> +
> +       /* Create and register the input driver. */
> +       input = input_allocate_device();
> +       if (!input) {
> +               dev_err(&pdev->dev, "failed to allocate input device\n");
> +               error = -ENOMEM;
> +               goto err_alloc_input;
> +       }
> +
> +       input->name = pdev->name;
> +       input->id.bustype = BUS_HOST;
> +       input->open = s3c_keypad_open;
> +       input->close = s3c_keypad_close;
> +       input->dev.parent = &pdev->dev;
> +       input->keycode = keypad->keycodes;
> +       input->keycodesize = sizeof(keypad->keycodes[0]);
> +       input->keycodemax = ARRAY_SIZE(keypad->keycodes);
> +
> +       keypad->dev = input;
> +       input_set_drvdata(input, keypad);
> +
> +       __set_bit(EV_KEY, input->evbit);
> +       __set_bit(EV_REP, input->evbit);
> +
> +       for (i = 0; i < pdata->max_keys; i++)
> +               __set_bit(keypad->keycodes[i] & KEY_MAX, input->keybit);
> +
> +       __clear_bit(KEY_RESERVED, input->keybit);
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0) {
> +               dev_err(&pdev->dev, "failed to get keypad irq\n");
> +               error = -ENXIO;
> +               goto err_get_irq;
> +       }
> +
> +       platform_set_drvdata(pdev, keypad);
> +
> +       error = request_irq(irq, s3c_keypad_irq, IRQF_DISABLED,
> +                           pdev->name, keypad);
> +       if (error) {
> +               dev_err(&pdev->dev, "failed to request IRQ\n");
> +               goto err_req_irq;
> +       }
> +
> +       keypad->irq = irq;
> +       setup_timer(&keypad->timer, s3c_keypad_timer_handler,
> +                       (unsigned long)keypad);
> +
> +       /* Register the input device */
> +       error = input_register_device(input);
> +       if (error) {
> +               dev_err(&pdev->dev, "failed to register input device\n");
> +               goto err_reg_input;
> +       }
> +
> +       device_init_wakeup(&pdev->dev, 1);
> +       dev_info(&pdev->dev, "Samsung Keypad Interface driver loaded\n");
> +
> +       return 0;
> +
> +err_reg_input:
> +       free_irq(irq, pdev);
> +
> +err_req_irq:
> +       platform_set_drvdata(pdev, NULL);
> +
> +err_get_irq:
> +       input_free_device(input);
> +
> +err_alloc_input:
> +       clk_put(keypad->clk);
> +
> +err_clk:
> +       iounmap(keypad->regs);
> +
> +err_map_io:
> +       release_mem_region(res->start, resource_size(res));
> +
> +err_keymap:
> +       kfree(keypad);
> +
> +       return error;
> +}
> +
> +static int __devexit s3c_keypad_remove(struct platform_device *pdev)
> +{
> +       struct s3c_keypad *keypad = platform_get_drvdata(pdev);
> +       struct resource *res;
> +
> +       free_irq(keypad->irq, pdev);
> +       clk_put(keypad->clk);
> +
> +       input_unregister_device(keypad->dev);
> +       iounmap(keypad->regs);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       release_mem_region(res->start, resource_size(res));
> +
> +       platform_set_drvdata(pdev, NULL);
> +       kfree(keypad);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int s3c_keypad_suspend(struct platform_device *dev, pm_message_t state)
> +{
> +       struct s3c_keypad *keypad = platform_get_drvdata(pdev);
> +
> +       keypad->keyifcon = readl(keypad->regs + S3C_KEYIFCON);
> +       keypad->keyiffc = readl(keypad->regs + S3C_KEYIFFC);
> +
> +       disable_irq(IRQ_KEYPAD);
> +       clk_disable(keypad->clk);
> +
> +       return 0;
> +}
> +
> +static int s3c_keypad_resume(struct platform_device *dev)
> +{
> +       struct s3c_keypad *keypad = platform_get_drvdata(pdev);

Where's pdev? maybe you should use 'pdev' instead of 'dev' at parameter.

> +
> +       clk_enable(keypad->clock);
> +
> +       writel(keypad->keyifcon, keypad->regs + S3C_KEYIFCON);
> +       writel(keypad->keyiffc, keypad->regs + S3C_KEYIFFC);
> +
> +       enable_irq(IRQ_KEYPAD);
> +
> +       return 0;
> +}
> +#else
> +#define s3c_keypad_suspend NULL
> +#define s3c_keypad_resume  NULL
> +#endif /* CONFIG_PM */
> +
> +static struct dev_pm_ops s3c_keypad_dev_pm_ops = {
> +       .suspend        = s3c_keypad_suspend,
> +       .resume         = s3c_keypad_resume,
> +};
> +
> +static struct platform_driver s3c_keypad_driver = {
> +       .probe          = s3c_keypad_probe,
> +       .remove         = s3c_keypad_remove,
> +       .driver         = {
> +               .owner  = THIS_MODULE,
> +               .name   = "s3c-keypad",
> +               .pm     = &s3c_keypad_dev_pm_ops,
> +       },
> +};
> +
> +static int __init s3c_keypad_init(void)
> +{
> +       return platform_driver_register(&s3c_keypad_driver);
> +}
> +
> +static void __exit s3c_keypad_exit(void)
> +{
> +       platform_driver_unregister(&s3c_keypad_driver);
> +}
> +
> +module_init(s3c_keypad_init);
> +module_exit(s3c_keypad_exit);
> +
> +MODULE_AUTHOR("Kyeongil, Kim <ki0351.kim@samsung.com>");
> +MODULE_AUTHOR("Jinsung, Yang <jsgood.yang@samsung.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("Keypad Interface Driver for Samsung SoC");
> +
> --
> 1.6.2.5
>
> --
> 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
>
--
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	[flat|nested] 7+ messages in thread

* RE: [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
  2009-09-09 11:21 ` Kyungmin Park
@ 2009-09-09 11:31   ` Jinsung Yang
  0 siblings, 0 replies; 7+ messages in thread
From: Jinsung Yang @ 2009-09-09 11:31 UTC (permalink / raw)
  To: 'Kyungmin Park'
  Cc: dmitry.torokhov, ben-linux, linux-input, linux-arm-kernel,
	'Kyeongil Kim'

> Simple typo at CONFIG_PM parameters. see below

Hi,
Thank you Kyungmin Park,
I will send again with fix my simple typo.

Best Regards
--
Jinsung, Yang <jsgood.yang@samsung.com>
AP Development Team
System LSI, Semiconductor Business
SAMSUNG Electronics Co., LTD



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
  2009-09-09 11:11 [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support jsgood.yang
  2009-09-09 11:21 ` Kyungmin Park
@ 2009-09-09 11:52 ` Mark Brown
  2009-09-14  5:22 ` Jae hoon Chung
  2009-09-26  9:54 ` Pavel Machek
  3 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2009-09-09 11:52 UTC (permalink / raw)
  To: jsgood.yang
  Cc: dmitry.torokhov, ben-linux, linux-input, linux-arm-kernel,
	Kyeongil Kim

On Wed, Sep 09, 2009 at 08:11:03PM +0900, jsgood.yang@samsung.com wrote:

> +#ifdef CONFIG_PM
> +static int s3c_keypad_suspend(struct platform_device *dev, pm_message_t state)
> +{
> +	struct s3c_keypad *keypad = platform_get_drvdata(pdev);
> +
> +	keypad->keyifcon = readl(keypad->regs + S3C_KEYIFCON);
> +	keypad->keyiffc = readl(keypad->regs + S3C_KEYIFFC);
> +
> +	disable_irq(IRQ_KEYPAD);
> +	clk_disable(keypad->clk);
> +
> +	return 0;
> +}

This will unconditionally enable the clock but the clock is only enabled
while the input device is opened.  This may create confusion or generate
warnings with the clock API so it'd be better to avoid doing this.

A similar problem exists in the resume function.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
  2009-09-09 11:11 [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support jsgood.yang
  2009-09-09 11:21 ` Kyungmin Park
  2009-09-09 11:52 ` Mark Brown
@ 2009-09-14  5:22 ` Jae hoon Chung
  2009-09-26  9:54 ` Pavel Machek
  3 siblings, 0 replies; 7+ messages in thread
From: Jae hoon Chung @ 2009-09-14  5:22 UTC (permalink / raw)
  To: jsgood.yang
  Cc: dmitry.torokhov, ben-linux, linux-input, linux-arm-kernel,
	Kyeongil Kim

Hi...

I have some question to you.

> +static int s3c_keypad_scan(struct s3c_keypad *keypad, u32 *keymask_low,
> +                               u32 *keymask_high)
> +{
> +       struct s3c_platform_keypad *pdata = keypad->pdata;
> +       int i, j = 0;
> +       u32 cval, rval, cfg;
> +
> +       for (i = 0; i < pdata->nr_cols; i++) {
> +               cval = readl(keypad->regs + S3C_KEYIFCOL);
> +               cval |= S3C_KEYIF_COL_DMASK;
> +               cval &= ~(1 << i);
> +               writel(cval, keypad->regs + S3C_KEYIFCOL);
> +               udelay(pdata->delay);
> +
> +               rval = ~(readl(keypad->regs + S3C_KEYIFROW)) &
> +                       S3C_KEYIF_ROW_DMASK;
> +
> +               if ((i * pdata->nr_rows) < pdata->max_masks)
> +                       *keymask_low |= (rval << (i * pdata->nr_rows));
> +               else {
> +                       *keymask_high |= (rval << (j * pdata->nr_rows));
> +                       j++;
> +               }
> +       }
> +
> +       cfg = readl(keypad->regs + S3C_KEYIFCOL);
> +       cfg &= ~S3C_KEYIF_COL_MASK_ALL;
> +       writel(cfg, keypad->regs + S3C_KEYIFCOL);
> +
> +       return 0;
> +}
> +
> +static void s3c_keypad_timer_handler(unsigned long data)
> +{
> +       struct s3c_keypad *keypad = (struct s3c_keypad *)data;
> +       struct s3c_platform_keypad *pdata = keypad->pdata;
> +       struct input_dev *input = keypad->dev;
> +       u32 keymask_low = 0, keymask_high = 0;
> +       u32 press_mask_low, press_mask_high;
> +       u32 release_mask_low, release_mask_high, code, cfg;
> +       int i;
> +
> +       s3c_keypad_scan(keypad, &keymask_low, &keymask_high);
> +
> +       if (keymask_low != keypad->prevmask_low) {
> +               press_mask_low = ((keymask_low ^ keypad->prevmask_low) &
> +                                       keymask_low);
> +               release_mask_low = ((keymask_low ^ keypad->prevmask_low) &
> +                                       keypad->prevmask_low);
> +
> +               i = 0;
> +               while (press_mask_low) {
> +                       if (press_mask_low & 1) {
> +                               code = keypad->keycodes[i];
> +                               input_report_key(input, code, 1);
> +                               dev_dbg(&input->dev, "low pressed: %d\n", i);
> +                       }
> +                       press_mask_low >>= 1;
> +                       i++;
> +               }
> +
> +               i = 0;
> +               while (release_mask_low) {
> +                       if (release_mask_low & 1) {
> +                               code = keypad->keycodes[i];
> +                               input_report_key(input, code, 0);
> +                               dev_dbg(&input->dev, "low released: %d\n", i);
> +                       }
> +                       release_mask_low >>= 1;
> +                       i++;
> +               }
> +               keypad->prevmask_low = keymask_low;
> +       }
> +
> +       if (keymask_high != keypad->prevmask_high) {
> +               press_mask_high = ((keymask_high ^ keypad->prevmask_high) &
> +                                       keymask_high);
> +               release_mask_high = ((keymask_high ^ keypad->prevmask_high) &
> +                                       keypad->prevmask_high);
> +
> +               i = 0;
> +               while (press_mask_high) {
> +                       if (press_mask_high & 1) {
> +                               code = keypad->keycodes[i + pdata->max_masks];
> +                               input_report_key(input, code, 1);
> +                               dev_dbg(&input->dev, "high pressed: %d %d\n",
> +                                       keypad->keycodes[i + pdata->max_masks],
> +                                       i);
> +                       }
> +                       press_mask_high >>= 1;
> +                       i++;
> +               }
> +
> +               i = 0;
> +               while (release_mask_high) {
> +                       if (release_mask_high & 1) {
> +                               code = keypad->keycodes[i + pdata->max_masks];
> +                               input_report_key(input, code, 0);
> +                               dev_dbg(&input->dev, "high released: %d\n",
> +                                       keypad->keycodes[i + pdata->max_masks]);
> +                       }
> +                       release_mask_high >>= 1;
> +                       i++;
> +               }
> +               keypad->prevmask_high = keymask_high;
> +       }
> +
> +       if (keymask_low | keymask_high) {
> +               mod_timer(&keypad->timer, jiffies + HZ / 10);
> +       } else {
> +               cfg = readl(keypad->regs + S3C_KEYIFCON);
> +               cfg &= ~S3C_KEYIF_CON_MASK_ALL;
> +               cfg |= (S3C_KEYIF_INT_F_EN | S3C_KEYIF_INT_R_EN |
> +                               S3C_KEYIF_DF_EN | S3C_KEYIF_FC_EN);
> +               writel(cfg, keypad->regs + S3C_KEYIFCON);
> +       }
> +}

> 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
>


I understood  your code that used the keymask_low & keymask_high.
why did you use to distinguish  a keymask_low & keymask_high?
In your code, that variable saved all value of row_val , then you are
searching the value of pressed row_val...
i think it is unnecessary.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
  2009-09-09 11:11 [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support jsgood.yang
                   ` (2 preceding siblings ...)
  2009-09-14  5:22 ` Jae hoon Chung
@ 2009-09-26  9:54 ` Pavel Machek
  2009-09-26 17:21   ` Trilok Soni
  3 siblings, 1 reply; 7+ messages in thread
From: Pavel Machek @ 2009-09-26  9:54 UTC (permalink / raw)
  To: jsgood.yang
  Cc: dmitry.torokhov, ben-linux, linux-input, linux-arm-kernel,
	Kyeongil Kim

On Wed 2009-09-09 20:11:03, jsgood.yang@samsung.com wrote:
> From: Jinsung Yang <jsgood.yang@samsung.com>
> 
> Add support for Samsung matrix keypad driver

Could generic matrix keyboard driver be used instead?
							Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support
  2009-09-26  9:54 ` Pavel Machek
@ 2009-09-26 17:21   ` Trilok Soni
  0 siblings, 0 replies; 7+ messages in thread
From: Trilok Soni @ 2009-09-26 17:21 UTC (permalink / raw)
  To: Pavel Machek
  Cc: jsgood.yang, Kyeongil Kim, dmitry.torokhov, linux-arm-kernel,
	ben-linux, linux-input

Hi Pavel,

On Sat, Sep 26, 2009 at 3:24 PM, Pavel Machek <pavel@ucw.cz> wrote:
> On Wed 2009-09-09 20:11:03, jsgood.yang@samsung.com wrote:
>> From: Jinsung Yang <jsgood.yang@samsung.com>
>>
>> Add support for Samsung matrix keypad driver
>
> Could generic matrix keyboard driver be used instead?
>                                                        Pavel

Just looking at initial lines of code of this driver, matrix gpio
keypad driver doesn't fit the need, because this driver is based on
keypad controller on SoC and not through gpios.

-- 
---Trilok Soni
http://triloksoni.wordpress.com
http://www.linkedin.com/in/triloksoni
--
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	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-09-26 17:21 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-09 11:11 [PATCH 1/4] [INPUT][KEYBOARD] Samsung keypad driver support jsgood.yang
2009-09-09 11:21 ` Kyungmin Park
2009-09-09 11:31   ` Jinsung Yang
2009-09-09 11:52 ` Mark Brown
2009-09-14  5:22 ` Jae hoon Chung
2009-09-26  9:54 ` Pavel Machek
2009-09-26 17:21   ` Trilok Soni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).