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