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