Commit 60214f05 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Dmitry Torokhov

Input: ep93xx_keypad - update driver to new core support

This driver was merged before the ep93xx core support was added
for the keypad clock and acquiring/releasing the necessary gpio's.
Now that the proper support is in the ep93xx core this driver
needs to be updated to work correctly.

Summary of changes:
  1) Remove some unused members from the platform data.
  2) Remove the custom KEY macro and use the ones available in
     <linux/input/matrix_keypad.h>
  3) Remove the keypad_{readl/writel} macros and just use
     __raw_{readl/writel} directly.
  4) Update the clk_set_rate() call to work with the core support.
  5) Cleanup the probe routine and remove some unneeded messages.
  6) Use the ep93xx core functions to acquire and release the gpio's.
  7) Fix the clk_get() call to get the keypad clock.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 7547a3e8
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
#ifndef __ASM_ARCH_EP93XX_KEYPAD_H #ifndef __ASM_ARCH_EP93XX_KEYPAD_H
#define __ASM_ARCH_EP93XX_KEYPAD_H #define __ASM_ARCH_EP93XX_KEYPAD_H
#define MAX_MATRIX_KEY_ROWS (8)
#define MAX_MATRIX_KEY_COLS (8)
/* flags for the ep93xx_keypad driver */ /* flags for the ep93xx_keypad driver */
#define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */ #define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */
#define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */ #define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */
...@@ -18,8 +15,6 @@ ...@@ -18,8 +15,6 @@
/** /**
* struct ep93xx_keypad_platform_data - platform specific device structure * struct ep93xx_keypad_platform_data - platform specific device structure
* @matrix_key_rows: number of rows in the keypad matrix
* @matrix_key_cols: number of columns in the keypad matrix
* @matrix_key_map: array of keycodes defining the keypad matrix * @matrix_key_map: array of keycodes defining the keypad matrix
* @matrix_key_map_size: ARRAY_SIZE(matrix_key_map) * @matrix_key_map_size: ARRAY_SIZE(matrix_key_map)
* @debounce: debounce start count; terminal count is 0xff * @debounce: debounce start count; terminal count is 0xff
...@@ -27,8 +22,6 @@ ...@@ -27,8 +22,6 @@
* @flags: see above * @flags: see above
*/ */
struct ep93xx_keypad_platform_data { struct ep93xx_keypad_platform_data {
unsigned int matrix_key_rows;
unsigned int matrix_key_cols;
unsigned int *matrix_key_map; unsigned int *matrix_key_map;
int matrix_key_map_size; int matrix_key_map_size;
unsigned int debounce; unsigned int debounce;
...@@ -36,7 +29,7 @@ struct ep93xx_keypad_platform_data { ...@@ -36,7 +29,7 @@ struct ep93xx_keypad_platform_data {
unsigned int flags; unsigned int flags;
}; };
/* macro for creating the matrix_key_map table */ #define EP93XX_MATRIX_ROWS (8)
#define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val)) #define EP93XX_MATRIX_COLS (8)
#endif /* __ASM_ARCH_EP93XX_KEYPAD_H */ #endif /* __ASM_ARCH_EP93XX_KEYPAD_H */
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h>
#include <linux/input/matrix_keypad.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio.h>
#include <mach/ep93xx_keypad.h> #include <mach/ep93xx_keypad.h>
/* /*
...@@ -60,38 +60,37 @@ ...@@ -60,38 +60,37 @@
#define KEY_REG_KEY1_MASK (0x0000003f) #define KEY_REG_KEY1_MASK (0x0000003f)
#define KEY_REG_KEY1_SHIFT (0) #define KEY_REG_KEY1_SHIFT (0)
#define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) #define EP93XX_MATRIX_SIZE (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
#define keypad_writel(v, off) __raw_writel((v), keypad->mmio_base + (off))
#define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
struct ep93xx_keypad { struct ep93xx_keypad {
struct ep93xx_keypad_platform_data *pdata; struct ep93xx_keypad_platform_data *pdata;
struct clk *clk;
struct input_dev *input_dev; struct input_dev *input_dev;
struct clk *clk;
void __iomem *mmio_base; void __iomem *mmio_base;
int irq; unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE];
int enabled;
int key1; int key1;
int key2; int key2;
unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; int irq;
bool enabled;
}; };
static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad)
{ {
struct ep93xx_keypad_platform_data *pdata = keypad->pdata; struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
struct input_dev *input_dev = keypad->input_dev; struct input_dev *input_dev = keypad->input_dev;
unsigned int *key;
int i; int i;
for (i = 0; i < pdata->matrix_key_map_size; i++) { key = &pdata->matrix_key_map[0];
unsigned int key = pdata->matrix_key_map[i]; for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
int row = (key >> 28) & 0xf; int row = KEY_ROW(*key);
int col = (key >> 24) & 0xf; int col = KEY_COL(*key);
int code = key & 0xffffff; int code = KEY_VAL(*key);
keypad->matrix_keycodes[(row << 3) + col] = code; keypad->matrix_keycodes[(row << 3) + col] = code;
__set_bit(code, input_dev->keybit); __set_bit(code, input_dev->keybit);
...@@ -102,9 +101,11 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) ...@@ -102,9 +101,11 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
{ {
struct ep93xx_keypad *keypad = dev_id; struct ep93xx_keypad *keypad = dev_id;
struct input_dev *input_dev = keypad->input_dev; struct input_dev *input_dev = keypad->input_dev;
unsigned int status = keypad_readl(KEY_REG); unsigned int status;
int keycode, key1, key2; int keycode, key1, key2;
status = __raw_readl(keypad->mmio_base + KEY_REG);
keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
key1 = keypad->matrix_keycodes[keycode]; key1 = keypad->matrix_keycodes[keycode];
...@@ -152,7 +153,10 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) ...@@ -152,7 +153,10 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
struct ep93xx_keypad_platform_data *pdata = keypad->pdata; struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
unsigned int val = 0; unsigned int val = 0;
clk_set_rate(keypad->clk, pdata->flags & EP93XX_KEYPAD_KDIV); if (pdata->flags & EP93XX_KEYPAD_KDIV)
clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV4);
else
clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV16);
if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY) if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY)
val |= KEY_INIT_DIS3KY; val |= KEY_INIT_DIS3KY;
...@@ -167,7 +171,7 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) ...@@ -167,7 +171,7 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK); val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK);
keypad_writel(val, KEY_INIT); __raw_writel(val, keypad->mmio_base + KEY_INIT);
} }
static int ep93xx_keypad_open(struct input_dev *pdev) static int ep93xx_keypad_open(struct input_dev *pdev)
...@@ -177,7 +181,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev) ...@@ -177,7 +181,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev)
if (!keypad->enabled) { if (!keypad->enabled) {
ep93xx_keypad_config(keypad); ep93xx_keypad_config(keypad);
clk_enable(keypad->clk); clk_enable(keypad->clk);
keypad->enabled = 1; keypad->enabled = true;
} }
return 0; return 0;
...@@ -189,7 +193,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev) ...@@ -189,7 +193,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev)
if (keypad->enabled) { if (keypad->enabled) {
clk_disable(keypad->clk); clk_disable(keypad->clk);
keypad->enabled = 0; keypad->enabled = false;
} }
} }
...@@ -211,7 +215,7 @@ static int ep93xx_keypad_suspend(struct platform_device *pdev, ...@@ -211,7 +215,7 @@ static int ep93xx_keypad_suspend(struct platform_device *pdev,
if (keypad->enabled) { if (keypad->enabled) {
clk_disable(keypad->clk); clk_disable(keypad->clk);
keypad->enabled = 0; keypad->enabled = false;
} }
mutex_unlock(&input_dev->mutex); mutex_unlock(&input_dev->mutex);
...@@ -236,7 +240,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) ...@@ -236,7 +240,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev)
if (!keypad->enabled) { if (!keypad->enabled) {
ep93xx_keypad_config(keypad); ep93xx_keypad_config(keypad);
clk_enable(keypad->clk); clk_enable(keypad->clk);
keypad->enabled = 1; keypad->enabled = true;
} }
} }
...@@ -252,88 +256,56 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) ...@@ -252,88 +256,56 @@ static int ep93xx_keypad_resume(struct platform_device *pdev)
static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
{ {
struct ep93xx_keypad *keypad; struct ep93xx_keypad *keypad;
struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input_dev; struct input_dev *input_dev;
struct resource *res; struct resource *res;
int irq, err, i, gpio; int err;
if (!pdata ||
!pdata->matrix_key_rows ||
pdata->matrix_key_rows > MAX_MATRIX_KEY_ROWS ||
!pdata->matrix_key_cols ||
pdata->matrix_key_cols > MAX_MATRIX_KEY_COLS) {
dev_err(&pdev->dev, "invalid or missing platform data\n");
return -EINVAL;
}
keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL); keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL);
if (!keypad) { if (!keypad)
dev_err(&pdev->dev, "failed to allocate driver data\n");
return -ENOMEM; return -ENOMEM;
}
keypad->pdata = pdata; keypad->pdata = pdev->dev.platform_data;
if (!keypad->pdata) {
err = -EINVAL;
goto failed_free;
}
irq = platform_get_irq(pdev, 0); keypad->irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (!keypad->irq) {
dev_err(&pdev->dev, "failed to get keypad irq\n");
err = -ENXIO; err = -ENXIO;
goto failed_free; goto failed_free;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res) {
dev_err(&pdev->dev, "failed to get I/O memory\n");
err = -ENXIO; err = -ENXIO;
goto failed_free; goto failed_free;
} }
res = request_mem_region(res->start, resource_size(res), pdev->name); res = request_mem_region(res->start, resource_size(res), pdev->name);
if (!res) { if (!res) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
err = -EBUSY; err = -EBUSY;
goto failed_free; goto failed_free;
} }
keypad->mmio_base = ioremap(res->start, resource_size(res)); keypad->mmio_base = ioremap(res->start, resource_size(res));
if (keypad->mmio_base == NULL) { if (keypad->mmio_base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
err = -ENXIO; err = -ENXIO;
goto failed_free_mem; goto failed_free_mem;
} }
/* Request the needed GPIO's */ err = ep93xx_keypad_acquire_gpio(pdev);
gpio = EP93XX_GPIO_LINE_ROW0; if (err)
for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) { goto failed_free_io;
err = gpio_request(gpio, pdev->name);
if (err) {
dev_err(&pdev->dev, "failed to request gpio-%d\n",
gpio);
goto failed_free_rows;
}
}
gpio = EP93XX_GPIO_LINE_COL0;
for (i = 0; i < keypad->pdata->matrix_key_cols; i++, gpio++) {
err = gpio_request(gpio, pdev->name);
if (err) {
dev_err(&pdev->dev, "failed to request gpio-%d\n",
gpio);
goto failed_free_cols;
}
}
keypad->clk = clk_get(&pdev->dev, "key_clk"); keypad->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(keypad->clk)) { if (IS_ERR(keypad->clk)) {
dev_err(&pdev->dev, "failed to get keypad clock\n");
err = PTR_ERR(keypad->clk); err = PTR_ERR(keypad->clk);
goto failed_free_io; goto failed_free_gpio;
} }
/* Create and register the input driver */
input_dev = input_allocate_device(); input_dev = input_allocate_device();
if (!input_dev) { if (!input_dev) {
dev_err(&pdev->dev, "failed to allocate input device\n");
err = -ENOMEM; err = -ENOMEM;
goto failed_put_clk; goto failed_put_clk;
} }
...@@ -358,44 +330,29 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -358,44 +330,29 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
ep93xx_keypad_build_keycode(keypad); ep93xx_keypad_build_keycode(keypad);
platform_set_drvdata(pdev, keypad); platform_set_drvdata(pdev, keypad);
err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED, err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
pdev->name, keypad); IRQF_DISABLED, pdev->name, keypad);
if (err) { if (err)
dev_err(&pdev->dev, "failed to request IRQ\n");
goto failed_free_dev; goto failed_free_dev;
}
keypad->irq = irq;
/* Register the input device */
err = input_register_device(input_dev); err = input_register_device(input_dev);
if (err) { if (err)
dev_err(&pdev->dev, "failed to register input device\n");
goto failed_free_irq; goto failed_free_irq;
}
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
return 0; return 0;
failed_free_irq: failed_free_irq:
free_irq(irq, pdev); free_irq(keypad->irq, pdev);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
failed_free_dev: failed_free_dev:
input_free_device(input_dev); input_free_device(input_dev);
failed_put_clk: failed_put_clk:
clk_put(keypad->clk); clk_put(keypad->clk);
failed_free_gpio:
ep93xx_keypad_release_gpio(pdev);
failed_free_io: failed_free_io:
i = keypad->pdata->matrix_key_cols - 1;
gpio = EP93XX_GPIO_LINE_COL0 + i;
failed_free_cols:
for ( ; i >= 0; i--, gpio--)
gpio_free(gpio);
i = keypad->pdata->matrix_key_rows - 1;
gpio = EP93XX_GPIO_LINE_ROW0 + i;
failed_free_rows:
for ( ; i >= 0; i--, gpio--)
gpio_free(gpio);
iounmap(keypad->mmio_base); iounmap(keypad->mmio_base);
failed_free_mem: failed_free_mem:
release_mem_region(res->start, resource_size(res)); release_mem_region(res->start, resource_size(res));
...@@ -408,7 +365,6 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) ...@@ -408,7 +365,6 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev)
{ {
struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
struct resource *res; struct resource *res;
int i, gpio;
free_irq(keypad->irq, pdev); free_irq(keypad->irq, pdev);
...@@ -420,15 +376,7 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) ...@@ -420,15 +376,7 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev)
input_unregister_device(keypad->input_dev); input_unregister_device(keypad->input_dev);
i = keypad->pdata->matrix_key_cols - 1; ep93xx_keypad_release_gpio(pdev);
gpio = EP93XX_GPIO_LINE_COL0 + i;
for ( ; i >= 0; i--, gpio--)
gpio_free(gpio);
i = keypad->pdata->matrix_key_rows - 1;
gpio = EP93XX_GPIO_LINE_ROW0 + i;
for ( ; i >= 0; i--, gpio--)
gpio_free(gpio);
iounmap(keypad->mmio_base); iounmap(keypad->mmio_base);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment