diff mbox

[4/5] Input: mpr121 - use matrix keypad helper API

Message ID 1484156549-26585-5-git-send-email-akinobu.mita@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Akinobu Mita Jan. 11, 2017, 5:42 p.m. UTC
Convert to use matrix_kaypad_build_keymap() helper.

This is preparation for adding device tree support.  This change enables
to share code between legacy platform data probe and device tree probe.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
---
 drivers/input/keyboard/Kconfig           |  1 +
 drivers/input/keyboard/mpr121_touchkey.c | 64 +++++++++++++++++++++-----------
 2 files changed, 43 insertions(+), 22 deletions(-)

Comments

Dmitry Torokhov Jan. 13, 2017, 6:18 a.m. UTC | #1
Hi Akinobu,

On Thu, Jan 12, 2017 at 02:42:28AM +0900, Akinobu Mita wrote:
> Convert to use matrix_kaypad_build_keymap() helper.
> 
> This is preparation for adding device tree support.  This change enables
> to share code between legacy platform data probe and device tree probe.

I feel that matrix keymap is overkill here. We have standardish
linus,keycodes property for non-matrix keys/buttons; I think it should
be used here as well. For example of parsing see atmel_captouch_probe().

Also, I do not see anyone in mainline actually using mpr121 platform
data and the driver was merged in 2011. Therefore let's use generic
device properties to fetch keymap and other parameters and get rid of
platform data. If there are legacy (non-DT) boards they can define
property sets in their board-specific code.

Also, could you make a patch removing #ifdef CONFIG_PM_SLEEP and mark
suspend/resume handlers as __maybe_unused instead?

Thanks!

> 
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig           |  1 +
>  drivers/input/keyboard/mpr121_touchkey.c | 64 +++++++++++++++++++++-----------
>  2 files changed, 43 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index cbd75cf..b436e71 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -407,6 +407,7 @@ config KEYBOARD_MCS
>  config KEYBOARD_MPR121
>  	tristate "Freescale MPR121 Touchkey"
>  	depends on I2C
> +	select INPUT_MATRIXKMAP
>  	help
>  	  Say Y here if you have Freescale MPR121 touchkey controller
>  	  chip in your system.
> diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c
> index c809f70..7e85512 100644
> --- a/drivers/input/keyboard/mpr121_touchkey.c
> +++ b/drivers/input/keyboard/mpr121_touchkey.c
> @@ -20,6 +20,7 @@
>  #include <linux/bitops.h>
>  #include <linux/interrupt.h>
>  #include <linux/i2c/mpr121_touchkey.h>
> +#include <linux/input/matrix_keypad.h>
>  
>  /* Register definitions */
>  #define ELE_TOUCH_STATUS_0_ADDR	0x0
> @@ -61,7 +62,6 @@ struct mpr121_touchkey {
>  	struct input_dev	*input_dev;
>  	unsigned int		statusbits;
>  	unsigned int		keycount;
> -	u16			keycodes[MPR121_MAX_KEY_COUNT];
>  };
>  
>  struct mpr121_init_register {
> @@ -88,6 +88,7 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
>  	struct input_dev *input = mpr121->input_dev;
>  	unsigned int bit_changed;
>  	unsigned int key_num;
> +	const unsigned short *keycode = input->keycode;
>  	int reg;
>  
>  	reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
> @@ -114,7 +115,7 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
>  			continue;
>  
>  		pressed = reg & (1 << key_num);
> -		key_val = mpr121->keycodes[key_num];
> +		key_val = keycode[key_num];
>  
>  		input_event(input, EV_MSC, MSC_SCAN, key_num);
>  		input_report_key(input, key_val, pressed);
> @@ -196,23 +197,46 @@ static int mpr_touchkey_probe(struct i2c_client *client,
>  {
>  	const struct mpr121_platform_data *pdata =
>  			dev_get_platdata(&client->dev);
> +	struct device *dev = &client->dev;
> +	unsigned int keymap_size;
> +	struct matrix_keymap_data *keymap_data;
>  	struct mpr121_touchkey *mpr121;
>  	struct input_dev *input_dev;
>  	int error;
>  	int i;
>  
> -	if (!pdata) {
> -		dev_err(&client->dev, "no platform data defined\n");
> -		return -EINVAL;
> -	}
> +	if (pdata) {
> +		uint32_t *keymap;
>  
> -	if (!pdata->keymap || !pdata->keymap_size) {
> -		dev_err(&client->dev, "missing keymap data\n");
> -		return -EINVAL;
> -	}
> +		if (!pdata->keymap || !pdata->keymap_size) {
> +			dev_err(dev, "missing keymap data\n");
> +			return -EINVAL;
> +		}
> +
> +		if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
> +			dev_err(dev, "too many keys defined\n");
> +			return -EINVAL;
> +		}
> +
> +		keymap_size = pdata->keymap_size;
> +
> +		keymap = devm_kcalloc(dev, keymap_size,
> +				sizeof(keymap_data->keymap[0]), GFP_KERNEL);
> +		if (!keymap)
> +			return -ENOMEM;
>  
> -	if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
> -		dev_err(&client->dev, "too many keys defined\n");
> +		for (i = 0; i < keymap_size; i++)
> +			keymap[i] = KEY(0, i, pdata->keymap[i]);
> +
> +		keymap_data = devm_kzalloc(dev, sizeof(*keymap_data),
> +					GFP_KERNEL);
> +		if (!keymap_data)
> +			return -ENOMEM;
> +
> +		keymap_data->keymap_size = keymap_size;
> +		keymap_data->keymap = keymap;
> +	} else {
> +		dev_err(&client->dev, "no platform data defined\n");
>  		return -EINVAL;
>  	}
>  
> @@ -232,22 +256,18 @@ static int mpr_touchkey_probe(struct i2c_client *client,
>  
>  	mpr121->client = client;
>  	mpr121->input_dev = input_dev;
> -	mpr121->keycount = pdata->keymap_size;
> +	mpr121->keycount = keymap_size;
>  
>  	input_dev->name = "Freescale MPR121 Touchkey";
>  	input_dev->id.bustype = BUS_I2C;
>  	input_dev->dev.parent = &client->dev;
> -	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
> +	input_dev->evbit[0] = BIT_MASK(EV_REP);
>  	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
>  
> -	input_dev->keycode = mpr121->keycodes;
> -	input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
> -	input_dev->keycodemax = mpr121->keycount;
> -
> -	for (i = 0; i < pdata->keymap_size; i++) {
> -		input_set_capability(input_dev, EV_KEY, pdata->keymap[i]);
> -		mpr121->keycodes[i] = pdata->keymap[i];
> -	}
> +	error = matrix_keypad_build_keymap(keymap_data, NULL, 1, keymap_size,
> +						NULL, input_dev);
> +	if (error)
> +		return error;
>  
>  	error = mpr121_phys_init(pdata, mpr121, client);
>  	if (error) {
> -- 
> 2.7.4
>
diff mbox

Patch

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index cbd75cf..b436e71 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -407,6 +407,7 @@  config KEYBOARD_MCS
 config KEYBOARD_MPR121
 	tristate "Freescale MPR121 Touchkey"
 	depends on I2C
+	select INPUT_MATRIXKMAP
 	help
 	  Say Y here if you have Freescale MPR121 touchkey controller
 	  chip in your system.
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c
index c809f70..7e85512 100644
--- a/drivers/input/keyboard/mpr121_touchkey.c
+++ b/drivers/input/keyboard/mpr121_touchkey.c
@@ -20,6 +20,7 @@ 
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
 #include <linux/i2c/mpr121_touchkey.h>
+#include <linux/input/matrix_keypad.h>
 
 /* Register definitions */
 #define ELE_TOUCH_STATUS_0_ADDR	0x0
@@ -61,7 +62,6 @@  struct mpr121_touchkey {
 	struct input_dev	*input_dev;
 	unsigned int		statusbits;
 	unsigned int		keycount;
-	u16			keycodes[MPR121_MAX_KEY_COUNT];
 };
 
 struct mpr121_init_register {
@@ -88,6 +88,7 @@  static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
 	struct input_dev *input = mpr121->input_dev;
 	unsigned int bit_changed;
 	unsigned int key_num;
+	const unsigned short *keycode = input->keycode;
 	int reg;
 
 	reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
@@ -114,7 +115,7 @@  static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
 			continue;
 
 		pressed = reg & (1 << key_num);
-		key_val = mpr121->keycodes[key_num];
+		key_val = keycode[key_num];
 
 		input_event(input, EV_MSC, MSC_SCAN, key_num);
 		input_report_key(input, key_val, pressed);
@@ -196,23 +197,46 @@  static int mpr_touchkey_probe(struct i2c_client *client,
 {
 	const struct mpr121_platform_data *pdata =
 			dev_get_platdata(&client->dev);
+	struct device *dev = &client->dev;
+	unsigned int keymap_size;
+	struct matrix_keymap_data *keymap_data;
 	struct mpr121_touchkey *mpr121;
 	struct input_dev *input_dev;
 	int error;
 	int i;
 
-	if (!pdata) {
-		dev_err(&client->dev, "no platform data defined\n");
-		return -EINVAL;
-	}
+	if (pdata) {
+		uint32_t *keymap;
 
-	if (!pdata->keymap || !pdata->keymap_size) {
-		dev_err(&client->dev, "missing keymap data\n");
-		return -EINVAL;
-	}
+		if (!pdata->keymap || !pdata->keymap_size) {
+			dev_err(dev, "missing keymap data\n");
+			return -EINVAL;
+		}
+
+		if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
+			dev_err(dev, "too many keys defined\n");
+			return -EINVAL;
+		}
+
+		keymap_size = pdata->keymap_size;
+
+		keymap = devm_kcalloc(dev, keymap_size,
+				sizeof(keymap_data->keymap[0]), GFP_KERNEL);
+		if (!keymap)
+			return -ENOMEM;
 
-	if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
-		dev_err(&client->dev, "too many keys defined\n");
+		for (i = 0; i < keymap_size; i++)
+			keymap[i] = KEY(0, i, pdata->keymap[i]);
+
+		keymap_data = devm_kzalloc(dev, sizeof(*keymap_data),
+					GFP_KERNEL);
+		if (!keymap_data)
+			return -ENOMEM;
+
+		keymap_data->keymap_size = keymap_size;
+		keymap_data->keymap = keymap;
+	} else {
+		dev_err(&client->dev, "no platform data defined\n");
 		return -EINVAL;
 	}
 
@@ -232,22 +256,18 @@  static int mpr_touchkey_probe(struct i2c_client *client,
 
 	mpr121->client = client;
 	mpr121->input_dev = input_dev;
-	mpr121->keycount = pdata->keymap_size;
+	mpr121->keycount = keymap_size;
 
 	input_dev->name = "Freescale MPR121 Touchkey";
 	input_dev->id.bustype = BUS_I2C;
 	input_dev->dev.parent = &client->dev;
-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_REP);
 	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
-	input_dev->keycode = mpr121->keycodes;
-	input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
-	input_dev->keycodemax = mpr121->keycount;
-
-	for (i = 0; i < pdata->keymap_size; i++) {
-		input_set_capability(input_dev, EV_KEY, pdata->keymap[i]);
-		mpr121->keycodes[i] = pdata->keymap[i];
-	}
+	error = matrix_keypad_build_keymap(keymap_data, NULL, 1, keymap_size,
+						NULL, input_dev);
+	if (error)
+		return error;
 
 	error = mpr121_phys_init(pdata, mpr121, client);
 	if (error) {