xref: /rk3399_rockchip-uboot/drivers/input/gpio_key.c (revision e7b5bb3cc9527752c2c01acb4325fc0721fb75aa)
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 #define MAX_KEY_NR	10
23 
24 struct gpio_key_priv {
25 	u32 key_nr;
26 };
27 
28 static void gpio_irq_handler(int irq, void *data)
29 {
30 	struct udevice *dev = data;
31 	struct gpio_key_priv *priv = dev_get_priv(dev);
32 	struct input_key *key = dev_get_platdata(dev);
33 	int i;
34 
35 	for (i = 0; i < priv->key_nr; i++) {
36 		if (key[i].irq != irq)
37 			continue;
38 
39 		/* up event */
40 		if (irq_get_gpio_level(irq)) {
41 			key[i].up_t = key_get_timer(0);
42 			debug("%s: key down: %llu ms\n",
43 			      key[i].name, key[i].down_t);
44 		/* down event */
45 		} else {
46 			key[i].down_t = key_get_timer(0);
47 			debug("%s: key up: %llu ms\n",
48 			      key[i].name, key[i].up_t);
49 		}
50 		/* Must delay */
51 		mdelay(10);
52 		irq_revert_irq_type(irq);
53 	}
54 }
55 
56 static int gpio_key_ofdata_to_platdata(struct udevice *dev)
57 {
58 	struct gpio_key_priv *priv = dev_get_priv(dev);
59 	struct input_key *key = dev_get_platdata(dev);
60 	u32 gpios[2], i = 0;
61 	ofnode node;
62 	int irq;
63 
64 	dev_for_each_subnode(node, dev) {
65 		key[i].name = ofnode_read_string(node, "label");
66 		if (ofnode_read_u32(node, "linux,code", &key[i].code)) {
67 			printf("failed read 'linux,code' of %s key\n",
68 			       key[i].name);
69 			return -EINVAL;
70 		}
71 		if (ofnode_read_u32_array(node, "gpios", gpios, 2)) {
72 			printf("failed to read 'gpios' of %s key\n",
73 			       key[i].name);
74 			return -EINVAL;
75 		}
76 
77 		/* Must register as interrupt, be able to wakeup system */
78 		irq = phandle_gpio_to_irq(gpios[0], gpios[1]);
79 		if (irq < 0) {
80 			printf("failed to request irq for gpio, ret=%d\n", irq);
81 			return irq;
82 		}
83 		key[i].irq = irq;
84 		irq_install_handler(irq, gpio_irq_handler, dev);
85 		irq_handler_enable(irq);
86 		irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
87 
88 		debug("%s: name=%s: code=%d\n",
89 		      __func__, key[i].name, key[i].code);
90 
91 		/* Next node */
92 		i++;
93 		priv->key_nr = i;
94 		if (i >= MAX_KEY_NR) {
95 			printf("Too many keys, Max support: %d\n", MAX_KEY_NR);
96 			return -EINVAL;
97 		}
98 	}
99 
100 	return 0;
101 }
102 
103 static int gpio_key_read(struct udevice *dev, int code)
104 {
105 	struct gpio_key_priv *priv = dev_get_priv(dev);
106 	struct input_key *key = dev_get_platdata(dev);
107 	u32 report = KEY_NOT_EXIST;
108 	int i = 0;
109 
110 	for (i = 0; i < priv->key_nr; i++) {
111 		if (key[i].code != code)
112 			continue;
113 		report = key_parse_gpio_event(&key[i]);
114 		break;
115 	}
116 
117 	return report;
118 }
119 
120 static const struct dm_key_ops key_ops = {
121 	.name = "gpio-keys",
122 	.read = gpio_key_read,
123 };
124 
125 static const struct udevice_id gpio_key_ids[] = {
126 	{ .compatible = "gpio-keys" },
127 	{ },
128 };
129 
130 U_BOOT_DRIVER(gpio_keys) = {
131 	.name   = "gpio-keys",
132 	.id     = UCLASS_KEY,
133 	.of_match = gpio_key_ids,
134 	.ops	= &key_ops,
135 	.ofdata_to_platdata = gpio_key_ofdata_to_platdata,
136 	.platdata_auto_alloc_size = sizeof(struct input_key) * MAX_KEY_NR,
137 	.priv_auto_alloc_size = sizeof(struct gpio_key_priv),
138 };
139