Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: mtk-pmic-keys - add support for MT6358

MT6358 pmic keys behave differently than mt6397 and mt6323: there are
two interrupts per key: one for press, the other one for release (_r)

Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Link: https://lore.kernel.org/r/20220121140323.4080640-4-mkorpershoek@baylibre.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Mattijs Korpershoek and committed by
Dmitry Torokhov
994673dc 41799efd

+46 -2
+46 -2
drivers/input/keyboard/mtk-pmic-keys.c
··· 9 9 #include <linux/interrupt.h> 10 10 #include <linux/kernel.h> 11 11 #include <linux/mfd/mt6323/registers.h> 12 + #include <linux/mfd/mt6358/registers.h> 12 13 #include <linux/mfd/mt6397/core.h> 13 14 #include <linux/mfd/mt6397/registers.h> 14 15 #include <linux/module.h> ··· 75 74 .pmic_rst_reg = MT6323_TOP_RST_MISC, 76 75 }; 77 76 77 + static const struct mtk_pmic_regs mt6358_regs = { 78 + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = 79 + MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, 80 + 0x2, MT6358_PSC_TOP_INT_CON0, 0x5), 81 + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = 82 + MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, 83 + 0x8, MT6358_PSC_TOP_INT_CON0, 0xa), 84 + .pmic_rst_reg = MT6358_TOP_RST_MISC, 85 + }; 86 + 78 87 struct mtk_pmic_keys_info { 79 88 struct mtk_pmic_keys *keys; 80 89 const struct mtk_pmic_keys_regs *regs; 81 90 unsigned int keycode; 82 91 int irq; 92 + int irq_r; /* optional: release irq if different */ 83 93 bool wakeup:1; 84 94 }; 85 95 ··· 200 188 return ret; 201 189 } 202 190 191 + if (info->irq_r > 0) { 192 + ret = devm_request_threaded_irq(keys->dev, info->irq_r, NULL, 193 + mtk_pmic_keys_irq_handler_thread, 194 + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, 195 + "mtk-pmic-keys", info); 196 + if (ret) { 197 + dev_err(keys->dev, "Failed to request IRQ_r: %d: %d\n", 198 + info->irq, ret); 199 + return ret; 200 + } 201 + } 202 + 203 203 input_set_capability(keys->input_dev, EV_KEY, info->keycode); 204 204 205 205 return 0; ··· 223 199 int index; 224 200 225 201 for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { 226 - if (keys->keys[index].wakeup) 202 + if (keys->keys[index].wakeup) { 227 203 enable_irq_wake(keys->keys[index].irq); 204 + if (keys->keys[index].irq_r > 0) 205 + enable_irq_wake(keys->keys[index].irq_r); 206 + } 228 207 } 229 208 230 209 return 0; ··· 239 212 int index; 240 213 241 214 for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { 242 - if (keys->keys[index].wakeup) 215 + if (keys->keys[index].wakeup) { 243 216 disable_irq_wake(keys->keys[index].irq); 217 + if (keys->keys[index].irq_r > 0) 218 + disable_irq_wake(keys->keys[index].irq_r); 219 + } 244 220 } 245 221 246 222 return 0; ··· 260 230 .compatible = "mediatek,mt6323-keys", 261 231 .data = &mt6323_regs, 262 232 }, { 233 + .compatible = "mediatek,mt6358-keys", 234 + .data = &mt6358_regs, 235 + }, { 263 236 /* sentinel */ 264 237 } 265 238 }; ··· 275 242 struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent); 276 243 struct device_node *node = pdev->dev.of_node, *child; 277 244 static const char *const irqnames[] = { "powerkey", "homekey" }; 245 + static const char *const irqnames_r[] = { "powerkey_r", "homekey_r" }; 278 246 struct mtk_pmic_keys *keys; 279 247 const struct mtk_pmic_regs *mtk_pmic_regs; 280 248 struct input_dev *input_dev; ··· 317 283 if (keys->keys[index].irq < 0) { 318 284 of_node_put(child); 319 285 return keys->keys[index].irq; 286 + } 287 + 288 + if (of_device_is_compatible(node, "mediatek,mt6358-keys")) { 289 + keys->keys[index].irq_r = platform_get_irq_byname(pdev, 290 + irqnames_r[index]); 291 + 292 + if (keys->keys[index].irq_r < 0) { 293 + of_node_put(child); 294 + return keys->keys[index].irq_r; 295 + } 320 296 } 321 297 322 298 error = of_property_read_u32(child,