1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ON pin driver for Dialog DA9052 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>
13 #include <linux/workqueue.h>
15 #include <linux/mfd/da9052/da9052.h>
16 #include <linux/mfd/da9052/reg.h>
19 struct da9052
*da9052
;
20 struct input_dev
*input
;
21 struct delayed_work work
;
24 static void da9052_onkey_query(struct da9052_onkey
*onkey
)
28 ret
= da9052_reg_read(onkey
->da9052
, DA9052_STATUS_A_REG
);
30 dev_err(onkey
->da9052
->dev
,
31 "Failed to read onkey event err=%d\n", ret
);
34 * Since interrupt for deassertion of ONKEY pin is not
35 * generated, onkey event state determines the onkey
38 bool pressed
= !(ret
& DA9052_STATUSA_NONKEY
);
40 input_report_key(onkey
->input
, KEY_POWER
, pressed
);
41 input_sync(onkey
->input
);
44 * Interrupt is generated only when the ONKEY pin
45 * is asserted. Hence the deassertion of the pin
46 * is simulated through work queue.
49 schedule_delayed_work(&onkey
->work
,
50 msecs_to_jiffies(50));
54 static void da9052_onkey_work(struct work_struct
*work
)
56 struct da9052_onkey
*onkey
= container_of(work
, struct da9052_onkey
,
59 da9052_onkey_query(onkey
);
62 static irqreturn_t
da9052_onkey_irq(int irq
, void *data
)
64 struct da9052_onkey
*onkey
= data
;
66 da9052_onkey_query(onkey
);
71 static int da9052_onkey_probe(struct platform_device
*pdev
)
73 struct da9052
*da9052
= dev_get_drvdata(pdev
->dev
.parent
);
74 struct da9052_onkey
*onkey
;
75 struct input_dev
*input_dev
;
79 dev_err(&pdev
->dev
, "Failed to get the driver's data\n");
83 onkey
= kzalloc(sizeof(*onkey
), GFP_KERNEL
);
84 input_dev
= input_allocate_device();
85 if (!onkey
|| !input_dev
) {
86 dev_err(&pdev
->dev
, "Failed to allocate memory\n");
91 onkey
->input
= input_dev
;
92 onkey
->da9052
= da9052
;
93 INIT_DELAYED_WORK(&onkey
->work
, da9052_onkey_work
);
95 input_dev
->name
= "da9052-onkey";
96 input_dev
->phys
= "da9052-onkey/input0";
97 input_dev
->dev
.parent
= &pdev
->dev
;
99 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
);
100 __set_bit(KEY_POWER
, input_dev
->keybit
);
102 error
= da9052_request_irq(onkey
->da9052
, DA9052_IRQ_NONKEY
, "ONKEY",
103 da9052_onkey_irq
, onkey
);
105 dev_err(onkey
->da9052
->dev
,
106 "Failed to register ONKEY IRQ: %d\n", error
);
110 error
= input_register_device(onkey
->input
);
112 dev_err(&pdev
->dev
, "Unable to register input device, %d\n",
117 platform_set_drvdata(pdev
, onkey
);
121 da9052_free_irq(onkey
->da9052
, DA9052_IRQ_NONKEY
, onkey
);
122 cancel_delayed_work_sync(&onkey
->work
);
124 input_free_device(input_dev
);
130 static int da9052_onkey_remove(struct platform_device
*pdev
)
132 struct da9052_onkey
*onkey
= platform_get_drvdata(pdev
);
134 da9052_free_irq(onkey
->da9052
, DA9052_IRQ_NONKEY
, onkey
);
135 cancel_delayed_work_sync(&onkey
->work
);
137 input_unregister_device(onkey
->input
);
143 static struct platform_driver da9052_onkey_driver
= {
144 .probe
= da9052_onkey_probe
,
145 .remove
= da9052_onkey_remove
,
147 .name
= "da9052-onkey",
150 module_platform_driver(da9052_onkey_driver
);
152 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
153 MODULE_DESCRIPTION("Onkey driver for DA9052");
154 MODULE_LICENSE("GPL");
155 MODULE_ALIAS("platform:da9052-onkey");