Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318323
b: refs/heads/master
c: 8314f53
h: refs/heads/master
i:
  318321: 7ccaa57
  318319: 018e027
v: v3
  • Loading branch information
Shiraz Hashim authored and Dmitry Torokhov committed Jul 13, 2012
1 parent a9dd9b7 commit 9658af4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 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: 53fe628558bab9a11050ba067a09442c92dca6bb
refs/heads/master: 8314f532ebd55f1d6dc23b143cda3c1714ffe201
2 changes: 2 additions & 0 deletions trunk/arch/arm/plat-spear/include/plat/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ int _name[] = { \
* keymap: pointer to keymap data (table and size)
* rep: enables key autorepeat
* mode: choose keyboard support(9x9, 6x6, 2x2)
* suspended_rate: rate at which keyboard would operate in suspended mode
*
* This structure is supposed to be used by platform code to supply
* keymaps to drivers that implement keyboards.
Expand All @@ -157,6 +158,7 @@ struct kbd_platform_data {
const struct matrix_keymap_data *keymap;
bool rep;
unsigned int mode;
unsigned int suspended_rate;
};

#endif /* __PLAT_KEYBOARD_H */
46 changes: 44 additions & 2 deletions trunk/drivers/input/keyboard/spear-keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct spear_kbd {
unsigned short last_key;
unsigned short keycodes[NUM_ROWS * NUM_COLS];
bool rep;
unsigned int suspended_rate;
u32 mode_ctl_reg;
};

static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
Expand Down Expand Up @@ -149,7 +151,7 @@ static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
{
struct device_node *np = pdev->dev.of_node;
int error;
u32 val;
u32 val, suspended_rate;

if (!np) {
dev_err(&pdev->dev, "Missing DT data\n");
Expand All @@ -159,6 +161,9 @@ static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
if (of_property_read_bool(np, "autorepeat"))
kbd->rep = true;

if (of_property_read_u32(np, "suspended_rate", &suspended_rate))
kbd->suspended_rate = suspended_rate;

error = of_property_read_u32(np, "st,mode", &val);
if (error) {
dev_err(&pdev->dev, "DT: Invalid or missing mode\n");
Expand Down Expand Up @@ -216,6 +221,7 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev)
} else {
kbd->mode = pdata->mode;
kbd->rep = pdata->rep;
kbd->suspended_rate = pdata->suspended_rate;
}

kbd->res = request_mem_region(res->start, resource_size(res),
Expand Down Expand Up @@ -317,16 +323,48 @@ static int spear_kbd_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct spear_kbd *kbd = platform_get_drvdata(pdev);
struct input_dev *input_dev = kbd->input;
unsigned int rate = 0, mode_ctl_reg, val;

mutex_lock(&input_dev->mutex);

/* explicitly enable clock as we may program device */
clk_enable(kbd->clk);

mode_ctl_reg = readl_relaxed(kbd->io_base + MODE_CTL_REG);

if (device_may_wakeup(&pdev->dev)) {
enable_irq_wake(kbd->irq);

/*
* reprogram the keyboard operating frequency as on some
* platform it may change during system suspended
*/
if (kbd->suspended_rate)
rate = kbd->suspended_rate / 1000000 - 1;
else
rate = clk_get_rate(kbd->clk) / 1000000 - 1;

val = mode_ctl_reg &
~(MODE_CTL_PCLK_FREQ_MSK << MODE_CTL_PCLK_FREQ_SHIFT);
val |= (rate & MODE_CTL_PCLK_FREQ_MSK)
<< MODE_CTL_PCLK_FREQ_SHIFT;
writel_relaxed(val, kbd->io_base + MODE_CTL_REG);

} else {
if (input_dev->users)
if (input_dev->users) {
writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN,
kbd->io_base + MODE_CTL_REG);
clk_disable(kbd->clk);
}
}

/* store current configuration */
if (input_dev->users)
kbd->mode_ctl_reg = mode_ctl_reg;

/* restore previous clk state */
clk_disable(kbd->clk);

mutex_unlock(&input_dev->mutex);

return 0;
Expand All @@ -347,6 +385,10 @@ static int spear_kbd_resume(struct device *dev)
clk_enable(kbd->clk);
}

/* restore current configuration */
if (input_dev->users)
writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG);

mutex_unlock(&input_dev->mutex);

return 0;
Expand Down

0 comments on commit 9658af4

Please sign in to comment.