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 key_data { 32 u8 int_sts_reg; 33 u8 int_msk_reg; 34 u8 pwron_rise_int; 35 u8 pwron_fall_int; 36 struct reg_data *init_reg; 37 u32 init_reg_num; 38 struct reg_data *irq_reg; 39 u32 irq_reg_num; 40 uint64_t key_down_t; 41 uint64_t key_up_t; 42 }; 43 44 struct reg_data { 45 u8 reg; 46 u8 val; 47 }; 48 49 static struct reg_data rk816_init_reg[] = { 50 /* only enable rise/fall interrupt */ 51 { RK816_INT_MSK_REG1, 0x9f }, 52 { RK816_INT_MSK_REG2, 0xff }, 53 { RK816_INT_MSK_REG3, 0xff }, 54 /* clear all interrupt states */ 55 { RK816_INT_STS_REG1, 0xff }, 56 { RK816_INT_STS_REG2, 0xff }, 57 { RK816_INT_STS_REG3, 0xff }, 58 }; 59 60 static struct reg_data rk816_irq_reg[] = { 61 /* clear all interrupt states */ 62 { RK816_INT_STS_REG1, 0xff }, 63 { RK816_INT_STS_REG2, 0xff }, 64 { RK816_INT_STS_REG3, 0xff }, 65 }; 66 67 static struct reg_data rk805_irq_reg[] = { 68 /* clear all interrupt states */ 69 { RK805_INT_STS_REG, 0xff }, 70 }; 71 72 static struct reg_data rk805_init_reg[] = { 73 /* only enable rise/fall interrupt */ 74 { RK805_INT_MSK_REG, 0x7e }, 75 /* clear all interrupt states */ 76 { RK805_INT_STS_REG, 0xff }, 77 }; 78 79 static inline uint64_t arch_counter_get_cntpct(void) 80 { 81 uint64_t cval = 0; 82 83 isb(); 84 #ifdef CONFIG_ARM64 85 asm volatile("mrs %0, cntpct_el0" : "=r" (cval)); 86 #else 87 asm volatile ("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval)); 88 #endif 89 return cval; 90 } 91 92 static uint64_t get_ms(uint64_t base) 93 { 94 return (arch_counter_get_cntpct() / 24000UL) - base; 95 } 96 97 static int rk8xx_pwrkey_read(struct udevice *dev) 98 { 99 struct key_data *key = dev_get_priv(dev); 100 u32 report = KEY_PRESS_NONE; 101 102 if ((key->key_up_t > key->key_down_t) && 103 (key->key_up_t - key->key_down_t) >= KEY_LONG_DOWN_MS) { 104 debug("%s: long key ms: %llu\n", __func__, key->key_up_t - key->key_down_t); 105 key->key_up_t = 0; 106 key->key_down_t = 0; 107 report = KEY_PRESS_LONG_DOWN; 108 } else if (key->key_down_t && get_ms(key->key_down_t) >= KEY_LONG_DOWN_MS) { 109 debug("%s: long key (hold) ms: %llu\n", __func__, key->key_up_t - key->key_down_t); 110 key->key_up_t = 0; 111 key->key_down_t = 0; 112 report = KEY_PRESS_LONG_DOWN; 113 } else if ((key->key_up_t > key->key_down_t) && 114 (key->key_up_t - key->key_down_t) < KEY_LONG_DOWN_MS) { 115 debug("%s: short key ms: %llu\n", __func__, key->key_up_t - key->key_down_t); 116 key->key_up_t = 0; 117 key->key_down_t = 0; 118 report = KEY_PRESS_DOWN; 119 } else { 120 debug("%s: key up: %llu, down: %llu\n", __func__, key->key_up_t, key->key_down_t); 121 } 122 123 return report; 124 } 125 126 static void pwrkey_irq_handler(int irq, void *data) 127 { 128 struct udevice *dev = data; 129 struct key_data *key = dev_get_priv(dev); 130 int ret, val, i; 131 132 /* read status */ 133 val = pmic_reg_read(dev->parent, key->int_sts_reg); 134 if (val < 0) { 135 printf("%s: i2c read failed, ret=%d\n", __func__, val); 136 return; 137 } 138 139 /* fall event */ 140 if (val & key->pwron_fall_int) { 141 key->key_down_t = get_ms(0); 142 debug("%s: key down: %llu ms\n", __func__, key->key_down_t); 143 } 144 145 /* rise event */ 146 if (val & key->pwron_rise_int) { 147 key->key_up_t = get_ms(0); 148 debug("%s: key up: %llu ms\n", __func__, key->key_up_t); 149 } 150 151 /* clear intertup */ 152 for (i = 0; i < key->irq_reg_num; i++) { 153 ret = pmic_reg_write(dev->parent, 154 key->irq_reg[i].reg, 155 key->irq_reg[i].val); 156 if (ret < 0) { 157 printf("%s: i2c write reg 0x%x failed, ret=%d\n", 158 __func__, key->irq_reg[i].reg, ret); 159 } 160 } 161 } 162 163 static int pwrkey_interrupt_init(struct udevice *dev) 164 { 165 u32 interrupt[2], phandle; 166 int irq, ret; 167 168 phandle = dev_read_u32_default(dev->parent, "interrupt-parent", -1); 169 if (phandle < 0) { 170 printf("failed get 'interrupt-parent', ret=%d\n", phandle); 171 return phandle; 172 } 173 174 ret = dev_read_u32_array(dev->parent, "interrupts", interrupt, 2); 175 if (ret) { 176 printf("failed get 'interrupt', ret=%d\n", ret); 177 return ret; 178 } 179 180 irq = phandle_gpio_to_irq(phandle, interrupt[0]); 181 irq_install_handler(irq, pwrkey_irq_handler, dev); 182 irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); 183 irq_handler_enable(irq); 184 185 return 0; 186 } 187 188 static const struct dm_key_ops key_ops = { 189 .type = KEY_POWER, 190 .name = "pmic-pwrkey", 191 .read = rk8xx_pwrkey_read, 192 }; 193 194 static int rk8xx_pwrkey_probe(struct udevice *dev) 195 { 196 struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent); 197 struct key_data *key = dev_get_priv(dev); 198 int ret, i; 199 200 switch (rk8xx->variant) { 201 case RK805_ID: 202 key->int_sts_reg = RK805_INT_STS_REG; 203 key->int_msk_reg = RK805_INT_MSK_REG; 204 key->pwron_rise_int = RK805_PWRON_RISE_INT; 205 key->pwron_fall_int = RK805_PWRON_FALL_INT; 206 key->init_reg = rk805_init_reg; 207 key->init_reg_num = ARRAY_SIZE(rk805_init_reg); 208 key->irq_reg = rk805_irq_reg; 209 key->irq_reg_num = ARRAY_SIZE(rk805_irq_reg); 210 break; 211 212 case RK816_ID: 213 key->int_sts_reg = RK816_INT_STS_REG1; 214 key->int_msk_reg = RK816_INT_MSK_REG1; 215 key->pwron_rise_int = RK816_PWRON_RISE_INT; 216 key->pwron_fall_int = RK816_PWRON_FALL_INT; 217 key->init_reg = rk816_init_reg; 218 key->init_reg_num = ARRAY_SIZE(rk816_init_reg); 219 key->irq_reg = rk816_irq_reg; 220 key->irq_reg_num = ARRAY_SIZE(rk816_irq_reg); 221 break; 222 223 default: 224 return -EINVAL; 225 } 226 227 /* mask and clear intertup */ 228 for (i = 0; i < key->init_reg_num; i++) { 229 ret = pmic_reg_write(dev->parent, 230 key->init_reg[i].reg, 231 key->init_reg[i].val); 232 if (ret < 0) { 233 printf("%s: i2c write reg 0x%x failed, ret=%d\n", 234 __func__, key->init_reg[i].reg, ret); 235 return ret; 236 } 237 } 238 239 return pwrkey_interrupt_init(dev); 240 } 241 242 U_BOOT_DRIVER(rk8xx_pwrkey) = { 243 .name = "rk8xx_pwrkey", 244 .id = UCLASS_KEY, 245 .probe = rk8xx_pwrkey_probe, 246 .ops = &key_ops, 247 .priv_auto_alloc_size = sizeof(struct key_data), 248 }; 249