xref: /rk3399_rockchip-uboot/drivers/input/gpio_key.c (revision f05ce84792cbd2e5573a414010d421eb8fbb7689)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <dm.h>
8 #include <adc.h>
9 #include <common.h>
10 #include <console.h>
11 #include <dm.h>
12 #include <errno.h>
13 #include <fdtdec.h>
14 #include <malloc.h>
15 #include <key.h>
16 #include <linux/input.h>
17 #include <errno.h>
18 #include <dm/read.h>
19 #include <irq-generic.h>
20 #include <irq-platform.h>
21 
22 static void gpio_irq_handler(int irq, void *data)
23 {
24 	struct input_key *key = data;
25 
26 	if (key->irq != irq)
27 		return;
28 
29 	/* up event */
30 	if (irq_get_gpio_level(irq)) {
31 		key->up_t = key_timer(0);
32 		debug("%s: key down: %llu ms\n", key->name, key->down_t);
33 	/* down event */
34 	} else {
35 		key->down_t = key_timer(0);
36 		debug("%s: key up: %llu ms\n", key->name, key->up_t);
37 	}
38 	/* Must delay */
39 	mdelay(10);
40 	irq_revert_irq_type(irq);
41 }
42 
43 static int gpio_key_ofdata_to_platdata(struct udevice *dev)
44 {
45 	struct input_key *key;
46 	u32 gpios[2];
47 	ofnode node;
48 	int irq, ret;
49 
50 	dev_for_each_subnode(node, dev) {
51 		key = calloc(1, sizeof(struct input_key));
52 		if (!key)
53 			return -ENOMEM;
54 
55 		key->parent = dev;
56 		key->type = GPIO_KEY;
57 		key->name = ofnode_read_string(node, "label");
58 		ret = ofnode_read_u32(node, "linux,code", &key->code);
59 		if (ret) {
60 			printf("%s: failed read 'linux,code', ret=%d\n",
61 			       key->name, ret);
62 			free(key);
63 			continue;
64 		}
65 
66 		/* Only register power key as interrupt */
67 		if (key->code == KEY_POWER) {
68 			ret = ofnode_read_u32_array(node, "gpios", gpios, 2);
69 			if (ret) {
70 				printf("%s: failed to read 'gpios', ret=%d\n",
71 				       key->name, ret);
72 				free(key);
73 				continue;
74 			}
75 
76 			/* Must register as interrupt, be able to wakeup system */
77 			irq = phandle_gpio_to_irq(gpios[0], gpios[1]);
78 			if (irq < 0) {
79 				printf("%s: failed to request irq, ret=%d\n",
80 				       key->name, irq);
81 				free(key);
82 				continue;
83 			}
84 			key->irq = irq;
85 			key_add(key);
86 			irq_install_handler(irq, gpio_irq_handler, key);
87 			irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
88 			irq_handler_enable(irq);
89 		} else {
90 			ret = gpio_request_by_name_nodev(node, "gpios", 0,
91 							 &key->gpio,
92 							 GPIOD_IS_IN);
93 			if (ret) {
94 				printf("%s: failed to request gpio, ret=%d\n",
95 				       key->name, ret);
96 			}
97 
98 			key_add(key);
99 		}
100 
101 		debug("%s: name=%s: code=%d\n", __func__, key->name, key->code);
102 	}
103 
104 	return 0;
105 }
106 
107 static const struct dm_key_ops key_ops = {
108 	.name = "gpio-keys",
109 };
110 
111 static const struct udevice_id gpio_key_ids[] = {
112 	{ .compatible = "gpio-keys" },
113 	{ },
114 };
115 
116 U_BOOT_DRIVER(gpio_keys) = {
117 	.name   = "gpio-keys",
118 	.id     = UCLASS_KEY,
119 	.of_match = gpio_key_ids,
120 	.ops	= &key_ops,
121 	.ofdata_to_platdata = gpio_key_ofdata_to_platdata,
122 };
123