diff options
22 files changed, 265 insertions, 209 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 33259798081..55f7e57d4e4 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -25,10 +25,6 @@ config INPUT  if INPUT -config INPUT_OF_MATRIX_KEYMAP -	depends on USE_OF -	bool -  config INPUT_FF_MEMLESS  	tristate "Support for memoryless force-feedback devices"  	help @@ -68,6 +64,19 @@ config INPUT_SPARSEKMAP  	  To compile this driver as a module, choose M here: the  	  module will be called sparse-keymap. +config INPUT_MATRIXKMAP +	tristate "Matrix keymap support library" +	help +	  Say Y here if you are using a driver for an input +	  device that uses matrix keymap. This option is only +	  useful for out-of-tree drivers since in-tree drivers +	  select it automatically. + +	  If unsure, say N. + +	  To compile this driver as a module, choose M here: the +	  module will be called matrix-keymap. +  comment "Userland interfaces"  config INPUT_MOUSEDEV diff --git a/drivers/input/Makefile b/drivers/input/Makefile index b173a13a73c..5ca3f631497 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o input-mt.o ff-core.o  obj-$(CONFIG_INPUT_FF_MEMLESS)	+= ff-memless.o  obj-$(CONFIG_INPUT_POLLDEV)	+= input-polldev.o  obj-$(CONFIG_INPUT_SPARSEKMAP)	+= sparse-keymap.o +obj-$(CONFIG_INPUT_MATRIXKMAP)	+= matrix-keymap.o  obj-$(CONFIG_INPUT_MOUSEDEV)	+= mousedev.o  obj-$(CONFIG_INPUT_JOYDEV)	+= joydev.o @@ -24,4 +25,3 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN)	+= touchscreen/  obj-$(CONFIG_INPUT_MISC)	+= misc/  obj-$(CONFIG_INPUT_APMPOWER)	+= apm-power.o -obj-$(CONFIG_INPUT_OF_MATRIX_KEYMAP) += of_keymap.o diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ea4bbaae9e0..c0e11ecc646 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -166,6 +166,7 @@ config KEYBOARD_LKKBD  config KEYBOARD_EP93XX  	tristate "EP93xx Matrix Keypad support"  	depends on ARCH_EP93XX +	select INPUT_MATRIXKMAP  	help  	  Say Y here to enable the matrix keypad on the Cirrus EP93XX. @@ -224,6 +225,7 @@ config KEYBOARD_TCA6416  config KEYBOARD_TCA8418  	tristate "TCA8418 Keypad Support"  	depends on I2C +	select INPUT_MATRIXKMAP  	help  	  This driver implements basic keypad functionality  	  for keys connected through TCA8418 keypad decoder. @@ -240,6 +242,7 @@ config KEYBOARD_TCA8418  config KEYBOARD_MATRIX  	tristate "GPIO driven matrix keypad support"  	depends on GENERIC_GPIO +	select INPUT_MATRIXKMAP  	help  	  Enable support for GPIO driven matrix keypad. @@ -312,6 +315,7 @@ config KEYBOARD_LM8323  config KEYBOARD_LM8333  	tristate "LM8333 keypad chip"  	depends on I2C +	select INPUT_MATRIXKMAP  	help  	  If you say yes here you get support for the National Semiconductor  	  LM8333 keypad controller. @@ -376,6 +380,7 @@ config KEYBOARD_MPR121  config KEYBOARD_IMX  	tristate "IMX keypad support"  	depends on ARCH_MXC +	select INPUT_MATRIXKMAP  	help  	  Enable support for IMX keypad port. @@ -394,6 +399,7 @@ config KEYBOARD_NEWTON  config KEYBOARD_NOMADIK  	tristate "ST-Ericsson Nomadik SKE keyboard"  	depends on PLAT_NOMADIK +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use a keypad provided on the SKE controller  	  used on the Ux500 and Nomadik platforms @@ -404,7 +410,7 @@ config KEYBOARD_NOMADIK  config KEYBOARD_TEGRA  	tristate "NVIDIA Tegra internal matrix keyboard controller support"  	depends on ARCH_TEGRA -	select INPUT_OF_MATRIX_KEYMAP if USE_OF +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use a matrix keyboard connected directly  	  to the internal keyboard controller on Tegra SoCs. @@ -442,6 +448,7 @@ config KEYBOARD_PXA930_ROTARY  config KEYBOARD_PMIC8XXX  	tristate "Qualcomm PMIC8XXX keypad support"  	depends on MFD_PM8XXX +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to enable the driver for the PMIC8XXX  	  keypad provided as a reference design from Qualcomm. This is intended @@ -453,6 +460,7 @@ config KEYBOARD_PMIC8XXX  config KEYBOARD_SAMSUNG  	tristate "Samsung keypad support"  	depends on HAVE_CLK +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the keypad on your Samsung mobile  	  device. @@ -495,6 +503,7 @@ config KEYBOARD_SH_KEYSC  config KEYBOARD_STMPE  	tristate "STMPE keypad support"  	depends on MFD_STMPE +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the keypad controller on STMPE I/O  	  expanders. @@ -515,6 +524,7 @@ config KEYBOARD_DAVINCI  config KEYBOARD_OMAP  	tristate "TI OMAP keypad support"  	depends on (ARCH_OMAP1 || ARCH_OMAP2) +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the OMAP keypad. @@ -523,6 +533,7 @@ config KEYBOARD_OMAP  config KEYBOARD_OMAP4  	tristate "TI OMAP4+ keypad support" +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the OMAP4+ keypad. @@ -532,6 +543,7 @@ config KEYBOARD_OMAP4  config KEYBOARD_SPEAR  	tristate "ST SPEAR keyboard support"  	depends on PLAT_SPEAR +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the SPEAR keyboard. @@ -541,6 +553,7 @@ config KEYBOARD_SPEAR  config KEYBOARD_TC3589X  	tristate "TC3589X Keypad support"  	depends on MFD_TC3589X +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the keypad controller on  	  TC35892/3 I/O expander. @@ -551,6 +564,7 @@ config KEYBOARD_TC3589X  config KEYBOARD_TNETV107X  	tristate "TI TNETV107X keypad support"  	depends on ARCH_DAVINCI_TNETV107X +	select INPUT_MATRIXKMAP  	help  	  Say Y here if you want to use the TNETV107X keypad. @@ -560,6 +574,7 @@ config KEYBOARD_TNETV107X  config KEYBOARD_TWL4030  	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"  	depends on TWL4030_CORE +	select INPUT_MATRIXKMAP  	help  	  Say Y here if your board use the keypad controller on  	  TWL4030 family chips.  It's safe to say enable this @@ -583,6 +598,7 @@ config KEYBOARD_XTKBD  config KEYBOARD_W90P910  	tristate "W90P910 Matrix Keypad support"  	depends on ARCH_W90X900 +	select INPUT_MATRIXKMAP  	help  	  Say Y here to enable the matrix keypad on evaluation board  	  based on W90P910. diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index df194bdaab5..c46fc818546 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -303,19 +303,16 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)  	input_dev->open = ep93xx_keypad_open;  	input_dev->close = ep93xx_keypad_close;  	input_dev->dev.parent = &pdev->dev; -	input_dev->keycode = keypad->keycodes; -	input_dev->keycodesize = sizeof(keypad->keycodes[0]); -	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); -	input_set_drvdata(input_dev, keypad); +	err = matrix_keypad_build_keymap(keymap_data, NULL, +					 EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS, +					 keypad->keycodes, input_dev); +	if (err) +		goto failed_free_dev; -	input_dev->evbit[0] = BIT_MASK(EV_KEY);  	if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) -		input_dev->evbit[0] |= BIT_MASK(EV_REP); - -	matrix_keypad_build_keymap(keymap_data, 3, -				   input_dev->keycode, input_dev->keybit); -	platform_set_drvdata(pdev, keypad); +		__set_bit(EV_REP, input_dev->evbit); +	input_set_drvdata(input_dev, keypad);  	err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,  			  0, pdev->name, keypad); @@ -326,6 +323,7 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)  	if (err)  		goto failed_free_irq; +	platform_set_drvdata(pdev, keypad);  	device_init_wakeup(&pdev->dev, 1);  	return 0; diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index fb87b3bcadb..6ee7421e232 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -481,7 +481,7 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)  	}  	if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || -	   keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { +	    keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) {  		dev_err(&pdev->dev,  			"invalid key data (too many rows or colums)\n");  		error = -EINVAL; @@ -496,14 +496,17 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)  	input_dev->dev.parent = &pdev->dev;  	input_dev->open = imx_keypad_open;  	input_dev->close = imx_keypad_close; -	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); -	input_dev->keycode = keypad->keycodes; -	input_dev->keycodesize = sizeof(keypad->keycodes[0]); -	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); -	matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, -				keypad->keycodes, input_dev->keybit); +	error = matrix_keypad_build_keymap(keymap_data, NULL, +					   MAX_MATRIX_KEY_ROWS, +					   MAX_MATRIX_KEY_COLS, +					   keypad->keycodes, input_dev); +	if (error) { +		dev_err(&pdev->dev, "failed to build keymap\n"); +		goto failed_clock_put; +	} +	__set_bit(EV_REP, input_dev->evbit);  	input_set_capability(input_dev, EV_MSC, MSC_SCAN);  	input_set_drvdata(input_dev, keypad); diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c index 9a8c4a6cf5c..ca168a6679d 100644 --- a/drivers/input/keyboard/lm8333.c +++ b/drivers/input/keyboard/lm8333.c @@ -29,9 +29,9 @@  #define LM8333_FIFO_TRANSFER_SIZE	16 -#define LM8333_ROW_SHIFT	4  #define LM8333_NUM_ROWS		8 - +#define LM8333_NUM_COLS		16 +#define LM8333_ROW_SHIFT	4  struct lm8333 {  	struct i2c_client *client; @@ -159,14 +159,13 @@ static int __devinit lm8333_probe(struct i2c_client *client,  	input->dev.parent = &client->dev;  	input->id.bustype = BUS_I2C; -	input->keycode = lm8333->keycodes; -	input->keycodesize = sizeof(lm8333->keycodes[0]); -	input->keycodemax = ARRAY_SIZE(lm8333->keycodes); -	input->evbit[0] = BIT_MASK(EV_KEY);  	input_set_capability(input, EV_MSC, MSC_SCAN); -	matrix_keypad_build_keymap(pdata->matrix_data, LM8333_ROW_SHIFT, -			input->keycode, input->keybit); +	err = matrix_keypad_build_keymap(pdata->matrix_data, NULL, +					 LM8333_NUM_ROWS, LM8333_NUM_COLS, +					 lm8333->keycodes, input); +	if (err) +		goto free_mem;  	if (pdata->debounce_time) {  		err = lm8333_write8(lm8333, LM8333_DEBOUNCE, diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 98ae281bedb..18b72372028 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -437,19 +437,18 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)  	input_dev->name		= pdev->name;  	input_dev->id.bustype	= BUS_HOST;  	input_dev->dev.parent	= &pdev->dev; -	input_dev->evbit[0]	= BIT_MASK(EV_KEY); -	if (!pdata->no_autorepeat) -		input_dev->evbit[0] |= BIT_MASK(EV_REP);  	input_dev->open		= matrix_keypad_start;  	input_dev->close	= matrix_keypad_stop; -	input_dev->keycode	= keypad->keycodes; -	input_dev->keycodesize	= sizeof(keypad->keycodes[0]); -	input_dev->keycodemax	= pdata->num_row_gpios << row_shift; - -	matrix_keypad_build_keymap(keymap_data, row_shift, -				   input_dev->keycode, input_dev->keybit); +	err = matrix_keypad_build_keymap(keymap_data, NULL, +					 pdata->num_row_gpios, +					 pdata->num_col_gpios, +					 keypad->keycodes, input_dev); +	if (err) +		goto err_free_mem; +	if (!pdata->no_autorepeat) +		__set_bit(EV_REP, input_dev->evbit);  	input_set_capability(input_dev, EV_MSC, MSC_SCAN);  	input_set_drvdata(input_dev, keypad); diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 101e245944e..4ea4341a68c 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -39,7 +39,8 @@  #define SKE_KPRISA	(0x1 << 2)  #define SKE_KEYPAD_ROW_SHIFT	3 -#define SKE_KPD_KEYMAP_SIZE	(8 * 8) +#define SKE_KPD_NUM_ROWS	8 +#define SKE_KPD_NUM_COLS	8  /* keypad auto scan registers */  #define SKE_ASR0	0x20 @@ -63,7 +64,7 @@ struct ske_keypad {  	void __iomem *reg_base;  	struct input_dev *input;  	const struct ske_keypad_platform_data *board; -	unsigned short keymap[SKE_KPD_KEYMAP_SIZE]; +	unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS];  	struct clk *clk;  	spinlock_t ske_keypad_lock;  }; @@ -261,19 +262,18 @@ static int __init ske_keypad_probe(struct platform_device *pdev)  	input->name = "ux500-ske-keypad";  	input->dev.parent = &pdev->dev; -	input->keycode = keypad->keymap; -	input->keycodesize = sizeof(keypad->keymap[0]); -	input->keycodemax = ARRAY_SIZE(keypad->keymap); +	error = matrix_keypad_build_keymap(plat->keymap_data, NULL, +					   SKE_KPD_NUM_ROWS, SKE_KPD_NUM_COLS, +					   keypad->keymap, input); +	if (error) { +		dev_err(&pdev->dev, "Failed to build keymap\n"); +		goto err_iounmap; +	}  	input_set_capability(input, EV_MSC, MSC_SCAN); - -	__set_bit(EV_KEY, input->evbit);  	if (!plat->no_autorepeat)  		__set_bit(EV_REP, input->evbit); -	matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, -			input->keycode, input->keybit); -  	clk_enable(keypad->clk);  	/* go through board initialization helpers */ diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 6b630d9d3df..a0222db4dc8 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -61,6 +61,7 @@ struct omap_kp {  	unsigned int cols;  	unsigned long delay;  	unsigned int debounce; +	unsigned short keymap[];  };  static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); @@ -316,13 +317,6 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)  	if (!cpu_is_omap24xx())  		omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); -	input_dev->keycode      = &omap_kp[1]; -	input_dev->keycodesize  = sizeof(unsigned short); -	input_dev->keycodemax   = keycodemax; - -	if (pdata->rep) -		__set_bit(EV_REP, input_dev->evbit); -  	if (pdata->delay)  		omap_kp->delay = pdata->delay; @@ -371,9 +365,6 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)  		goto err2;  	/* setup input device */ -	__set_bit(EV_KEY, input_dev->evbit); -	matrix_keypad_build_keymap(pdata->keymap_data, row_shift, -			input_dev->keycode, input_dev->keybit);  	input_dev->name = "omap-keypad";  	input_dev->phys = "omap-keypad/input0";  	input_dev->dev.parent = &pdev->dev; @@ -383,6 +374,15 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)  	input_dev->id.product = 0x0001;  	input_dev->id.version = 0x0100; +	if (pdata->rep) +		__set_bit(EV_REP, input_dev->evbit); + +	ret = matrix_keypad_build_keymap(pdata->keymap_data, NULL, +					 pdata->rows, pdata->cols, +					 omap_kp->keymap, input_dev); +	if (ret < 0) +		goto err3; +  	ret = input_register_device(omap_kp->input);  	if (ret < 0) {  		printk(KERN_ERR "Unable to register omap-keypad input device\n"); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 28da0e46968..aed5f6999ce 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -322,20 +322,19 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)  	input_dev->open = omap4_keypad_open;  	input_dev->close = omap4_keypad_close; -	input_dev->keycode	= keypad_data->keymap; -	input_dev->keycodesize	= sizeof(keypad_data->keymap[0]); -	input_dev->keycodemax	= max_keys; +	error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, +					   pdata->rows, pdata->cols, +					   keypad_data->keymap, input_dev); +	if (error) { +		dev_err(&pdev->dev, "failed to build keymap\n"); +		goto err_free_input; +	} -	__set_bit(EV_KEY, input_dev->evbit);  	__set_bit(EV_REP, input_dev->evbit); -  	input_set_capability(input_dev, EV_MSC, MSC_SCAN);  	input_set_drvdata(input_dev, keypad_data); -	matrix_keypad_build_keymap(pdata->keymap_data, row_shift, -			input_dev->keycode, input_dev->keybit); -  	error = request_irq(keypad_data->irq, omap4_keypad_interrupt,  			     IRQF_TRIGGER_RISING,  			     "omap4-keypad", keypad_data); diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 01a1c9f8a38..52c34657d30 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -626,21 +626,21 @@ static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev)  	kp->input->id.product	= 0x0001;  	kp->input->id.vendor	= 0x0001; -	kp->input->evbit[0]	= BIT_MASK(EV_KEY); - -	if (pdata->rep) -		__set_bit(EV_REP, kp->input->evbit); - -	kp->input->keycode	= kp->keycodes; -	kp->input->keycodemax	= PM8XXX_MATRIX_MAX_SIZE; -	kp->input->keycodesize	= sizeof(kp->keycodes);  	kp->input->open		= pmic8xxx_kp_open;  	kp->input->close	= pmic8xxx_kp_close; -	matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, -					kp->input->keycode, kp->input->keybit); +	rc = matrix_keypad_build_keymap(keymap_data, NULL, +					PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, +					kp->keycodes, kp->input); +	if (rc) { +		dev_err(&pdev->dev, "failed to build keymap\n"); +		goto err_get_irq; +	} +	if (pdata->rep) +		__set_bit(EV_REP, kp->input->evbit);  	input_set_capability(kp->input, EV_MSC, MSC_SCAN); +  	input_set_drvdata(kp->input, kp);  	/* initialize keypad state */ diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 2391ae884fe..a061ba603a2 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -454,23 +454,23 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)  	input_dev->name = pdev->name;  	input_dev->id.bustype = BUS_HOST;  	input_dev->dev.parent = &pdev->dev; -	input_set_drvdata(input_dev, keypad);  	input_dev->open = samsung_keypad_open;  	input_dev->close = samsung_keypad_close; -	input_dev->evbit[0] = BIT_MASK(EV_KEY); -	if (!pdata->no_autorepeat) -		input_dev->evbit[0] |= BIT_MASK(EV_REP); +	error = matrix_keypad_build_keymap(keymap_data, NULL, +					   pdata->rows, pdata->cols, +					   keypad->keycodes, input_dev); +	if (error) { +		dev_err(&pdev->dev, "failed to build keymap\n"); +		goto err_put_clk; +	}  	input_set_capability(input_dev, EV_MSC, MSC_SCAN); +	if (!pdata->no_autorepeat) +		__set_bit(EV_REP, input_dev->evbit); -	input_dev->keycode = keypad->keycodes; -	input_dev->keycodesize = sizeof(keypad->keycodes[0]); -	input_dev->keycodemax = pdata->rows << row_shift; - -	matrix_keypad_build_keymap(keymap_data, row_shift, -			input_dev->keycode, input_dev->keybit); +	input_set_drvdata(input_dev, keypad);  	keypad->irq = platform_get_irq(pdev, 0);  	if (keypad->irq < 0) { diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 3b6b528f02f..e83cab27eb5 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -49,7 +49,9 @@  #define KEY_VALUE	0x00FFFFFF  #define ROW_MASK	0xF0  #define COLUMN_MASK	0x0F -#define ROW_SHIFT	4 +#define NUM_ROWS	16 +#define NUM_COLS	16 +  #define KEY_MATRIX_SHIFT	6  struct spear_kbd { @@ -60,7 +62,7 @@ struct spear_kbd {  	unsigned int irq;  	unsigned int mode;  	unsigned short last_key; -	unsigned short keycodes[256]; +	unsigned short keycodes[NUM_ROWS * NUM_COLS];  };  static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) @@ -212,18 +214,17 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev)  	input_dev->open = spear_kbd_open;  	input_dev->close = spear_kbd_close; -	__set_bit(EV_KEY, input_dev->evbit); +	error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS, +					   kbd->keycodes, input_dev); +	if (error) { +		dev_err(&pdev->dev, "Failed to build keymap\n"); +		goto err_put_clk; +	} +  	if (pdata->rep)  		__set_bit(EV_REP, input_dev->evbit);  	input_set_capability(input_dev, EV_MSC, MSC_SCAN); -	input_dev->keycode = kbd->keycodes; -	input_dev->keycodesize = sizeof(kbd->keycodes[0]); -	input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes); - -	matrix_keypad_build_keymap(keymap, ROW_SHIFT, -			input_dev->keycode, input_dev->keybit); -  	input_set_drvdata(input_dev, kbd);  	error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 9397cf9c625..470a8778dec 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -289,19 +289,17 @@ static int __devinit stmpe_keypad_probe(struct platform_device *pdev)  	input->id.bustype = BUS_I2C;  	input->dev.parent = &pdev->dev; -	input_set_capability(input, EV_MSC, MSC_SCAN); +	ret = matrix_keypad_build_keymap(plat->keymap_data, NULL, +					 STMPE_KEYPAD_MAX_ROWS, +					 STMPE_KEYPAD_MAX_COLS, +					 keypad->keymap, input); +	if (ret) +		goto out_freeinput; -	__set_bit(EV_KEY, input->evbit); +	input_set_capability(input, EV_MSC, MSC_SCAN);  	if (!plat->no_autorepeat)  		__set_bit(EV_REP, input->evbit); -	input->keycode = keypad->keymap; -	input->keycodesize = sizeof(keypad->keymap[0]); -	input->keycodemax = ARRAY_SIZE(keypad->keymap); - -	matrix_keypad_build_keymap(plat->keymap_data, STMPE_KEYPAD_ROW_SHIFT, -				   input->keycode, input->keybit); -  	for (i = 0; i < plat->keymap_data->keymap_size; i++) {  		unsigned int key = plat->keymap_data->keymap[i]; diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index f4da2a7a697..7d498e69850 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -78,7 +78,7 @@   * @input:      pointer to input device object   * @board:      keypad platform device   * @krow:	number of rows - * @kcol:	number of coloumns + * @kcol:	number of columns   * @keymap:     matrix scan code table for keycodes   * @keypad_stopped: holds keypad status   */ @@ -333,23 +333,22 @@ static int __devinit tc3589x_keypad_probe(struct platform_device *pdev)  	input->name = pdev->name;  	input->dev.parent = &pdev->dev; -	input->keycode = keypad->keymap; -	input->keycodesize = sizeof(keypad->keymap[0]); -	input->keycodemax = ARRAY_SIZE(keypad->keymap); -  	input->open = tc3589x_keypad_open;  	input->close = tc3589x_keypad_close; -	input_set_drvdata(input, keypad); +	error = matrix_keypad_build_keymap(plat->keymap_data, NULL, +					   TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, +					   keypad->keymap, input); +	if (error) { +		dev_err(&pdev->dev, "Failed to build keymap\n"); +		goto err_free_mem; +	}  	input_set_capability(input, EV_MSC, MSC_SCAN); - -	__set_bit(EV_KEY, input->evbit);  	if (!plat->no_autorepeat)  		__set_bit(EV_REP, input->evbit); -	matrix_keypad_build_keymap(plat->keymap_data, 0x3, -			input->keycode, input->keybit); +	input_set_drvdata(input, keypad);  	error = request_threaded_irq(irq, NULL,  			tc3589x_keypad_irq, plat->irqtype, diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 958ec107bfb..5f87b28b319 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -342,21 +342,20 @@ static int __devinit tca8418_keypad_probe(struct i2c_client *client,  	input->id.product = 0x001;  	input->id.version = 0x0001; -	input->keycode     = keypad_data->keymap; -	input->keycodesize = sizeof(keypad_data->keymap[0]); -	input->keycodemax  = max_keys; +	error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, +					   pdata->rows, pdata->cols, +					   keypad_data->keymap, input); +	if (error) { +		dev_dbg(&client->dev, "Failed to build keymap\n"); +		goto fail2; +	} -	__set_bit(EV_KEY, input->evbit);  	if (pdata->rep)  		__set_bit(EV_REP, input->evbit); -  	input_set_capability(input, EV_MSC, MSC_SCAN);  	input_set_drvdata(input, keypad_data); -	matrix_keypad_build_keymap(pdata->keymap_data, row_shift, -			input->keycode, input->keybit); -  	if (pdata->irq_is_gpio)  		client->irq = gpio_to_irq(client->irq); diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index fe4ac95ca6c..6722d376e89 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -686,6 +686,7 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)  	int num_rows = 0;  	unsigned int debounce_cnt;  	unsigned int scan_time_rows; +	unsigned int keymap_rows;  	if (!pdata)  		pdata = tegra_kbc_dt_parse_pdata(pdev); @@ -757,29 +758,34 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)  	kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt;  	kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); +	kbc->wakeup_key = pdata->wakeup_key; +	kbc->use_fn_map = pdata->use_fn_map; +	kbc->use_ghost_filter = pdata->use_ghost_filter; +  	input_dev->name = pdev->name;  	input_dev->id.bustype = BUS_HOST;  	input_dev->dev.parent = &pdev->dev;  	input_dev->open = tegra_kbc_open;  	input_dev->close = tegra_kbc_close; -	input_set_drvdata(input_dev, kbc); - -	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); -	input_set_capability(input_dev, EV_MSC, MSC_SCAN); - -	input_dev->keycode = kbc->keycode; -	input_dev->keycodesize = sizeof(kbc->keycode[0]); -	input_dev->keycodemax = KBC_MAX_KEY; +	keymap_rows = KBC_MAX_KEY;  	if (pdata->use_fn_map) -		input_dev->keycodemax *= 2; +		keymap_rows *= 2; -	kbc->use_fn_map = pdata->use_fn_map; -	kbc->use_ghost_filter = pdata->use_ghost_filter;  	keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; -	matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, -				   input_dev->keycode, input_dev->keybit); -	kbc->wakeup_key = pdata->wakeup_key; + +	err = matrix_keypad_build_keymap(keymap_data, NULL, +					 keymap_rows, KBC_MAX_COL, +					 kbc->keycode, input_dev); +	if (err) { +		dev_err(&pdev->dev, "failed to build keymap\n"); +		goto err_put_clk; +	} + +	__set_bit(EV_REP, input_dev->evbit); +	input_set_capability(input_dev, EV_MSC, MSC_SCAN); + +	input_set_drvdata(input_dev, kbc);  	err = request_irq(kbc->irq, tegra_kbc_isr,  			  IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc); diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index fb39c94b6fd..a4a445fb702 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c @@ -247,15 +247,11 @@ static int __devinit keypad_probe(struct platform_device *pdev)  		error = -ENOMEM;  		goto error_input;  	} -	input_set_drvdata(kp->input_dev, kp);  	kp->input_dev->name	  = pdev->name;  	kp->input_dev->dev.parent = &pdev->dev;  	kp->input_dev->open	  = keypad_start;  	kp->input_dev->close	  = keypad_stop; -	kp->input_dev->evbit[0]	  = BIT_MASK(EV_KEY); -	if (!pdata->no_autorepeat) -		kp->input_dev->evbit[0] |= BIT_MASK(EV_REP);  	clk_enable(kp->clk);  	rev = keypad_read(kp, rev); @@ -264,15 +260,20 @@ static int __devinit keypad_probe(struct platform_device *pdev)  	kp->input_dev->id.version = ((rev >> 16) & 0xfff);  	clk_disable(kp->clk); -	kp->input_dev->keycode     = kp->keycodes; -	kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); -	kp->input_dev->keycodemax  = kp->rows << kp->row_shift; - -	matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, -				   kp->input_dev->keybit); +	error = matrix_keypad_build_keymap(keymap_data, NULL, +					   kp->rows, kp->cols, +					   kp->keycodes, kp->input_dev); +	if (error) { +		dev_err(dev, "Failed to build keymap\n"); +		goto error_reg; +	} +	if (!pdata->no_autorepeat) +		kp->input_dev->evbit[0] |= BIT_MASK(EV_REP);  	input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); +	input_set_drvdata(kp->input_dev, kp); +  	error = input_register_device(kp->input_dev);  	if (error < 0) {  		dev_err(dev, "Could not register input device\n"); diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 67bec14e8b9..a2c6f79aa10 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -361,14 +361,6 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev)  	kp->irq = platform_get_irq(pdev, 0);  	/* setup input device */ -	__set_bit(EV_KEY, input->evbit); - -	/* Enable auto repeat feature of Linux input subsystem */ -	if (pdata->rep) -		__set_bit(EV_REP, input->evbit); - -	input_set_capability(input, EV_MSC, MSC_SCAN); -  	input->name		= "TWL4030 Keypad";  	input->phys		= "twl4030_keypad/input0";  	input->dev.parent	= &pdev->dev; @@ -378,12 +370,19 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev)  	input->id.product	= 0x0001;  	input->id.version	= 0x0003; -	input->keycode		= kp->keymap; -	input->keycodesize	= sizeof(kp->keymap[0]); -	input->keycodemax	= ARRAY_SIZE(kp->keymap); +	error = matrix_keypad_build_keymap(keymap_data, NULL, +					   TWL4030_MAX_ROWS, +					   1 << TWL4030_ROW_SHIFT, +					   kp->keymap, input); +	if (error) { +		dev_err(kp->dbg_dev, "Failed to build keymap\n"); +		goto err1; +	} -	matrix_keypad_build_keymap(keymap_data, TWL4030_ROW_SHIFT, -				   input->keycode, input->keybit); +	input_set_capability(input, EV_MSC, MSC_SCAN); +	/* Enable auto repeat feature of Linux input subsystem */ +	if (pdata->rep) +		__set_bit(EV_REP, input->evbit);  	error = input_register_device(input);  	if (error) { diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 99bbb7e775a..085ede4d972 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c @@ -42,7 +42,8 @@  #define KGET_RAW(n)		(((n) & KEY0R) >> 3)  #define KGET_COLUMN(n)		((n) & KEY0C) -#define W90P910_MAX_KEY_NUM	(8 * 8) +#define W90P910_NUM_ROWS	8 +#define W90P910_NUM_COLS	8  #define W90P910_ROW_SHIFT	3  struct w90p910_keypad { @@ -51,7 +52,7 @@ struct w90p910_keypad {  	struct input_dev *input_dev;  	void __iomem *mmio_base;  	int irq; -	unsigned short keymap[W90P910_MAX_KEY_NUM]; +	unsigned short keymap[W90P910_NUM_ROWS * W90P910_NUM_COLS];  };  static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, @@ -190,17 +191,13 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)  	input_dev->close = w90p910_keypad_close;  	input_dev->dev.parent = &pdev->dev; -	input_dev->keycode = keypad->keymap; -	input_dev->keycodesize = sizeof(keypad->keymap[0]); -	input_dev->keycodemax = ARRAY_SIZE(keypad->keymap); - -	input_set_drvdata(input_dev, keypad); - -	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); -	input_set_capability(input_dev, EV_MSC, MSC_SCAN); - -	matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT, -				   input_dev->keycode, input_dev->keybit); +	error = matrix_keypad_build_keymap(keymap_data, NULL, +					   W90P910_NUM_ROWS, W90P910_NUM_COLS, +					   keypad->keymap, input_dev); +	if (error) { +		dev_err(&pdev->dev, "failed to build keymap\n"); +		goto failed_put_clk; +	}  	error = request_irq(keypad->irq, w90p910_keypad_irq_handler,  			    0, pdev->name, keypad); @@ -209,6 +206,10 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)  		goto failed_put_clk;  	} +	__set_bit(EV_REP, input_dev->evbit); +	input_set_capability(input_dev, EV_MSC, MSC_SCAN); +	input_set_drvdata(input_dev, keypad); +  	/* Register the input device */  	error = input_register_device(input_dev);  	if (error) { diff --git a/drivers/input/of_keymap.c b/drivers/input/matrix-keymap.c index 061493d5768..de7992d55da 100644 --- a/drivers/input/of_keymap.c +++ b/drivers/input/matrix-keymap.c @@ -1,5 +1,5 @@  /* - * Helpers for open firmware matrix keyboard bindings + * Helpers for matrix keyboard bindings   *   * Copyright (C) 2012 Google, Inc   * @@ -21,11 +21,65 @@  #include <linux/types.h>  #include <linux/input.h>  #include <linux/of.h> -#include <linux/input/matrix_keypad.h>  #include <linux/export.h>  #include <linux/gfp.h>  #include <linux/slab.h> +#include <linux/input/matrix_keypad.h> + + +/** + * matrix_keypad_build_keymap - convert platform keymap into matrix keymap + * @keymap_data: keymap supplied by the platform code + * @keymap_name: name of device tree property containing keymap (if device + *	tree support is enabled). + * @rows: number of rows in target keymap array + * @cols: number of cols in target keymap array + * @keymap: expanded version of keymap that is suitable for use by + * matrix keyboard driver + * @input_dev: input devices for which we are setting up the keymap + * + * This function converts platform keymap (encoded with KEY() macro) into + * an array of keycodes that is suitable for using in a standard matrix + * keyboard driver that uses row and col as indices. + */ +int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, +			       const char *keymap_name, +			       unsigned int rows, unsigned int cols, +			       unsigned short *keymap, +			       struct input_dev *input_dev) +{ +	unsigned int row_shift = get_count_order(cols); +	int i; + +	input_dev->keycode = keymap; +	input_dev->keycodesize = sizeof(*keymap); +	input_dev->keycodemax = rows << row_shift; + +	__set_bit(EV_KEY, input_dev->evbit); + +	for (i = 0; i < keymap_data->keymap_size; i++) { +		unsigned int key = keymap_data->keymap[i]; +		unsigned int row = KEY_ROW(key); +		unsigned int col = KEY_COL(key); +		unsigned short code = KEY_VAL(key); + +		if (row >= rows || col >= cols) { +			dev_err(input_dev->dev.parent, +				"%s: invalid keymap entry %d (row: %d, col: %d, rows: %d, cols: %d)\n", +				__func__, i, row, col, rows, cols); +			return -EINVAL; +		} + +		keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code; +		__set_bit(code, input_dev->keybit); +	} +	__clear_bit(KEY_RESERVED, input_dev->keybit); + +	return 0; +} +EXPORT_SYMBOL(matrix_keypad_build_keymap); +#ifdef CONFIG_OF  struct matrix_keymap_data *  matrix_keyboard_of_fill_keymap(struct device_node *np,  			       const char *propname) @@ -85,3 +139,4 @@ void matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd)  	}  }  EXPORT_SYMBOL_GPL(matrix_keyboard_of_free_keymap); +#endif diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 6c07ced0af8..e8fe08ebc24 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -75,39 +75,13 @@ struct matrix_keypad_platform_data {  	bool		no_autorepeat;  }; -/** - * matrix_keypad_build_keymap - convert platform keymap into matrix keymap - * @keymap_data: keymap supplied by the platform code - * @row_shift: number of bits to shift row value by to advance to the next - * line in the keymap - * @keymap: expanded version of keymap that is suitable for use by - * matrix keyboad driver - * @keybit: pointer to bitmap of keys supported by input device - * - * This function converts platform keymap (encoded with KEY() macro) into - * an array of keycodes that is suitable for using in a standard matrix - * keyboard driver that uses row and col as indices. - */ -static inline void -matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, -			   unsigned int row_shift, -			   unsigned short *keymap, unsigned long *keybit) -{ -	int i; - -	for (i = 0; i < keymap_data->keymap_size; i++) { -		unsigned int key = keymap_data->keymap[i]; -		unsigned int row = KEY_ROW(key); -		unsigned int col = KEY_COL(key); -		unsigned short code = KEY_VAL(key); - -		keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code; -		__set_bit(code, keybit); -	} -	__clear_bit(KEY_RESERVED, keybit); -} +int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, +			       const char *keymap_name, +			       unsigned int rows, unsigned int cols, +			       unsigned short *keymap, +			       struct input_dev *input_dev); -#ifdef CONFIG_INPUT_OF_MATRIX_KEYMAP +#ifdef CONFIG_OF  struct matrix_keymap_data *  matrix_keyboard_of_fill_keymap(struct device_node *np, const char *propname);  |