xref: /rk3399_rockchip-uboot/drivers/input/rk_key.c (revision 7c1937d6d1c7daf8e59b4760f8adc7ee42bd7bea)
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 			key_add(key);
75 		/* This is a GPIO key */
76 		} else {
77 			key->parent = dev;
78 			key->type = GPIO_KEY;
79 			key->name = ofnode_read_string(node, "label");
80 			ret = ofnode_read_u32(node, "linux,code", &key->code);
81 			if (ret) {
82 				printf("%s: failed read 'linux,code', ret=%d\n",
83 				       key->name, ret);
84 				free(key);
85 				continue;
86 			}
87 
88 			/* Only register power key as interrupt */
89 			if (key->code == KEY_POWER) {
90 				ret = ofnode_read_u32_array(node, "gpios",
91 							    gpios, 2);
92 				if (ret) {
93 					printf("%s: failed to read 'gpios', ret=%d\n",
94 					       key->name, ret);
95 					free(key);
96 					continue;
97 				}
98 
99 				/* Request irq */
100 				irq = phandle_gpio_to_irq(gpios[0], gpios[1]);
101 				if (irq < 0) {
102 					printf("%s: failed to request irq, ret=%d\n",
103 					       __func__, irq);
104 					free(key);
105 					continue;
106 				}
107 				key->irq = irq;
108 				key_add(key);
109 				irq_install_handler(irq, gpio_irq_handler, key);
110 				irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
111 				irq_handler_enable(irq);
112 			} else {
113 				ret = gpio_request_by_name_nodev(node, "gpios",
114 						0, &key->gpio, GPIOD_IS_IN);
115 				if (ret) {
116 					printf("%s: failed to request gpio, ret=%d\n",
117 					       key->name, ret);
118 					free(key);
119 					continue;
120 				}
121 				key_add(key);
122 			}
123 		}
124 
125 		debug("%s: name=%s: code=%d, adcval=%d, channel=%d, type=%d\n",
126 		      __func__, key->name, key->code, key->adcval,
127 		      key->channel, key->type);
128 	}
129 
130 	return 0;
131 }
132 
133 static const struct dm_key_ops key_ops = {
134 	.name = "rk-keys",
135 };
136 
137 static const struct udevice_id rk_keys_ids[] = {
138 	{ .compatible = "rockchip,key" },
139 	{ },
140 };
141 
142 U_BOOT_DRIVER(rk_keys) = {
143 	.name   = "rk-keys",
144 	.id     = UCLASS_KEY,
145 	.ops	= &key_ops,
146 	.of_match = rk_keys_ids,
147 	.ofdata_to_platdata = rk_keys_ofdata_to_platdata,
148 };
149