Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 306621
b: refs/heads/master
c: f77621c
h: refs/heads/master
i:
  306619: 397d62b
v: v3
  • Loading branch information
Poddar, Sourav authored and Dmitry Torokhov committed May 11, 2012
1 parent fe5cc76 commit fdbf159
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1a49a0a04d13049ac4f90d2e61da9b29a36962f7
refs/heads/master: f77621cc640a7c50b3d8c5254ecc5d91eaa99d0d
4 changes: 2 additions & 2 deletions trunk/drivers/input/keyboard/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,9 @@ config KEYBOARD_OMAP
module will be called omap-keypad.

config KEYBOARD_OMAP4
tristate "TI OMAP4 keypad support"
tristate "TI OMAP4+ keypad support"
help
Say Y here if you want to use the OMAP4 keypad.
Say Y here if you want to use the OMAP4+ keypad.

To compile this driver as a module, choose M here: the
module will be called omap4-keypad.
Expand Down
118 changes: 92 additions & 26 deletions trunk/drivers/input/keyboard/omap4-keypad.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,52 @@

#define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF

enum {
KBD_REVISION_OMAP4 = 0,
KBD_REVISION_OMAP5,
};

struct omap4_keypad {
struct input_dev *input;

void __iomem *base;
int irq;
unsigned int irq;

unsigned int rows;
unsigned int cols;
u32 reg_offset;
u32 irqreg_offset;
unsigned int row_shift;
unsigned char key_state[8];
unsigned short keymap[];
};

static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset)
{
return __raw_readl(keypad_data->base +
keypad_data->reg_offset + offset);
}

static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value)
{
__raw_writel(value,
keypad_data->base + keypad_data->reg_offset + offset);
}

static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset)
{
return __raw_readl(keypad_data->base +
keypad_data->irqreg_offset + offset);
}

static void kbd_write_irqreg(struct omap4_keypad *keypad_data,
u32 offset, u32 value)
{
__raw_writel(value,
keypad_data->base + keypad_data->irqreg_offset + offset);
}


/* Interrupt handler */
static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
{
Expand All @@ -91,12 +124,11 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
u32 *new_state = (u32 *) key_state;

/* Disable interrupts */
__raw_writel(OMAP4_VAL_IRQDISABLE,
keypad_data->base + OMAP4_KBD_IRQENABLE);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
OMAP4_VAL_IRQDISABLE);

*new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0);
*(new_state + 1) = __raw_readl(keypad_data->base
+ OMAP4_KBD_FULLCODE63_32);
*new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
*(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);

for (row = 0; row < keypad_data->rows; row++) {
changed = key_state[row] ^ keypad_data->key_state[row];
Expand All @@ -121,12 +153,13 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
sizeof(keypad_data->key_state));

/* clear pending interrupts */
__raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS),
keypad_data->base + OMAP4_KBD_IRQSTATUS);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));

/* enable interrupts */
__raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
keypad_data->base + OMAP4_KBD_IRQENABLE);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
OMAP4_DEF_IRQENABLE_EVENTEN |
OMAP4_DEF_IRQENABLE_LONGKEY);

return IRQ_HANDLED;
}
Expand All @@ -139,16 +172,17 @@ static int omap4_keypad_open(struct input_dev *input)

disable_irq(keypad_data->irq);

__raw_writel(OMAP4_VAL_FUNCTIONALCFG,
keypad_data->base + OMAP4_KBD_CTRL);
__raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME);
__raw_writel(OMAP4_VAL_IRQDISABLE,
keypad_data->base + OMAP4_KBD_IRQSTATUS);
__raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
keypad_data->base + OMAP4_KBD_IRQENABLE);
__raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA,
keypad_data->base + OMAP4_KBD_WAKEUPENABLE);
kbd_writel(keypad_data, OMAP4_KBD_CTRL,
OMAP4_VAL_FUNCTIONALCFG);
kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME,
OMAP4_VAL_DEBOUNCINGTIME);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
OMAP4_VAL_IRQDISABLE);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
OMAP4_DEF_IRQENABLE_EVENTEN |
OMAP4_DEF_IRQENABLE_LONGKEY);
kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE,
OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA);

enable_irq(keypad_data->irq);

Expand All @@ -162,12 +196,12 @@ static void omap4_keypad_close(struct input_dev *input)
disable_irq(keypad_data->irq);

/* Disable interrupts */
__raw_writel(OMAP4_VAL_IRQDISABLE,
keypad_data->base + OMAP4_KBD_IRQENABLE);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE,
OMAP4_VAL_IRQDISABLE);

/* clear pending interrupts */
__raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS),
keypad_data->base + OMAP4_KBD_IRQSTATUS);
kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS,
kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS));

enable_irq(keypad_data->irq);

Expand All @@ -182,6 +216,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
struct resource *res;
resource_size_t size;
unsigned int row_shift, max_keys;
int rev;
int irq;
int error;

Expand Down Expand Up @@ -241,11 +276,40 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
keypad_data->rows = pdata->rows;
keypad_data->cols = pdata->cols;

/*
* Enable clocks for the keypad module so that we can read
* revision register.
*/
pm_runtime_enable(&pdev->dev);
error = pm_runtime_get_sync(&pdev->dev);
if (error) {
dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
goto err_unmap;
}
rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION);
rev &= 0x03 << 30;
rev >>= 30;
switch (rev) {
case KBD_REVISION_OMAP4:
keypad_data->reg_offset = 0x00;
keypad_data->irqreg_offset = 0x00;
break;
case KBD_REVISION_OMAP5:
keypad_data->reg_offset = 0x10;
keypad_data->irqreg_offset = 0x0c;
break;
default:
dev_err(&pdev->dev,
"Keypad reports unsupported revision %d", rev);
error = -EINVAL;
goto err_pm_put_sync;
}

/* input device allocation */
keypad_data->input = input_dev = input_allocate_device();
if (!input_dev) {
error = -ENOMEM;
goto err_unmap;
goto err_pm_put_sync;
}

input_dev->name = pdev->name;
Expand Down Expand Up @@ -280,7 +344,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
goto err_free_input;
}

pm_runtime_enable(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);

error = input_register_device(keypad_data->input);
if (error < 0) {
Expand All @@ -296,6 +360,8 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
free_irq(keypad_data->irq, keypad_data);
err_free_input:
input_free_device(input_dev);
err_pm_put_sync:
pm_runtime_put_sync(&pdev->dev);
err_unmap:
iounmap(keypad_data->base);
err_release_mem:
Expand Down

0 comments on commit fdbf159

Please sign in to comment.