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