xref: /rk3399_rockchip-uboot/drivers/input/rk8xx_pwrkey.c (revision 15a7587bba2ffa33a2e08d02a707fe54b7e24d94)
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 RK817_GPIO_INT_CFG	0xfe
18 #define	RK817_INT_STS_REG0	0xf8
19 #define	RK817_INT_MSK_REG0	0xf9
20 #define	RK817_INT_STS_REG1	0xfa
21 #define	RK817_INT_MSK_REG1	0xfb
22 #define	RK817_INT_STS_REG2	0xfc
23 #define	RK817_INT_MSK_REG2	0xfd
24 #define RK817_PWRON_RISE_INT	(1 << 1)
25 #define RK817_PWRON_FALL_INT	(1 << 0)
26 #define RK817_PLUG_OUT_INT	(1 << 1)
27 #define RK817_INT_POL_MSK	BIT(1)
28 
29 #define	RK816_INT_STS_REG1	0x49
30 #define	RK816_INT_MSK_REG1	0x4a
31 #define	RK816_INT_STS_REG2	0x4c
32 #define	RK816_INT_MSK_REG2	0x4d
33 #define	RK816_INT_STS_REG3	0x4e
34 #define	RK816_INT_MSK_REG3	0x4f
35 #define RK816_PWRON_RISE_INT	(1 << 6)
36 #define RK816_PWRON_FALL_INT	(1 << 5)
37 #define RK816_PLUG_OUT_INT	(1 << 1)
38 
39 #define	RK805_INT_STS_REG	0x4c
40 #define	RK805_INT_MSK_REG	0x4d
41 #define RK805_PWRON_RISE_INT	(1 << 0)
42 #define RK805_PWRON_FALL_INT	(1 << 7)
43 
44 struct reg_data {
45 	u8 reg;
46 	u8 val;
47 };
48 
49 struct rk8xx_key_priv {
50 	u8 key_int_sts_reg;
51 	u8 key_int_msk_reg;
52 	u8 plug_int_sts_reg;
53 	u8 plug_int_msk_reg;
54 	u8 pwron_rise_int;
55 	u8 pwron_fall_int;
56 	u8 plug_out_int;
57 	struct reg_data *init_reg;
58 	u32 init_reg_num;
59 	struct reg_data *irq_reg;
60 	u32 irq_reg_num;
61 };
62 
63 static struct reg_data rk817_init_reg[] = {
64 	/* only enable rise/fall interrupt, plugout */
65 	{ RK817_INT_MSK_REG0, 0xfc },
66 	{ RK817_INT_MSK_REG1, 0xfd },
67 	{ RK817_INT_MSK_REG2, 0xff },
68 	/* clear all interrupt states */
69 	{ RK817_INT_STS_REG0, 0xff },
70 	{ RK817_INT_STS_REG1, 0xff },
71 	{ RK817_INT_STS_REG2, 0xff },
72 	/* pmic_int active low */
73 	{ RK817_GPIO_INT_CFG, 0x20 },
74 };
75 
76 static struct reg_data rk817_irq_reg[] = {
77 	/* clear all interrupt states */
78 	{ RK817_INT_STS_REG0, 0xff },
79 	{ RK817_INT_STS_REG1, 0xff },
80 	{ RK817_INT_STS_REG2, 0xff },
81 };
82 
83 static struct reg_data rk816_init_reg[] = {
84 	/* only enable rise/fall interrupt, plugout */
85 	{ RK816_INT_MSK_REG1, 0x9f },
86 	{ RK816_INT_MSK_REG2, 0xff },
87 	{ RK816_INT_MSK_REG3, 0xfd },
88 	/* clear all interrupt states */
89 	{ RK816_INT_STS_REG1, 0xff },
90 	{ RK816_INT_STS_REG2, 0xff },
91 	{ RK816_INT_STS_REG3, 0xff },
92 };
93 
94 static struct reg_data rk816_irq_reg[] = {
95 	/* clear all interrupt states */
96 	{ RK816_INT_STS_REG1, 0xff },
97 	{ RK816_INT_STS_REG2, 0xff },
98 	{ RK816_INT_STS_REG3, 0xff },
99 };
100 
101 static struct reg_data rk805_irq_reg[] = {
102 	/* clear all interrupt states */
103 	{ RK805_INT_STS_REG, 0xff },
104 };
105 
106 static struct reg_data rk805_init_reg[] = {
107 	/* only enable rise/fall interrupt */
108 	{ RK805_INT_MSK_REG, 0x7e },
109 	/* clear all interrupt states */
110 	{ RK805_INT_STS_REG, 0xff },
111 };
112 
113 static int rk8xx_pwrkey_read(struct udevice *dev, int code)
114 {
115 	struct input_key *key = dev_get_platdata(dev);
116 	u32 report = KEY_NOT_EXIST;
117 
118 	if (key->code != code)
119 		goto out;
120 
121 	debug("%s: long key ms: %llu\n",
122 	      __func__, key->up_t - key->down_t);
123 
124 	if ((key->up_t > key->down_t) &&
125 	    (key->up_t - key->down_t) >= KEY_LONG_DOWN_MS) {
126 		key->up_t = 0;
127 		key->down_t = 0;
128 		report = KEY_PRESS_LONG_DOWN;
129 		printf("'%s' key long pressed down\n", key->name);
130 	} else if (key->down_t &&
131 		   key_get_timer(key->down_t) >= KEY_LONG_DOWN_MS) {
132 		key->up_t = 0;
133 		key->down_t = 0;
134 		report = KEY_PRESS_LONG_DOWN;
135 		printf("'%s' key long pressed down(hold)\n", key->name);
136 	} else if ((key->up_t > key->down_t) &&
137 		   (key->up_t - key->down_t) < KEY_LONG_DOWN_MS) {
138 		key->up_t = 0;
139 		key->down_t = 0;
140 		report = KEY_PRESS_DOWN;
141 		printf("'%s' key pressed down\n", key->name);
142 	} else {
143 		report = KEY_PRESS_NONE;
144 	}
145 
146 out:
147 	return report;
148 }
149 
150 static void pwrkey_irq_handler(int irq, void *data)
151 {
152 	struct udevice *dev = data;
153 	struct rk8xx_key_priv *priv = dev_get_priv(dev);
154 	struct input_key *key = dev_get_platdata(dev);
155 	int ret, val, i;
156 
157 	debug("%s: irq = %d\n", __func__, irq);
158 
159 	/*
160 	 * This plug out interrupt only used to wakeup cpu while U-Boot
161 	 * charging and system suspend. Because we need to detect charger
162 	 * plug out event and then shutdown system.
163 	 */
164 	if (priv->plug_int_sts_reg) {
165 		val = pmic_reg_read(dev->parent, priv->plug_int_sts_reg);
166 		if (val < 0) {
167 			printf("%s: i2c read failed, ret=%d\n", __func__, val);
168 			return;
169 		}
170 
171 		if (val & priv->plug_out_int)
172 			printf("Plug out interrupt\n");
173 	}
174 
175 	/* read key status */
176 	val = pmic_reg_read(dev->parent, priv->key_int_sts_reg);
177 	if (val < 0) {
178 		printf("%s: i2c read failed, ret=%d\n", __func__, val);
179 		return;
180 	}
181 
182 	/* fall event */
183 	if (val & priv->pwron_fall_int) {
184 		key->down_t = key_get_timer(0);
185 		debug("%s: key down: %llu ms\n", __func__, key->down_t);
186 	}
187 
188 	/* rise event */
189 	if (val & priv->pwron_rise_int) {
190 		key->up_t = key_get_timer(0);
191 		debug("%s: key up: %llu ms\n", __func__, key->up_t);
192 	}
193 
194 	/* clear intertup */
195 	for (i = 0; i < priv->irq_reg_num; i++) {
196 		ret = pmic_reg_write(dev->parent,
197 				     priv->irq_reg[i].reg,
198 				     priv->irq_reg[i].val);
199 		if (ret < 0) {
200 			printf("%s: i2c write reg 0x%x failed, ret=%d\n",
201 			       __func__, priv->irq_reg[i].reg, ret);
202 		}
203 
204 		debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->irq_reg[i].reg,
205 		      pmic_reg_read(dev->parent, priv->irq_reg[i].reg));
206 	}
207 }
208 
209 static int pwrkey_interrupt_init(struct udevice *dev)
210 {
211 	struct input_key *key = dev_get_platdata(dev);
212 	u32 interrupt[2], phandle;
213 	int irq, ret;
214 
215 	phandle = dev_read_u32_default(dev->parent, "interrupt-parent", -1);
216 	if (phandle < 0) {
217 		printf("failed get 'interrupt-parent', ret=%d\n", phandle);
218 		return phandle;
219 	}
220 
221 	ret = dev_read_u32_array(dev->parent, "interrupts", interrupt, 2);
222 	if (ret) {
223 		printf("failed get 'interrupt', ret=%d\n", ret);
224 		return ret;
225 	}
226 
227 	key->name = "pwrkey";
228 	key->code = KEY_POWER;
229 	irq = phandle_gpio_to_irq(phandle, interrupt[0]);
230 	irq_install_handler(irq, pwrkey_irq_handler, dev);
231 	irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
232 	irq_handler_enable(irq);
233 
234 	return 0;
235 }
236 
237 static const struct dm_key_ops key_ops = {
238 	.name = "rk8xx-pwrkey",
239 	.read = rk8xx_pwrkey_read,
240 };
241 
242 static int rk8xx_pwrkey_probe(struct udevice *dev)
243 {
244 	struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
245 	struct rk8xx_key_priv *priv = dev_get_priv(dev);
246 	int ret, i;
247 
248 	switch (rk8xx->variant) {
249 	case RK805_ID:
250 		priv->key_int_sts_reg = RK805_INT_STS_REG;
251 		priv->key_int_msk_reg = RK805_INT_MSK_REG;
252 		priv->pwron_rise_int = RK805_PWRON_RISE_INT;
253 		priv->pwron_fall_int = RK805_PWRON_FALL_INT;
254 		priv->init_reg = rk805_init_reg;
255 		priv->init_reg_num = ARRAY_SIZE(rk805_init_reg);
256 		priv->irq_reg = rk805_irq_reg;
257 		priv->irq_reg_num = ARRAY_SIZE(rk805_irq_reg);
258 		break;
259 
260 	case RK816_ID:
261 		priv->key_int_sts_reg = RK816_INT_STS_REG1;
262 		priv->key_int_msk_reg = RK816_INT_MSK_REG1;
263 		priv->plug_int_sts_reg = RK816_INT_STS_REG3;
264 		priv->plug_int_msk_reg = RK816_INT_MSK_REG3;
265 		priv->pwron_rise_int = RK816_PWRON_RISE_INT;
266 		priv->pwron_fall_int = RK816_PWRON_FALL_INT;
267 		priv->plug_out_int = RK816_PLUG_OUT_INT;
268 		priv->init_reg = rk816_init_reg;
269 		priv->init_reg_num = ARRAY_SIZE(rk816_init_reg);
270 		priv->irq_reg = rk816_irq_reg;
271 		priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg);
272 		break;
273 	case RK817_ID:
274 		priv->key_int_sts_reg = RK817_INT_STS_REG0;
275 		priv->key_int_msk_reg = RK817_INT_MSK_REG0;
276 		priv->plug_int_sts_reg = RK817_INT_STS_REG1;
277 		priv->plug_int_msk_reg = RK817_INT_MSK_REG1;
278 		priv->pwron_rise_int = RK817_PWRON_RISE_INT;
279 		priv->pwron_fall_int = RK817_PWRON_FALL_INT;
280 		priv->plug_out_int = RK817_PLUG_OUT_INT;
281 		priv->init_reg = rk817_init_reg;
282 		priv->init_reg_num = ARRAY_SIZE(rk817_init_reg);
283 		priv->irq_reg = rk817_irq_reg;
284 		priv->irq_reg_num = ARRAY_SIZE(rk817_irq_reg);
285 		break;
286 	default:
287 		return -EINVAL;
288 	}
289 
290 	/* mask and clear interrupt */
291 	for (i = 0; i < priv->init_reg_num; i++) {
292 		ret = pmic_reg_write(dev->parent,
293 				     priv->init_reg[i].reg,
294 				     priv->init_reg[i].val);
295 		if (ret < 0) {
296 			printf("%s: i2c write reg 0x%x failed, ret=%d\n",
297 			       __func__, priv->init_reg[i].reg, ret);
298 			return ret;
299 		}
300 
301 		debug("%s: reg[%x] = 0x%x\n", __func__, priv->init_reg[i].reg,
302 		      pmic_reg_read(dev->parent, priv->init_reg[i].reg));
303 	}
304 
305 	return pwrkey_interrupt_init(dev);
306 }
307 
308 U_BOOT_DRIVER(rk8xx_pwrkey) = {
309 	.name   = "rk8xx_pwrkey",
310 	.id     = UCLASS_KEY,
311 	.ops	= &key_ops,
312 	.probe  = rk8xx_pwrkey_probe,
313 	.platdata_auto_alloc_size = sizeof(struct input_key),
314 	.priv_auto_alloc_size = sizeof(struct rk8xx_key_priv),
315 };
316