// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2022 Richtek Technology Corp. * Author: ChiYuan Huang */ #include #include #include #include #include #include #include #include #define RT5120_REG_INTSTAT 0x1E #define RT5120_PWRKEYSTAT_MASK BIT(7) struct rt5120_priv { struct regmap *regmap; struct input_dev *input; }; static irqreturn_t rt5120_pwrkey_handler(int irq, void *devid) { struct rt5120_priv *priv = devid; unsigned int stat; int error; error = regmap_read(priv->regmap, RT5120_REG_INTSTAT, &stat); if (error) return IRQ_NONE; input_report_key(priv->input, KEY_POWER, !(stat & RT5120_PWRKEYSTAT_MASK)); input_sync(priv->input); return IRQ_HANDLED; } static int rt5120_pwrkey_probe(struct platform_device *pdev) { struct rt5120_priv *priv; struct device *dev = &pdev->dev; int press_irq, release_irq; int error; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->regmap = dev_get_regmap(dev->parent, NULL); if (!priv->regmap) { dev_err(dev, "Failed to init regmap\n"); return -ENODEV; } press_irq = platform_get_irq_byname(pdev, "pwrkey-press"); if (press_irq < 0) return press_irq; release_irq = platform_get_irq_byname(pdev, "pwrkey-release"); if (release_irq < 0) return release_irq; /* Make input device be device resource managed */ priv->input = devm_input_allocate_device(dev); if (!priv->input) return -ENOMEM; priv->input->name = "rt5120_pwrkey"; priv->input->phys = "rt5120_pwrkey/input0"; priv->input->id.bustype = BUS_I2C; input_set_capability(priv->input, EV_KEY, KEY_POWER); error = input_register_device(priv->input); if (error) { dev_err(dev, "Failed to register input device: %d\n", error); return error; } error = devm_request_threaded_irq(dev, press_irq, NULL, rt5120_pwrkey_handler, 0, "pwrkey-press", priv); if (error) { dev_err(dev, "Failed to register pwrkey press irq: %d\n", error); return error; } error = devm_request_threaded_irq(dev, release_irq, NULL, rt5120_pwrkey_handler, 0, "pwrkey-release", priv); if (error) { dev_err(dev, "Failed to register pwrkey release irq: %d\n", error); return error; } return 0; } static const struct of_device_id r5120_pwrkey_match_table[] = { { .compatible = "richtek,rt5120-pwrkey" }, {} }; MODULE_DEVICE_TABLE(of, r5120_pwrkey_match_table); static struct platform_driver rt5120_pwrkey_driver = { .driver = { .name = "rt5120-pwrkey", .of_match_table = r5120_pwrkey_match_table, }, .probe = rt5120_pwrkey_probe, }; module_platform_driver(rt5120_pwrkey_driver); MODULE_AUTHOR("ChiYuan Huang "); MODULE_DESCRIPTION("Richtek RT5120 power key driver"); MODULE_LICENSE("GPL");