diff mbox

[v2,1/2] Input: DaVinci Key Scan Driver

Message ID 1254434051-28772-1-git-send-email-miguel.aguilar@ridgerun.com (mailing list archive)
State Superseded
Headers show

Commit Message

miguel.aguilar@ridgerun.com Oct. 1, 2009, 9:54 p.m. UTC
From: Miguel Aguilar <miguel.aguilar@ridgerun.com>

Adds the driver for enabling key scan support for DaVinci platforms.

DM365 is the only platform that uses this driver at the moment.

Signed-off-by: Miguel Aguilar <miguel.aguilar@ridgerun.com>
---
 arch/arm/mach-davinci/include/mach/keyscan.h |   12 ++++-
 drivers/input/keyboard/Kconfig               |    2 +-
 drivers/input/keyboard/davinci_keyscan.c     |   52 +++++++++++++++++--------
 3 files changed, 45 insertions(+), 21 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/include/mach/keyscan.h b/arch/arm/mach-davinci/include/mach/keyscan.h
index 6d64198..d82ae17 100644
--- a/arch/arm/mach-davinci/include/mach/keyscan.h
+++ b/arch/arm/mach-davinci/include/mach/keyscan.h
@@ -23,12 +23,18 @@ 
 
 #include <linux/io.h>
 
+/* Base of key scan register bank */
+#define DM365_KEYSCAN_BASE		(0x01C69400)
+
 struct davinci_ks_platform_data {
 	unsigned short	*keymap;
 	u32		keymapsize;
-	u32		rep:1;
-	u32		strobe;
-	u32		interval;
+	u8		rows;
+	u8		cols;
+	u8		rep:1;
+	u8		strobe;
+	u8		interval;
+
 };
 
 #endif
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 72e560e..eca9e14 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -366,7 +366,7 @@  config KEYBOARD_DAVINCI
 	depends on ARCH_DAVINCI_DM365
 	help
 	  Say Y to enable keypad module support for the TI DaVinci
-	  platforms (DM365)
+	  platforms (DM365).
 	  
 	  To compile this driver as a module, choose M here: the
 	  module will be called davinci_keyscan.
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c
index 074cf81..9b153a9 100644
--- a/drivers/input/keyboard/davinci_keyscan.c
+++ b/drivers/input/keyboard/davinci_keyscan.c
@@ -57,7 +57,6 @@ 
 #define DAVINCI_KEYSCAN_AUTODET		0x00000008
 #define DAVINCI_KEYSCAN_SCANMODE	0x00000010
 #define DAVINCI_KEYSCAN_OUTTYPE		0x00000020
-#define DAVINCI_KEYSCAN_4X4		0x00000040
 
 /* Masks for the interrupts */
 #define DAVINCI_KEYSCAN_INT_CONT	0x00000008
@@ -91,10 +90,14 @@  static u32 davinci_ks_read(struct davinci_ks *davinci_ks, u32 addr)
 }
 
 /* Initializing the kp Module */
-static void davinci_ks_initialize(struct davinci_ks *davinci_ks)
+static int davinci_ks_initialize(struct davinci_ks *davinci_ks)
 {
-	u32 strobe = davinci_ks->pdata->strobe;
-	u32 interval = davinci_ks->pdata->interval;
+	struct device *dev = &davinci_ks->input->dev;
+	u8 strobe = davinci_ks->pdata->strobe;
+	u8 interval = davinci_ks->pdata->interval;
+	u8 rows = davinci_ks->pdata->rows;
+	u8 cols = davinci_ks->pdata->cols;
+	u8 matrix_type = 0;
 
 	/* Enable all interrupts */
 	davinci_ks_write(davinci_ks, DAVINCI_KEYSCAN_INT_ALL, DAVINCI_KEYSCAN_INTENA);
@@ -107,9 +110,21 @@  static void davinci_ks_initialize(struct davinci_ks *davinci_ks)
 	davinci_ks_write(davinci_ks, interval, DAVINCI_KEYSCAN_INTERVAL);
 	davinci_ks_write(davinci_ks, 0x01, DAVINCI_KEYSCAN_CONTTIME);
 
-	/* Enable Keyscan module and enable */
-	davinci_ks_write(davinci_ks, DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN,
-			DAVINCI_KEYSCAN_KEYCTRL);
+	/* Define matrix type */
+	if ((rows == 4) && (cols == 4))
+		matrix_type = 0;
+	else if ((rows == 3) && (cols == 5))
+		matrix_type = 1;
+	else {
+		dev_err(dev, "davinci_scan: wrong matrix dimension\n");
+		return -EINVAL;
+	}
+
+	/* Enable key scan module and set matrix type */
+	davinci_ks_write(davinci_ks, DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN
+			    | (matrix_type << 6), DAVINCI_KEYSCAN_KEYCTRL);
+
+	return 0;
 }
 
 static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id)
@@ -141,7 +156,7 @@  static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id)
 			if((changed>>i) & 0x1) {
 				keycode = keymap[i];
 				release = (new_status >> i) & 0x1;
-				dev_info(dev, "davinci_keyscan: key %d %s\n",
+				dev_dbg(dev, "davinci_keyscan: key %d %s\n",
 				    keycode, release ? "released" : "pressed");
 				input_report_key(davinci_ks->input, keycode,
 						    !release);
@@ -168,7 +183,10 @@  static int __init davinci_ks_probe(struct platform_device *pdev)
 	struct davinci_ks_platform_data *pdata = pdev->dev.platform_data;
 	int ret, i;
 
-	dev_info(dev, "DaVinci Key Scan Driver\n");
+	if (!pdata->keymap) {
+		dev_dbg(dev, "no keymap from pdata\n");
+		return -EINVAL;
+	}
 
 	davinci_ks = kzalloc(sizeof(struct davinci_ks) +
 		sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL);
@@ -177,11 +195,6 @@  static int __init davinci_ks_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	if (!pdata->keymap) {
-		dev_dbg(dev, "no keymap from pdata\n");
-		return -EINVAL;
-	}
-
 	memcpy(davinci_ks->keymap, pdata->keymap,
 		    sizeof(unsigned short) * pdata->keymapsize);
 
@@ -254,20 +267,25 @@  static int __init davinci_ks_probe(struct platform_device *pdev)
 
 	ret = input_register_device(davinci_ks->input);
 	if (ret < 0) {
-		dev_err(dev, "unable to register DaVinci keyscan device\n");
+		dev_err(dev, "unable to register davinci key scan device\n");
 		goto fail4;
 	}
 
 	ret = request_irq(davinci_ks->irq, davinci_ks_interrupt, IRQF_DISABLED,
                          "davinci_keyscan", davinci_ks);
 	if (ret < 0) {
-		dev_err(dev, "unable to register DaVinci keyscan Interrupt\n");
+		dev_err(dev, "unable to register davinci key scan interrupt\n");
 		goto fail5;
 	}
 
-	davinci_ks_initialize(davinci_ks);
+	ret = davinci_ks_initialize(davinci_ks);
+	if (ret < 0) {
+		dev_err(dev, "unable to initialize davinci key scan device\n");
+		goto fail5;
+	}
 
 	return 0;
+
 fail5:
 	input_unregister_device(davinci_ks->input);
 	key_dev = NULL;