xref: /rk3399_rockchip-uboot/drivers/input/rk_key.c (revision 64048c537e998f015febb9bde9bf1ad42d869e8f)
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 rk_keys_ofdata_to_platdata(struct udevice *dev)
44 {
45 	struct input_key *key;
46 	u32 adc_channels[2], gpios[2], adcval;
47 	int irq, ret;
48 	ofnode node;
49 
50 	/* Get IO channel */
51 	if (dev_read_u32_array(dev, "io-channels", adc_channels, 2)) {
52 		printf("%s: failed to read 'io-channels'\n", __func__);
53 		return -EINVAL;
54 	}
55 
56 	dev_for_each_subnode(node, dev) {
57 		key = calloc(1, sizeof(struct input_key));
58 		if (!key)
59 			return -ENOMEM;
60 
61 		/* This is an ACD key */
62 		if (!ofnode_read_u32(node, "rockchip,adc_value", &adcval)) {
63 			key->parent = dev;
64 			key->name = ofnode_read_string(node, "label");
65 			key->type = ADC_KEY;
66 			key->adcval = adcval;
67 			key->channel = adc_channels[1];
68 			if (ofnode_read_u32(node, "linux,code", &key->code)) {
69 				printf("%s: failed to read 'linux,code'\n",
70 				       key->name);
71 				free(key);
72 				continue;
73 			}
74 		/* This is a GPIO key */
75 		} else {
76 			key->parent = dev;
77 			key->type = GPIO_KEY;
78 			key->name = ofnode_read_string(node, "label");
79 			ret = ofnode_read_u32(node, "linux,code", &key->code);
80 			if (ret) {
81 				printf("%s: failed read 'linux,code', ret=%d\n",
82 				       key->name, ret);
83 				free(key);
84 				continue;
85 			}
86 
87 			/* Only register power key as interrupt */
88 			if (key->code == KEY_POWER) {
89 				ret = ofnode_read_u32_array(node, "gpios",
90 							    gpios, 2);
91 				if (ret) {
92 					printf("%s: failed to read 'gpios', ret=%d\n",
93 					       key->name, ret);
94 					free(key);
95 					continue;
96 				}
97 
98 				/* Request irq */
99 				irq = phandle_gpio_to_irq(gpios[0], gpios[1]);
100 				if (irq < 0) {
101 					printf("%s: failed to request irq, ret=%d\n",
102 					       __func__, irq);
103 					free(key);
104 					continue;
105 				}
106 				key->irq = irq;
107 				key_add(key);
108 				irq_install_handler(irq, gpio_irq_handler, key);
109 				irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
110 				irq_handler_enable(irq);
111 			} else {
112 				ret = gpio_request_by_name_nodev(node, "gpios",
113 						0, &key->gpio, GPIOD_IS_IN);
114 				if (ret) {
115 					printf("%s: failed to request gpio, ret=%d\n",
116 					       key->name, ret);
117 					free(key);
118 					continue;
119 				}
120 				key_add(key);
121 			}
122 		}
123 
124 		debug("%s: name=%s: code=%d, adcval=%d, channel=%d, type=%d\n",
125 		      __func__, key->name, key->code, key->adcval,
126 		      key->channel, key->type);
127 	}
128 
129 	return 0;
130 }
131 
132 static const struct dm_key_ops key_ops = {
133 	.name = "rk-keys",
134 };
135 
136 static const struct udevice_id rk_keys_ids[] = {
137 	{ .compatible = "rockchip,key" },
138 	{ },
139 };
140 
141 U_BOOT_DRIVER(rk_keys) = {
142 	.name   = "rk-keys",
143 	.id     = UCLASS_KEY,
144 	.ops	= &key_ops,
145 	.of_match = rk_keys_ids,
146 	.ofdata_to_platdata = rk_keys_ofdata_to_platdata,
147 };
148