1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ON pin driver for Dialog DA9055 PMICs
5 * Copyright(c) 2012 Dialog Semiconductor Ltd.
7 * Author: David Dajun Chen <dchen@diasemi.com>
10 #include <linux/input.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
14 #include <linux/mfd/da9055/core.h>
15 #include <linux/mfd/da9055/reg.h>
18 struct da9055
*da9055
;
19 struct input_dev
*input
;
20 struct delayed_work work
;
23 static void da9055_onkey_query(struct da9055_onkey
*onkey
)
27 key_stat
= da9055_reg_read(onkey
->da9055
, DA9055_REG_STATUS_A
);
29 dev_err(onkey
->da9055
->dev
,
30 "Failed to read onkey event %d\n", key_stat
);
32 key_stat
&= DA9055_NOKEY_STS
;
34 * Onkey status bit is cleared when onkey button is released.
37 input_report_key(onkey
->input
, KEY_POWER
, 0);
38 input_sync(onkey
->input
);
43 * Interrupt is generated only when the ONKEY pin is asserted.
44 * Hence the deassertion of the pin is simulated through work queue.
47 schedule_delayed_work(&onkey
->work
, msecs_to_jiffies(10));
51 static void da9055_onkey_work(struct work_struct
*work
)
53 struct da9055_onkey
*onkey
= container_of(work
, struct da9055_onkey
,
56 da9055_onkey_query(onkey
);
59 static irqreturn_t
da9055_onkey_irq(int irq
, void *data
)
61 struct da9055_onkey
*onkey
= data
;
63 input_report_key(onkey
->input
, KEY_POWER
, 1);
64 input_sync(onkey
->input
);
66 da9055_onkey_query(onkey
);
71 static int da9055_onkey_probe(struct platform_device
*pdev
)
73 struct da9055
*da9055
= dev_get_drvdata(pdev
->dev
.parent
);
74 struct da9055_onkey
*onkey
;
75 struct input_dev
*input_dev
;
78 irq
= platform_get_irq_byname(pdev
, "ONKEY");
82 onkey
= devm_kzalloc(&pdev
->dev
, sizeof(*onkey
), GFP_KERNEL
);
84 dev_err(&pdev
->dev
, "Failed to allocate memory\n");
88 input_dev
= input_allocate_device();
90 dev_err(&pdev
->dev
, "Failed to allocate memory\n");
94 onkey
->input
= input_dev
;
95 onkey
->da9055
= da9055
;
96 input_dev
->name
= "da9055-onkey";
97 input_dev
->phys
= "da9055-onkey/input0";
98 input_dev
->dev
.parent
= &pdev
->dev
;
100 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
);
101 __set_bit(KEY_POWER
, input_dev
->keybit
);
103 INIT_DELAYED_WORK(&onkey
->work
, da9055_onkey_work
);
105 err
= request_threaded_irq(irq
, NULL
, da9055_onkey_irq
,
106 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
110 "Failed to register ONKEY IRQ %d, error = %d\n",
115 err
= input_register_device(input_dev
);
117 dev_err(&pdev
->dev
, "Unable to register input device, %d\n",
122 platform_set_drvdata(pdev
, onkey
);
127 free_irq(irq
, onkey
);
128 cancel_delayed_work_sync(&onkey
->work
);
130 input_free_device(input_dev
);
135 static int da9055_onkey_remove(struct platform_device
*pdev
)
137 struct da9055_onkey
*onkey
= platform_get_drvdata(pdev
);
138 int irq
= platform_get_irq_byname(pdev
, "ONKEY");
140 irq
= regmap_irq_get_virq(onkey
->da9055
->irq_data
, irq
);
141 free_irq(irq
, onkey
);
142 cancel_delayed_work_sync(&onkey
->work
);
143 input_unregister_device(onkey
->input
);
148 static struct platform_driver da9055_onkey_driver
= {
149 .probe
= da9055_onkey_probe
,
150 .remove
= da9055_onkey_remove
,
152 .name
= "da9055-onkey",
156 module_platform_driver(da9055_onkey_driver
);
158 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
159 MODULE_DESCRIPTION("Onkey driver for DA9055");
160 MODULE_LICENSE("GPL");
161 MODULE_ALIAS("platform:da9055-onkey");