From: Miguel Aguilar <[email protected]>

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 <[email protected]>
---
 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 --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;
-- 
1.6.0.4


_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to