@@ -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
@@ -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.
@@ -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;