diff options
-rw-r--r-- | arch/arm/mach-ux500/board-u5500.c | 10 | ||||
-rw-r--r-- | drivers/input/misc/ab8500-ponkey.c | 52 | ||||
-rw-r--r-- | include/linux/mfd/abx500.h | 3 |
3 files changed, 65 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 6d6b5f29242..5f637642721 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -123,6 +123,14 @@ static struct ab5500_hvleds_platform_data ab5500_hvleds_data = { }, }; +static struct ab5500_ponkey_platform_data ab5500_ponkey_data = { + /* + * Shutdown time in secs. Can be set + * to 10sec, 5sec and 0sec(disabled) + */ + .shutdown_secs = 10, +}; + /* * I2C */ @@ -359,6 +367,8 @@ static struct ab5500_platform_data ab5500_plf_data = { .dev_data[AB5500_DEVID_BTEMP] = &abx500_bm_pt_data, .dev_data_sz[AB5500_DEVID_BTEMP] = sizeof(abx500_bm_pt_data), #endif + .dev_data[AB5500_DEVID_ONSWA] = &ab5500_ponkey_data, + .dev_data_sz[AB5500_DEVID_ONSWA] = sizeof(ab5500_ponkey_data), }; static struct platform_device u5500_ab5500_device = { diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 39964956de2..251408b95c9 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -12,15 +12,28 @@ #include <linux/input.h> #include <linux/interrupt.h> #include <linux/slab.h> +#include <linux/mfd/abx500.h> + +/* Ponkey time control bits */ +#define AB5500_MCB 0x2F +#define AB5500_PONKEY_10SEC 0x0 +#define AB5500_PONKEY_5SEC 0x1 +#define AB5500_PONKEY_DISABLE 0x2 +#define AB5500_PONKEY_TMR_MASK 0x1 +#define AB5500_PONKEY_TR_MASK 0x2 + +static int ab5500_ponkey_hw_init(struct platform_device *); struct ab8500_ponkey_variant { const char *irq_falling; const char *irq_rising; + int (*hw_init)(struct platform_device *); }; static const struct ab8500_ponkey_variant ab5500_onswa = { .irq_falling = "ONSWAn_falling", .irq_rising = "ONSWAn_rising", + .hw_init = ab5500_ponkey_hw_init, }; static const struct ab8500_ponkey_variant ab8500_ponkey = { @@ -40,6 +53,37 @@ struct ab8500_ponkey_info { int irq_dbr; }; +static int ab5500_ponkey_hw_init(struct platform_device *pdev) +{ + u8 val; + struct ab5500_ponkey_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (pdata) { + switch (pdata->shutdown_secs) { + case 0: + val = AB5500_PONKEY_DISABLE; + break; + case 5: + val = AB5500_PONKEY_5SEC; + break; + case 10: + val = AB5500_PONKEY_10SEC; + break; + default: + val = AB5500_PONKEY_10SEC; + } + } else { + val = AB5500_PONKEY_10SEC; + } + return abx500_mask_and_set( + &pdev->dev, + AB5500_BANK_STARTUP, + AB5500_MCB, + AB5500_PONKEY_TMR_MASK | AB5500_PONKEY_TR_MASK, + val); +} + /* AB8500 gives us an interrupt when ONKEY is held */ static irqreturn_t ab8500_ponkey_handler(int irq, void *data) { @@ -64,6 +108,14 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) variant = (const struct ab8500_ponkey_variant *) pdev->id_entry->driver_data; + if (variant->hw_init) { + ret = variant->hw_init(pdev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to init hw"); + return ret; + } + } + irq_dbf = platform_get_irq_byname(pdev, variant->irq_falling); if (irq_dbf < 0) { dev_err(&pdev->dev, "No IRQ for %s: %d\n", diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 1d96d4f1bcc..79b3e9eb4f3 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -369,6 +369,9 @@ struct ab5500_platform_data { struct ab5500_regulator_platform_data *regulator; }; +struct ab5500_ponkey_platform_data { + u8 shutdown_secs; +}; int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, u8 value); |