xref: /rk3399_rockchip-uboot/drivers/input/rk8xx_pwrkey.c (revision a7b534a020837deb2425e7821feb51cd7c95c4ef)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <key.h>
10 #include <linux/input.h>
11 #include <power/pmic.h>
12 #include <power/rk8xx_pmic.h>
13 #include <irq-generic.h>
14 #include <asm/arch/periph.h>
15 #include <dm/pinctrl.h>
16 
17 #define	RK816_INT_STS_REG1	0x49
18 #define	RK816_INT_MSK_REG1	0x4a
19 #define	RK816_INT_STS_REG2	0x4c
20 #define	RK816_INT_MSK_REG2	0x4d
21 #define	RK816_INT_STS_REG3	0x4e
22 #define	RK816_INT_MSK_REG3	0x4f
23 #define RK816_PWRON_RISE_INT	(1 << 6)
24 #define RK816_PWRON_FALL_INT	(1 << 5)
25 
26 #define	RK805_INT_STS_REG	0x4c
27 #define	RK805_INT_MSK_REG	0x4d
28 #define RK805_PWRON_RISE_INT	(1 << 0)
29 #define RK805_PWRON_FALL_INT	(1 << 7)
30 
31 struct reg_data {
32 	u8 reg;
33 	u8 val;
34 };
35 
36 struct rk8xx_key_priv {
37 	u8 int_sts_reg;
38 	u8 int_msk_reg;
39 	u8 pwron_rise_int;
40 	u8 pwron_fall_int;
41 	struct reg_data *init_reg;
42 	u32 init_reg_num;
43 	struct reg_data *irq_reg;
44 	u32 irq_reg_num;
45 };
46 
47 static struct reg_data rk816_init_reg[] = {
48 	/* only enable rise/fall interrupt */
49 	{ RK816_INT_MSK_REG1, 0x9f },
50 	{ RK816_INT_MSK_REG2, 0xff },
51 	{ RK816_INT_MSK_REG3, 0xff },
52 	/* clear all interrupt states */
53 	{ RK816_INT_STS_REG1, 0xff },
54 	{ RK816_INT_STS_REG2, 0xff },
55 	{ RK816_INT_STS_REG3, 0xff },
56 };
57 
58 static struct reg_data rk816_irq_reg[] = {
59 	/* clear all interrupt states */
60 	{ RK816_INT_STS_REG1, 0xff },
61 	{ RK816_INT_STS_REG2, 0xff },
62 	{ RK816_INT_STS_REG3, 0xff },
63 };
64 
65 static struct reg_data rk805_irq_reg[] = {
66 	/* clear all interrupt states */
67 	{ RK805_INT_STS_REG, 0xff },
68 };
69 
70 static struct reg_data rk805_init_reg[] = {
71 	/* only enable rise/fall interrupt */
72 	{ RK805_INT_MSK_REG, 0x7e },
73 	/* clear all interrupt states */
74 	{ RK805_INT_STS_REG, 0xff },
75 };
76 
77 static int rk8xx_pwrkey_read(struct udevice *dev, int code)
78 {
79 	struct input_key *key = dev_get_platdata(dev);
80 	u32 report = KEY_NOT_EXIST;
81 
82 	if (key->code != code)
83 		goto out;
84 
85 	debug("%s: long key ms: %llu\n",
86 	      __func__, key->up_t - key->down_t);
87 
88 	if ((key->up_t > key->down_t) &&
89 	    (key->up_t - key->down_t) >= KEY_LONG_DOWN_MS) {
90 		key->up_t = 0;
91 		key->down_t = 0;
92 		report = KEY_PRESS_LONG_DOWN;
93 		printf("'%s' key long pressed down\n", key->name);
94 	} else if (key->down_t &&
95 		   key_get_timer(key->down_t) >= KEY_LONG_DOWN_MS) {
96 		key->up_t = 0;
97 		key->down_t = 0;
98 		report = KEY_PRESS_LONG_DOWN;
99 		printf("'%s' key long pressed down(hold)\n", key->name);
100 	} else if ((key->up_t > key->down_t) &&
101 		   (key->up_t - key->down_t) < KEY_LONG_DOWN_MS) {
102 		key->up_t = 0;
103 		key->down_t = 0;
104 		report = KEY_PRESS_DOWN;
105 		printf("'%s' key pressed down\n", key->name);
106 	} else {
107 		report = KEY_PRESS_NONE;
108 	}
109 
110 out:
111 	return report;
112 }
113 
114 static void pwrkey_irq_handler(int irq, void *data)
115 {
116 	struct udevice *dev = data;
117 	struct rk8xx_key_priv *priv = dev_get_priv(dev);
118 	struct input_key *key = dev_get_platdata(dev);
119 	int ret, val, i;
120 
121 	/* read status */
122 	val = pmic_reg_read(dev->parent, priv->int_sts_reg);
123 	if (val < 0) {
124 		printf("%s: i2c read failed, ret=%d\n", __func__, val);
125 		return;
126 	}
127 
128 	/* fall event */
129 	if (val & priv->pwron_fall_int) {
130 		key->down_t = key_get_timer(0);
131 		debug("%s: key down: %llu ms\n", __func__, key->down_t);
132 	}
133 
134 	/* rise event */
135 	if (val & priv->pwron_rise_int) {
136 		key->up_t = key_get_timer(0);
137 		debug("%s: key up: %llu ms\n", __func__, key->up_t);
138 	}
139 
140 	/* clear intertup */
141 	for (i = 0; i < priv->irq_reg_num; i++) {
142 		ret = pmic_reg_write(dev->parent,
143 				     priv->irq_reg[i].reg,
144 				     priv->irq_reg[i].val);
145 		if (ret < 0) {
146 			printf("%s: i2c write reg 0x%x failed, ret=%d\n",
147 			       __func__, priv->irq_reg[i].reg, ret);
148 		}
149 	}
150 }
151 
152 static int pwrkey_interrupt_init(struct udevice *dev)
153 {
154 	struct input_key *key = dev_get_platdata(dev);
155 	u32 interrupt[2], phandle;
156 	int irq, ret;
157 
158 	phandle = dev_read_u32_default(dev->parent, "interrupt-parent", -1);
159 	if (phandle < 0) {
160 		printf("failed get 'interrupt-parent', ret=%d\n", phandle);
161 		return phandle;
162 	}
163 
164 	ret = dev_read_u32_array(dev->parent, "interrupts", interrupt, 2);
165 	if (ret) {
166 		printf("failed get 'interrupt', ret=%d\n", ret);
167 		return ret;
168 	}
169 
170 	key->name = "pwrkey";
171 	key->code = KEY_POWER;
172 	irq = phandle_gpio_to_irq(phandle, interrupt[0]);
173 	irq_install_handler(irq, pwrkey_irq_handler, dev);
174 	irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
175 	irq_handler_enable(irq);
176 
177 	return 0;
178 }
179 
180 static const struct dm_key_ops key_ops = {
181 	.name = "rk8xx-pwrkey",
182 	.read = rk8xx_pwrkey_read,
183 };
184 
185 static int rk8xx_pwrkey_probe(struct udevice *dev)
186 {
187 	struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
188 	struct rk8xx_key_priv *priv = dev_get_priv(dev);
189 	int ret, i;
190 
191 	switch (rk8xx->variant) {
192 	case RK805_ID:
193 		priv->int_sts_reg = RK805_INT_STS_REG;
194 		priv->int_msk_reg = RK805_INT_MSK_REG;
195 		priv->pwron_rise_int = RK805_PWRON_RISE_INT;
196 		priv->pwron_fall_int = RK805_PWRON_FALL_INT;
197 		priv->init_reg = rk805_init_reg;
198 		priv->init_reg_num = ARRAY_SIZE(rk805_init_reg);
199 		priv->irq_reg = rk805_irq_reg;
200 		priv->irq_reg_num = ARRAY_SIZE(rk805_irq_reg);
201 		break;
202 
203 	case RK816_ID:
204 		priv->int_sts_reg = RK816_INT_STS_REG1;
205 		priv->int_msk_reg = RK816_INT_MSK_REG1;
206 		priv->pwron_rise_int = RK816_PWRON_RISE_INT;
207 		priv->pwron_fall_int = RK816_PWRON_FALL_INT;
208 		priv->init_reg = rk816_init_reg;
209 		priv->init_reg_num = ARRAY_SIZE(rk816_init_reg);
210 		priv->irq_reg = rk816_irq_reg;
211 		priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg);
212 		break;
213 
214 	default:
215 		return -EINVAL;
216 	}
217 
218 	/* mask and clear intertup */
219 	for (i = 0; i < priv->init_reg_num; i++) {
220 		ret = pmic_reg_write(dev->parent,
221 				     priv->init_reg[i].reg,
222 				     priv->init_reg[i].val);
223 		if (ret < 0) {
224 			printf("%s: i2c write reg 0x%x failed, ret=%d\n",
225 			       __func__, priv->init_reg[i].reg, ret);
226 			return ret;
227 		}
228 	}
229 
230 	return pwrkey_interrupt_init(dev);
231 }
232 
233 U_BOOT_DRIVER(rk8xx_pwrkey) = {
234 	.name   = "rk8xx_pwrkey",
235 	.id     = UCLASS_KEY,
236 	.ops	= &key_ops,
237 	.probe  = rk8xx_pwrkey_probe,
238 	.platdata_auto_alloc_size = sizeof(struct input_key),
239 	.priv_auto_alloc_size = sizeof(struct rk8xx_key_priv),
240 };
241