Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2010-2011, 2020-2021, The Linux Foundation. All rights reserved.
0004  * Copyright (c) 2014, Sony Mobile Communications Inc.
0005  */
0006 
0007 #include <linux/delay.h>
0008 #include <linux/errno.h>
0009 #include <linux/input.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/kernel.h>
0012 #include <linux/ktime.h>
0013 #include <linux/log2.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_device.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/reboot.h>
0020 #include <linux/regmap.h>
0021 
0022 #define PON_REV2            0x01
0023 
0024 #define PON_SUBTYPE         0x05
0025 
0026 #define PON_SUBTYPE_PRIMARY     0x01
0027 #define PON_SUBTYPE_SECONDARY       0x02
0028 #define PON_SUBTYPE_1REG        0x03
0029 #define PON_SUBTYPE_GEN2_PRIMARY    0x04
0030 #define PON_SUBTYPE_GEN2_SECONDARY  0x05
0031 #define PON_SUBTYPE_GEN3_PBS        0x08
0032 #define PON_SUBTYPE_GEN3_HLOS       0x09
0033 
0034 #define PON_RT_STS          0x10
0035 #define  PON_KPDPWR_N_SET       BIT(0)
0036 #define  PON_RESIN_N_SET        BIT(1)
0037 #define  PON_GEN3_RESIN_N_SET       BIT(6)
0038 #define  PON_GEN3_KPDPWR_N_SET      BIT(7)
0039 
0040 #define PON_PS_HOLD_RST_CTL     0x5a
0041 #define PON_PS_HOLD_RST_CTL2        0x5b
0042 #define  PON_PS_HOLD_ENABLE     BIT(7)
0043 #define  PON_PS_HOLD_TYPE_MASK      0x0f
0044 #define  PON_PS_HOLD_TYPE_WARM_RESET    1
0045 #define  PON_PS_HOLD_TYPE_SHUTDOWN  4
0046 #define  PON_PS_HOLD_TYPE_HARD_RESET    7
0047 
0048 #define PON_PULL_CTL            0x70
0049 #define  PON_KPDPWR_PULL_UP     BIT(1)
0050 #define  PON_RESIN_PULL_UP      BIT(0)
0051 
0052 #define PON_DBC_CTL         0x71
0053 #define  PON_DBC_DELAY_MASK     0x7
0054 
0055 struct pm8941_data {
0056     unsigned int    pull_up_bit;
0057     unsigned int    status_bit;
0058     bool        supports_ps_hold_poff_config;
0059     bool        supports_debounce_config;
0060     bool        has_pon_pbs;
0061     const char  *name;
0062     const char  *phys;
0063 };
0064 
0065 struct pm8941_pwrkey {
0066     struct device *dev;
0067     int irq;
0068     u32 baseaddr;
0069     u32 pon_pbs_baseaddr;
0070     struct regmap *regmap;
0071     struct input_dev *input;
0072 
0073     unsigned int revision;
0074     unsigned int subtype;
0075     struct notifier_block reboot_notifier;
0076 
0077     u32 code;
0078     u32 sw_debounce_time_us;
0079     ktime_t sw_debounce_end_time;
0080     bool last_status;
0081     const struct pm8941_data *data;
0082 };
0083 
0084 static int pm8941_reboot_notify(struct notifier_block *nb,
0085                 unsigned long code, void *unused)
0086 {
0087     struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
0088                             reboot_notifier);
0089     unsigned int enable_reg;
0090     unsigned int reset_type;
0091     int error;
0092 
0093     /* PMICs with revision 0 have the enable bit in same register as ctrl */
0094     if (pwrkey->revision == 0)
0095         enable_reg = PON_PS_HOLD_RST_CTL;
0096     else
0097         enable_reg = PON_PS_HOLD_RST_CTL2;
0098 
0099     error = regmap_update_bits(pwrkey->regmap,
0100                    pwrkey->baseaddr + enable_reg,
0101                    PON_PS_HOLD_ENABLE,
0102                    0);
0103     if (error)
0104         dev_err(pwrkey->dev,
0105             "unable to clear ps hold reset enable: %d\n",
0106             error);
0107 
0108     /*
0109      * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
0110      * writes.
0111      */
0112     usleep_range(100, 1000);
0113 
0114     switch (code) {
0115     case SYS_HALT:
0116     case SYS_POWER_OFF:
0117         reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
0118         break;
0119     case SYS_RESTART:
0120     default:
0121         if (reboot_mode == REBOOT_WARM)
0122             reset_type = PON_PS_HOLD_TYPE_WARM_RESET;
0123         else
0124             reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
0125         break;
0126     }
0127 
0128     error = regmap_update_bits(pwrkey->regmap,
0129                    pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
0130                    PON_PS_HOLD_TYPE_MASK,
0131                    reset_type);
0132     if (error)
0133         dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
0134             error);
0135 
0136     error = regmap_update_bits(pwrkey->regmap,
0137                    pwrkey->baseaddr + enable_reg,
0138                    PON_PS_HOLD_ENABLE,
0139                    PON_PS_HOLD_ENABLE);
0140     if (error)
0141         dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
0142 
0143     return NOTIFY_DONE;
0144 }
0145 
0146 static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
0147 {
0148     struct pm8941_pwrkey *pwrkey = _data;
0149     unsigned int sts;
0150     int err;
0151 
0152     if (pwrkey->sw_debounce_time_us) {
0153         if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
0154             dev_dbg(pwrkey->dev,
0155                 "ignoring key event received before debounce end %llu us\n",
0156                 pwrkey->sw_debounce_end_time);
0157             return IRQ_HANDLED;
0158         }
0159     }
0160 
0161     err = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_RT_STS, &sts);
0162     if (err)
0163         return IRQ_HANDLED;
0164 
0165     sts &= pwrkey->data->status_bit;
0166 
0167     if (pwrkey->sw_debounce_time_us && !sts)
0168         pwrkey->sw_debounce_end_time = ktime_add_us(ktime_get(),
0169                         pwrkey->sw_debounce_time_us);
0170 
0171     /*
0172      * Simulate a press event in case a release event occurred without a
0173      * corresponding press event.
0174      */
0175     if (!pwrkey->last_status && !sts) {
0176         input_report_key(pwrkey->input, pwrkey->code, 1);
0177         input_sync(pwrkey->input);
0178     }
0179     pwrkey->last_status = sts;
0180 
0181     input_report_key(pwrkey->input, pwrkey->code, sts);
0182     input_sync(pwrkey->input);
0183 
0184     return IRQ_HANDLED;
0185 }
0186 
0187 static int pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey *pwrkey)
0188 {
0189     unsigned int val, addr, mask;
0190     int error;
0191 
0192     if (pwrkey->data->has_pon_pbs && !pwrkey->pon_pbs_baseaddr) {
0193         dev_err(pwrkey->dev,
0194             "PON_PBS address missing, can't read HW debounce time\n");
0195         return 0;
0196     }
0197 
0198     if (pwrkey->pon_pbs_baseaddr)
0199         addr = pwrkey->pon_pbs_baseaddr + PON_DBC_CTL;
0200     else
0201         addr = pwrkey->baseaddr + PON_DBC_CTL;
0202     error = regmap_read(pwrkey->regmap, addr, &val);
0203     if (error)
0204         return error;
0205 
0206     if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY)
0207         mask = 0xf;
0208     else
0209         mask = 0x7;
0210 
0211     pwrkey->sw_debounce_time_us =
0212         2 * USEC_PER_SEC / (1 << (mask - (val & mask)));
0213 
0214     dev_dbg(pwrkey->dev, "SW debounce time = %u us\n",
0215         pwrkey->sw_debounce_time_us);
0216 
0217     return 0;
0218 }
0219 
0220 static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev)
0221 {
0222     struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
0223 
0224     if (device_may_wakeup(dev))
0225         enable_irq_wake(pwrkey->irq);
0226 
0227     return 0;
0228 }
0229 
0230 static int __maybe_unused pm8941_pwrkey_resume(struct device *dev)
0231 {
0232     struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
0233 
0234     if (device_may_wakeup(dev))
0235         disable_irq_wake(pwrkey->irq);
0236 
0237     return 0;
0238 }
0239 
0240 static SIMPLE_DEV_PM_OPS(pm8941_pwr_key_pm_ops,
0241              pm8941_pwrkey_suspend, pm8941_pwrkey_resume);
0242 
0243 static int pm8941_pwrkey_probe(struct platform_device *pdev)
0244 {
0245     struct pm8941_pwrkey *pwrkey;
0246     bool pull_up;
0247     struct device *parent;
0248     struct device_node *regmap_node;
0249     const __be32 *addr;
0250     u32 req_delay;
0251     int error;
0252 
0253     if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
0254         req_delay = 15625;
0255 
0256     if (req_delay > 2000000 || req_delay == 0) {
0257         dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
0258         return -EINVAL;
0259     }
0260 
0261     pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
0262 
0263     pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
0264     if (!pwrkey)
0265         return -ENOMEM;
0266 
0267     pwrkey->dev = &pdev->dev;
0268     pwrkey->data = of_device_get_match_data(&pdev->dev);
0269 
0270     parent = pdev->dev.parent;
0271     regmap_node = pdev->dev.of_node;
0272     pwrkey->regmap = dev_get_regmap(parent, NULL);
0273     if (!pwrkey->regmap) {
0274         regmap_node = parent->of_node;
0275         /*
0276          * We failed to get regmap for parent. Let's see if we are
0277          * a child of pon node and read regmap and reg from its
0278          * parent.
0279          */
0280         pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
0281         if (!pwrkey->regmap) {
0282             dev_err(&pdev->dev, "failed to locate regmap\n");
0283             return -ENODEV;
0284         }
0285     }
0286 
0287     addr = of_get_address(regmap_node, 0, NULL, NULL);
0288     if (!addr) {
0289         dev_err(&pdev->dev, "reg property missing\n");
0290         return -EINVAL;
0291     }
0292     pwrkey->baseaddr = be32_to_cpup(addr);
0293 
0294     if (pwrkey->data->has_pon_pbs) {
0295         /* PON_PBS base address is optional */
0296         addr = of_get_address(regmap_node, 1, NULL, NULL);
0297         if (addr)
0298             pwrkey->pon_pbs_baseaddr = be32_to_cpup(addr);
0299     }
0300 
0301     pwrkey->irq = platform_get_irq(pdev, 0);
0302     if (pwrkey->irq < 0)
0303         return pwrkey->irq;
0304 
0305     error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
0306                 &pwrkey->revision);
0307     if (error) {
0308         dev_err(&pdev->dev, "failed to read revision: %d\n", error);
0309         return error;
0310     }
0311 
0312     error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_SUBTYPE,
0313                 &pwrkey->subtype);
0314     if (error) {
0315         dev_err(&pdev->dev, "failed to read subtype: %d\n", error);
0316         return error;
0317     }
0318 
0319     error = of_property_read_u32(pdev->dev.of_node, "linux,code",
0320                      &pwrkey->code);
0321     if (error) {
0322         dev_dbg(&pdev->dev,
0323             "no linux,code assuming power (%d)\n", error);
0324         pwrkey->code = KEY_POWER;
0325     }
0326 
0327     pwrkey->input = devm_input_allocate_device(&pdev->dev);
0328     if (!pwrkey->input) {
0329         dev_dbg(&pdev->dev, "unable to allocate input device\n");
0330         return -ENOMEM;
0331     }
0332 
0333     input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
0334 
0335     pwrkey->input->name = pwrkey->data->name;
0336     pwrkey->input->phys = pwrkey->data->phys;
0337 
0338     if (pwrkey->data->supports_debounce_config) {
0339         req_delay = (req_delay << 6) / USEC_PER_SEC;
0340         req_delay = ilog2(req_delay);
0341 
0342         error = regmap_update_bits(pwrkey->regmap,
0343                        pwrkey->baseaddr + PON_DBC_CTL,
0344                        PON_DBC_DELAY_MASK,
0345                        req_delay);
0346         if (error) {
0347             dev_err(&pdev->dev, "failed to set debounce: %d\n",
0348                 error);
0349             return error;
0350         }
0351     }
0352 
0353     error = pm8941_pwrkey_sw_debounce_init(pwrkey);
0354     if (error)
0355         return error;
0356 
0357     if (pwrkey->data->pull_up_bit) {
0358         error = regmap_update_bits(pwrkey->regmap,
0359                        pwrkey->baseaddr + PON_PULL_CTL,
0360                        pwrkey->data->pull_up_bit,
0361                        pull_up ? pwrkey->data->pull_up_bit :
0362                              0);
0363         if (error) {
0364             dev_err(&pdev->dev, "failed to set pull: %d\n", error);
0365             return error;
0366         }
0367     }
0368 
0369     error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
0370                       NULL, pm8941_pwrkey_irq,
0371                       IRQF_ONESHOT,
0372                       pwrkey->data->name, pwrkey);
0373     if (error) {
0374         dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
0375         return error;
0376     }
0377 
0378     error = input_register_device(pwrkey->input);
0379     if (error) {
0380         dev_err(&pdev->dev, "failed to register input device: %d\n",
0381             error);
0382         return error;
0383     }
0384 
0385     if (pwrkey->data->supports_ps_hold_poff_config) {
0386         pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify;
0387         error = register_reboot_notifier(&pwrkey->reboot_notifier);
0388         if (error) {
0389             dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
0390                 error);
0391             return error;
0392         }
0393     }
0394 
0395     platform_set_drvdata(pdev, pwrkey);
0396     device_init_wakeup(&pdev->dev, 1);
0397 
0398     return 0;
0399 }
0400 
0401 static int pm8941_pwrkey_remove(struct platform_device *pdev)
0402 {
0403     struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
0404 
0405     if (pwrkey->data->supports_ps_hold_poff_config)
0406         unregister_reboot_notifier(&pwrkey->reboot_notifier);
0407 
0408     return 0;
0409 }
0410 
0411 static const struct pm8941_data pwrkey_data = {
0412     .pull_up_bit = PON_KPDPWR_PULL_UP,
0413     .status_bit = PON_KPDPWR_N_SET,
0414     .name = "pm8941_pwrkey",
0415     .phys = "pm8941_pwrkey/input0",
0416     .supports_ps_hold_poff_config = true,
0417     .supports_debounce_config = true,
0418     .has_pon_pbs = false,
0419 };
0420 
0421 static const struct pm8941_data resin_data = {
0422     .pull_up_bit = PON_RESIN_PULL_UP,
0423     .status_bit = PON_RESIN_N_SET,
0424     .name = "pm8941_resin",
0425     .phys = "pm8941_resin/input0",
0426     .supports_ps_hold_poff_config = true,
0427     .supports_debounce_config = true,
0428     .has_pon_pbs = false,
0429 };
0430 
0431 static const struct pm8941_data pon_gen3_pwrkey_data = {
0432     .status_bit = PON_GEN3_KPDPWR_N_SET,
0433     .name = "pmic_pwrkey",
0434     .phys = "pmic_pwrkey/input0",
0435     .supports_ps_hold_poff_config = false,
0436     .supports_debounce_config = false,
0437     .has_pon_pbs = true,
0438 };
0439 
0440 static const struct pm8941_data pon_gen3_resin_data = {
0441     .status_bit = PON_GEN3_RESIN_N_SET,
0442     .name = "pmic_resin",
0443     .phys = "pmic_resin/input0",
0444     .supports_ps_hold_poff_config = false,
0445     .supports_debounce_config = false,
0446     .has_pon_pbs = true,
0447 };
0448 
0449 static const struct of_device_id pm8941_pwr_key_id_table[] = {
0450     { .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
0451     { .compatible = "qcom,pm8941-resin", .data = &resin_data },
0452     { .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
0453     { .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
0454     { }
0455 };
0456 MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
0457 
0458 static struct platform_driver pm8941_pwrkey_driver = {
0459     .probe = pm8941_pwrkey_probe,
0460     .remove = pm8941_pwrkey_remove,
0461     .driver = {
0462         .name = "pm8941-pwrkey",
0463         .pm = &pm8941_pwr_key_pm_ops,
0464         .of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
0465     },
0466 };
0467 module_platform_driver(pm8941_pwrkey_driver);
0468 
0469 MODULE_DESCRIPTION("PM8941 Power Key driver");
0470 MODULE_LICENSE("GPL v2");