xref: /rk3399_rockchip-uboot/drivers/input/rk8xx_pwrkey.c (revision 5ce558eee1d84a2b85f2bbc4c4547c8ea1c1dae4)
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 
14 #define	RK816_INT_STS_REG1	0x49
15 #define	RK816_INT_MSK_REG1	0x4a
16 #define RK816_PWRON_RISE_INT	(1 << 6)
17 #define RK816_PWRON_FALL_INT	(1 << 5)
18 
19 #define	RK805_INT_STS_REG	0x4c
20 #define	RK805_INT_MSK_REG	0x4d
21 #define RK805_PWRON_RISE_INT	(1 << 0)
22 #define RK805_PWRON_FALL_INT	(1 << 7)
23 
24 struct key_data {
25 	u8 int_sts_reg;
26 	u8 int_msk_reg;
27 	u8 pwron_rise_int;
28 	u8 pwron_fall_int;
29 };
30 
31 static int rk8xx_pwrkey_read(struct udevice *dev)
32 {
33 	struct key_data *key = dev_get_priv(dev);
34 	int status = KEY_PRESS_NONE;
35 	int ret, val;
36 
37 	val = pmic_reg_read(dev->parent, key->int_sts_reg);
38 	if (val < 0) {
39 		printf("%s: i2c read failed, ret=%d\n", __func__, val);
40 		return val;
41 	}
42 
43 	if (val & key->pwron_fall_int)
44 		status = KEY_PRESS_DOWN;
45 
46 	/* Must check pwron rise behind of fall !! */
47 	if (val & key->pwron_rise_int) {
48 		/* Clear fall when detect rise */
49 		ret = pmic_reg_write(dev->parent, key->int_sts_reg,
50 				     key->pwron_fall_int | key->pwron_rise_int);
51 		if (ret < 0) {
52 			printf("%s: i2c write failed, ret=%d\n", __func__, val);
53 			return ret;
54 		}
55 
56 		status = KEY_PRESS_UP;
57 	}
58 
59 	debug("%s: int sts = 0x%x msk = 0x%x\n",
60 	      __func__, pmic_reg_read(dev->parent, key->int_sts_reg),
61 	      pmic_reg_read(dev->parent, key->int_msk_reg));
62 
63 	return status;
64 }
65 
66 static const struct dm_key_ops key_ops = {
67 	.type = KEY_POWER,
68 	.name = "pmic-pwrkey",
69 	.read = rk8xx_pwrkey_read,
70 };
71 
72 static int rk8xx_pwrkey_probe(struct udevice *dev)
73 {
74 	struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
75 	struct key_data *key = dev_get_priv(dev);
76 	int ret, val;
77 
78 	switch (rk8xx->variant) {
79 	case RK805_ID:
80 		key->int_sts_reg = RK805_INT_STS_REG;
81 		key->int_msk_reg = RK805_INT_MSK_REG;
82 		key->pwron_rise_int = RK805_PWRON_RISE_INT;
83 		key->pwron_fall_int = RK805_PWRON_FALL_INT;
84 		break;
85 
86 	case RK816_ID:
87 		key->int_sts_reg = RK816_INT_STS_REG1;
88 		key->int_msk_reg = RK816_INT_MSK_REG1;
89 		key->pwron_rise_int = RK816_PWRON_RISE_INT;
90 		key->pwron_fall_int = RK816_PWRON_FALL_INT;
91 		break;
92 
93 	default:
94 		return -EINVAL;
95 	}
96 
97 	/* Clear states */
98 	ret = pmic_reg_write(dev->parent, key->int_sts_reg,
99 			     key->pwron_rise_int | key->pwron_fall_int);
100 	if (ret < 0) {
101 		printf("%s: i2c write failed, ret=%d\n", __func__, ret);
102 		return ret;
103 	}
104 
105 	val = pmic_reg_read(dev->parent, key->int_msk_reg);
106 	if (val < 0) {
107 		printf("%s: i2c read failed, ret=%d\n", __func__, val);
108 		return val;
109 	}
110 
111 	/* enable fall and rise interrupt */
112 	val = 0xff;
113 	val &= ~(key->pwron_rise_int | key->pwron_fall_int);
114 	ret = pmic_reg_write(dev->parent, key->int_msk_reg, val);
115 	if (ret < 0) {
116 		printf("%s: i2c write failed, ret=%d\n", __func__, val);
117 		return ret;
118 	}
119 
120 	return 0;
121 }
122 
123 U_BOOT_DRIVER(rk8xx_pwrkey) = {
124 	.name   = "rk8xx_pwrkey",
125 	.id     = UCLASS_KEY,
126 	.probe  = rk8xx_pwrkey_probe,
127 	.ops	= &key_ops,
128 	.priv_auto_alloc_size = sizeof(struct key_data),
129 };
130