summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-ux500/board-u5500.c10
-rw-r--r--drivers/input/misc/ab8500-ponkey.c52
-rw-r--r--include/linux/mfd/abx500.h3
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);