Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (22 commits) Input: ALPS - add interleaved protocol support (Dell E6x00 series) Input: keyboard - don't override beep with a bell Input: altera_ps2 - fix test of unsigned in altera_ps2_probe() Input: add mc13783 touchscreen driver Input: ep93xx_keypad - update driver to new core support Input: wacom - separate pen from express keys on Graphire Input: wacom - add defines for data packet report IDs Input: wacom - add support for new LCD tablets Input: wacom - add defines for packet lengths of various devices Input: wacom - ensure the device is initialized properly upon resume Input: at32psif - do not sleep in atomic context Input: i8042 - add Gigabyte M1022M to the noloop list Input: i8042 - allow installing platform filters for incoming data Input: i8042 - fix locking in interrupt routine Input: ALPS - do not set REL_X/REL_Y capabilities on the touchpad Input: document use of input_event() function Input: sa1111ps2 - annotate probe() and remove() methods Input: ambakmi - annotate probe() and remove() methods Input: gscps2 - fix probe() and remove() annotations Input: altera_ps2 - add annotations to probe and remove methods ...
This commit is contained in:
@@ -22,11 +22,11 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/ep93xx_keypad.h>
|
||||
|
||||
/*
|
||||
@@ -60,38 +60,37 @@
|
||||
#define KEY_REG_KEY1_MASK (0x0000003f)
|
||||
#define KEY_REG_KEY1_SHIFT (0)
|
||||
|
||||
#define keypad_readl(off) __raw_readl(keypad->mmio_base + (off))
|
||||
#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)
|
||||
#define EP93XX_MATRIX_SIZE (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
|
||||
|
||||
struct ep93xx_keypad {
|
||||
struct ep93xx_keypad_platform_data *pdata;
|
||||
|
||||
struct clk *clk;
|
||||
struct input_dev *input_dev;
|
||||
struct clk *clk;
|
||||
|
||||
void __iomem *mmio_base;
|
||||
|
||||
int irq;
|
||||
int enabled;
|
||||
unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE];
|
||||
|
||||
int key1;
|
||||
int key2;
|
||||
|
||||
unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
|
||||
int irq;
|
||||
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad)
|
||||
{
|
||||
struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
|
||||
struct input_dev *input_dev = keypad->input_dev;
|
||||
unsigned int *key;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pdata->matrix_key_map_size; i++) {
|
||||
unsigned int key = pdata->matrix_key_map[i];
|
||||
int row = (key >> 28) & 0xf;
|
||||
int col = (key >> 24) & 0xf;
|
||||
int code = key & 0xffffff;
|
||||
key = &pdata->matrix_key_map[0];
|
||||
for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
|
||||
int row = KEY_ROW(*key);
|
||||
int col = KEY_COL(*key);
|
||||
int code = KEY_VAL(*key);
|
||||
|
||||
keypad->matrix_keycodes[(row << 3) + col] = code;
|
||||
__set_bit(code, input_dev->keybit);
|
||||
@@ -102,9 +101,11 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct ep93xx_keypad *keypad = dev_id;
|
||||
struct input_dev *input_dev = keypad->input_dev;
|
||||
unsigned int status = keypad_readl(KEY_REG);
|
||||
unsigned int status;
|
||||
int keycode, key1, key2;
|
||||
|
||||
status = __raw_readl(keypad->mmio_base + KEY_REG);
|
||||
|
||||
keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
|
||||
key1 = keypad->matrix_keycodes[keycode];
|
||||
|
||||
@@ -152,7 +153,10 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
|
||||
struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
|
||||
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)
|
||||
val |= KEY_INIT_DIS3KY;
|
||||
@@ -167,7 +171,7 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
|
||||
|
||||
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)
|
||||
@@ -177,7 +181,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev)
|
||||
if (!keypad->enabled) {
|
||||
ep93xx_keypad_config(keypad);
|
||||
clk_enable(keypad->clk);
|
||||
keypad->enabled = 1;
|
||||
keypad->enabled = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -189,7 +193,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev)
|
||||
|
||||
if (keypad->enabled) {
|
||||
clk_disable(keypad->clk);
|
||||
keypad->enabled = 0;
|
||||
keypad->enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +215,7 @@ static int ep93xx_keypad_suspend(struct platform_device *pdev,
|
||||
|
||||
if (keypad->enabled) {
|
||||
clk_disable(keypad->clk);
|
||||
keypad->enabled = 0;
|
||||
keypad->enabled = false;
|
||||
}
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
@@ -236,7 +240,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev)
|
||||
if (!keypad->enabled) {
|
||||
ep93xx_keypad_config(keypad);
|
||||
clk_enable(keypad->clk);
|
||||
keypad->enabled = 1;
|
||||
keypad->enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,88 +256,56 @@ static int ep93xx_keypad_resume(struct platform_device *pdev)
|
||||
static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ep93xx_keypad *keypad;
|
||||
struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct input_dev *input_dev;
|
||||
struct resource *res;
|
||||
int irq, err, i, gpio;
|
||||
|
||||
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;
|
||||
}
|
||||
int err;
|
||||
|
||||
keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL);
|
||||
if (!keypad) {
|
||||
dev_err(&pdev->dev, "failed to allocate driver data\n");
|
||||
if (!keypad)
|
||||
return -ENOMEM;
|
||||
|
||||
keypad->pdata = pdev->dev.platform_data;
|
||||
if (!keypad->pdata) {
|
||||
err = -EINVAL;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
keypad->pdata = pdata;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to get keypad irq\n");
|
||||
keypad->irq = platform_get_irq(pdev, 0);
|
||||
if (!keypad->irq) {
|
||||
err = -ENXIO;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to get I/O memory\n");
|
||||
err = -ENXIO;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
res = request_mem_region(res->start, resource_size(res), pdev->name);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to request I/O memory\n");
|
||||
err = -EBUSY;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
keypad->mmio_base = ioremap(res->start, resource_size(res));
|
||||
if (keypad->mmio_base == NULL) {
|
||||
dev_err(&pdev->dev, "failed to remap I/O memory\n");
|
||||
err = -ENXIO;
|
||||
goto failed_free_mem;
|
||||
}
|
||||
|
||||
/* Request the needed GPIO's */
|
||||
gpio = EP93XX_GPIO_LINE_ROW0;
|
||||
for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) {
|
||||
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");
|
||||
if (IS_ERR(keypad->clk)) {
|
||||
dev_err(&pdev->dev, "failed to get keypad clock\n");
|
||||
err = PTR_ERR(keypad->clk);
|
||||
err = ep93xx_keypad_acquire_gpio(pdev);
|
||||
if (err)
|
||||
goto failed_free_io;
|
||||
|
||||
keypad->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(keypad->clk)) {
|
||||
err = PTR_ERR(keypad->clk);
|
||||
goto failed_free_gpio;
|
||||
}
|
||||
|
||||
/* Create and register the input driver */
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
dev_err(&pdev->dev, "failed to allocate input device\n");
|
||||
err = -ENOMEM;
|
||||
goto failed_put_clk;
|
||||
}
|
||||
@@ -358,44 +330,29 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
|
||||
ep93xx_keypad_build_keycode(keypad);
|
||||
platform_set_drvdata(pdev, keypad);
|
||||
|
||||
err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED,
|
||||
pdev->name, keypad);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ\n");
|
||||
err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
|
||||
IRQF_DISABLED, pdev->name, keypad);
|
||||
if (err)
|
||||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
keypad->irq = irq;
|
||||
|
||||
/* Register the input device */
|
||||
err = input_register_device(input_dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to register input device\n");
|
||||
if (err)
|
||||
goto failed_free_irq;
|
||||
}
|
||||
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
failed_free_irq:
|
||||
free_irq(irq, pdev);
|
||||
free_irq(keypad->irq, pdev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
failed_free_dev:
|
||||
input_free_device(input_dev);
|
||||
failed_put_clk:
|
||||
clk_put(keypad->clk);
|
||||
failed_free_gpio:
|
||||
ep93xx_keypad_release_gpio(pdev);
|
||||
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);
|
||||
failed_free_mem:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
@@ -408,7 +365,6 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
int i, gpio;
|
||||
|
||||
free_irq(keypad->irq, pdev);
|
||||
|
||||
@@ -420,15 +376,7 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev)
|
||||
|
||||
input_unregister_device(keypad->input_dev);
|
||||
|
||||
i = keypad->pdata->matrix_key_cols - 1;
|
||||
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);
|
||||
ep93xx_keypad_release_gpio(pdev);
|
||||
|
||||
iounmap(keypad->mmio_base);
|
||||
|
||||
|
Verwijs in nieuw issue
Block a user