Re: [PATCH] input: add support for generic GPIO-based matrix keypad

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>> Did you tried assigning max_keypmap_size in platform data to
>>> MATRIX_MAX_COLS * MATRIX_MAX_ROWS ?
>>>
>> Yes, this fixes crashes. But this is just workaround for bug in driver.
>>
> 
> As you have access to h/w, care to submit a patch which fixes this?
> 

Dmitry & Trilok,

How about this?  Due to the fact that we are not able to sort out the
proper solution for a dynamic maximum of columns/rows, let's simplify
the fix to the patch below:


>From 61ea1bd16a3636f526fb12619e84a75fa16b7f38 Mon Sep 17 00:00:00 2001
From: Eric Miao <eric.y.miao@xxxxxxxxx>
Date: Mon, 20 Jul 2009 11:31:08 +0800
Subject: [PATCH] input: matrix keymap size fixed to maximum

Introduced KEY_IDX(), merged keymap_data into 'matrix_keypad_platform_data'.

Signed-off-by: Eric Miao <eric.y.miao@xxxxxxxxx>
---
 drivers/input/keyboard/matrix_keypad.c |   22 ++++++----------------
 include/linux/input/matrix_keypad.h    |   21 +++++----------------
 2 files changed, 11 insertions(+), 32 deletions(-)

diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index e9b2e7c..a0ba134 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -136,7 +136,7 @@ static void matrix_keypad_scan(struct work_struct *work)
 			if ((bits_changed & (1 << row)) == 0)
 				continue;
 
-			code = (row << 4) + col;
+			code = KEY_IDX(row, col);
 			input_event(input_dev, EV_MSC, MSC_SCAN, code);
 			input_report_key(input_dev,
 					 keypad->keycodes[code],
@@ -313,7 +313,6 @@ err_free_cols:
 static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 {
 	const struct matrix_keypad_platform_data *pdata;
-	const struct matrix_keymap_data *keymap_data;
 	struct matrix_keypad *keypad;
 	struct input_dev *input_dev;
 	unsigned short *keycodes;
@@ -326,20 +325,13 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	keymap_data = pdata->keymap_data;
-	if (!keymap_data) {
+	if (!pdata->keymap) {
 		dev_err(&pdev->dev, "no keymap data defined\n");
 		return -EINVAL;
 	}
 
-	if (!keymap_data->max_keymap_size) {
-		dev_err(&pdev->dev, "invalid keymap data supplied\n");
-		return -EINVAL;
-	}
-
 	keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
-	keycodes = kzalloc(keymap_data->max_keymap_size *
-				sizeof(keypad->keycodes),
+	keycodes = kzalloc(sizeof(keypad->keycodes) * MATRIX_MAX_KEYS,
 			   GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!keypad || !keycodes || !input_dev) {
@@ -362,16 +354,14 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 	input_dev->close	= matrix_keypad_stop;
 
 	input_dev->keycode	= keycodes;
-	input_dev->keycodesize	= sizeof(*keycodes);
-	input_dev->keycodemax	= keymap_data->max_keymap_size;
 
-	for (i = 0; i < keymap_data->keymap_size; i++) {
-		unsigned int key = keymap_data->keymap[i];
+	for (i = 0; i < pdata->keymap_size; i++) {
+		unsigned int key = pdata->keymap[i];
 		unsigned int row = KEY_ROW(key);
 		unsigned int col = KEY_COL(key);
 		unsigned short code = KEY_VAL(key);
 
-		keycodes[(row << 4) + col] = code;
+		keycodes[KEY_IDX(row, col)] = code;
 		__set_bit(code, input_dev->keybit);
 	}
 	__clear_bit(KEY_RESERVED, input_dev->keybit);
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 7964516..59173c9 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -6,6 +6,7 @@
 
 #define MATRIX_MAX_ROWS		16
 #define MATRIX_MAX_COLS		16
+#define MATRIX_MAX_KEYS		(MATRIX_MAX_ROWS * MATRIX_MAX_COLS)
 
 #define KEY(row, col, val)	((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
 				 (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
@@ -14,26 +15,13 @@
 #define KEY_ROW(k)		(((k) >> 24) & 0xff)
 #define KEY_COL(k)		(((k) >> 16) & 0xff)
 #define KEY_VAL(k)		((k) & 0xffff)
+#define KEY_IDX(row, col)	(((row) << 4) + (col))
 
 /**
- * struct matrix_keymap_data - keymap for matrix keyboards
+ * struct matrix_keypad_platform_data - platform-dependent keypad data
  * @keymap: pointer to array of uint32 values encoded with KEY() macro
  *	representing keymap
  * @keymap_size: number of entries (initialized) in this keymap
- * @max_keymap_size: maximum size of keymap supported by the device
- *
- * This structure is supposed to be used by platform code to supply
- * keymaps to drivers that implement matrix-like keypads/keyboards.
- */
-struct matrix_keymap_data {
-	const uint32_t *keymap;
-	unsigned int	keymap_size;
-	unsigned int	max_keymap_size;
-};
-
-/**
- * struct matrix_keypad_platform_data - platform-dependent keypad data
- * @keymap_data: pointer to &matrix_keymap_data
  * @row_gpios: array of gpio numbers reporesenting rows
  * @col_gpios: array of gpio numbers reporesenting colums
  * @num_row_gpios: actual number of row gpios used by device
@@ -46,7 +34,8 @@ struct matrix_keymap_data {
  * matrix_keypad driver to perform proper initialization.
  */
 struct matrix_keypad_platform_data {
-	const struct matrix_keymap_data *keymap_data;
+	const uint32_t *keymap;
+	unsigned int	keymap_size;
 
 	unsigned int	row_gpios[MATRIX_MAX_ROWS];
 	unsigned int	col_gpios[MATRIX_MAX_COLS];
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux