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 void pwrkey_irq_handler(int irq, struct udevice *dev) 105 { 106 struct rk8xx_key_priv *priv = dev_get_priv(dev); 107 struct dm_key_uclass_platdata *uc_key = dev_get_uclass_platdata(dev); 108 int ret, val, i; 109 110 debug("%s: irq = %d\n", __func__, irq); 111 112 /* 113 * This plug out interrupt only used to wakeup cpu while U-Boot 114 * charging and system suspend. Because we need to detect charger 115 * plug out event and then shutdown system. 116 */ 117 if (priv->plug_int_sts_reg) { 118 val = pmic_reg_read(dev->parent, priv->plug_int_sts_reg); 119 if (val < 0) { 120 printf("%s: i2c read failed, ret=%d\n", __func__, val); 121 return; 122 } 123 124 if (val & priv->plug_out_int) 125 printf("Plug out interrupt\n"); 126 } 127 128 /* read key status */ 129 val = pmic_reg_read(dev->parent, priv->key_int_sts_reg); 130 if (val < 0) { 131 printf("%s: i2c read failed, ret=%d\n", __func__, val); 132 return; 133 } 134 135 /* fall event */ 136 if (val & priv->pwron_fall_int) { 137 uc_key->fall_ms = key_timer(0); 138 debug("%s: key down: %llu ms\n", __func__, uc_key->fall_ms); 139 } 140 141 /* rise event */ 142 if (val & priv->pwron_rise_int) { 143 uc_key->rise_ms = key_timer(0); 144 debug("%s: key up: %llu ms\n", __func__, uc_key->rise_ms); 145 } 146 147 /* clear intertup */ 148 for (i = 0; i < priv->irq_reg_num; i++) { 149 ret = pmic_reg_write(dev->parent, 150 priv->irq_reg[i].reg, 151 priv->irq_reg[i].val); 152 if (ret < 0) { 153 printf("%s: i2c write reg 0x%x failed, ret=%d\n", 154 __func__, priv->irq_reg[i].reg, ret); 155 } 156 157 debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->irq_reg[i].reg, 158 pmic_reg_read(dev->parent, priv->irq_reg[i].reg)); 159 } 160 } 161 162 static int pwrkey_interrupt_init(struct udevice *dev) 163 { 164 struct dm_key_uclass_platdata *uc_key = dev_get_uclass_platdata(dev); 165 u32 interrupt[2], phandle; 166 int ret; 167 168 phandle = dev_read_u32_default(dev->parent, "interrupt-parent", -1); 169 if (phandle < 0) { 170 printf("read 'interrupt-parent' failed, 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("read 'interrupt' failed, ret=%d\n", ret); 177 return ret; 178 } 179 180 uc_key->name = "rk8xx_pwr"; 181 uc_key->type = GPIO_KEY; 182 uc_key->code = KEY_POWER; 183 uc_key->gpios[0] = phandle; 184 uc_key->gpios[1] = interrupt[0]; 185 uc_key->irq_thread = pwrkey_irq_handler; 186 187 return 0; 188 } 189 190 static int rk8xx_pwrkey_probe(struct udevice *dev) 191 { 192 struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent); 193 struct rk8xx_key_priv *priv = dev_get_priv(dev); 194 int ret, i; 195 196 switch (rk8xx->variant) { 197 case RK805_ID: 198 priv->key_int_sts_reg = RK805_INT_STS_REG; 199 priv->key_int_msk_reg = RK805_INT_MSK_REG; 200 priv->pwron_rise_int = RK805_PWRON_RISE_INT; 201 priv->pwron_fall_int = RK805_PWRON_FALL_INT; 202 priv->init_reg = rk805_init_reg; 203 priv->init_reg_num = ARRAY_SIZE(rk805_init_reg); 204 priv->irq_reg = rk805_irq_reg; 205 priv->irq_reg_num = ARRAY_SIZE(rk805_irq_reg); 206 break; 207 208 case RK816_ID: 209 priv->key_int_sts_reg = RK816_INT_STS_REG1; 210 priv->key_int_msk_reg = RK816_INT_MSK_REG1; 211 priv->plug_int_sts_reg = RK816_INT_STS_REG3; 212 priv->plug_int_msk_reg = RK816_INT_MSK_REG3; 213 priv->pwron_rise_int = RK816_PWRON_RISE_INT; 214 priv->pwron_fall_int = RK816_PWRON_FALL_INT; 215 priv->plug_out_int = RK816_PLUG_OUT_INT; 216 priv->init_reg = rk816_init_reg; 217 priv->init_reg_num = ARRAY_SIZE(rk816_init_reg); 218 priv->irq_reg = rk816_irq_reg; 219 priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg); 220 break; 221 case RK809_ID: 222 case RK817_ID: 223 priv->key_int_sts_reg = RK817_INT_STS_REG0; 224 priv->key_int_msk_reg = RK817_INT_MSK_REG0; 225 priv->plug_int_sts_reg = RK817_INT_STS_REG1; 226 priv->plug_int_msk_reg = RK817_INT_MSK_REG1; 227 priv->pwron_rise_int = RK817_PWRON_RISE_INT; 228 priv->pwron_fall_int = RK817_PWRON_FALL_INT; 229 priv->plug_out_int = RK817_PLUG_OUT_INT; 230 priv->init_reg = rk817_init_reg; 231 priv->init_reg_num = ARRAY_SIZE(rk817_init_reg); 232 priv->irq_reg = rk817_irq_reg; 233 priv->irq_reg_num = ARRAY_SIZE(rk817_irq_reg); 234 break; 235 default: 236 return -EINVAL; 237 } 238 239 /* mask and clear interrupt */ 240 for (i = 0; i < priv->init_reg_num; i++) { 241 ret = pmic_reg_write(dev->parent, 242 priv->init_reg[i].reg, 243 priv->init_reg[i].val); 244 if (ret < 0) { 245 printf("%s: i2c write reg 0x%x failed, ret=%d\n", 246 __func__, priv->init_reg[i].reg, ret); 247 return ret; 248 } 249 250 debug("%s: reg[%x] = 0x%x\n", __func__, priv->init_reg[i].reg, 251 pmic_reg_read(dev->parent, priv->init_reg[i].reg)); 252 } 253 254 return pwrkey_interrupt_init(dev); 255 } 256 257 U_BOOT_DRIVER(rk8xx_pwrkey) = { 258 .name = "rk8xx_pwrkey", 259 .id = UCLASS_KEY, 260 .probe = rk8xx_pwrkey_probe, 261 .priv_auto_alloc_size = sizeof(struct rk8xx_key_priv), 262 }; 263