Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
0003  */
0004 
0005 #include <linux/module.h>
0006 #include <linux/kernel.h>
0007 #include <linux/errno.h>
0008 #include <linux/slab.h>
0009 #include <linux/input.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/regmap.h>
0013 #include <linux/log2.h>
0014 #include <linux/of.h>
0015 #include <linux/of_device.h>
0016 
0017 #define PON_CNTL_1 0x1C
0018 #define PON_CNTL_PULL_UP BIT(7)
0019 #define PON_CNTL_TRIG_DELAY_MASK (0x7)
0020 #define PON_CNTL_1_PULL_UP_EN           0xe0
0021 #define PON_CNTL_1_USB_PWR_EN           0x10
0022 #define PON_CNTL_1_WD_EN_RESET          0x08
0023 
0024 #define PM8058_SLEEP_CTRL           0x02b
0025 #define PM8921_SLEEP_CTRL           0x10a
0026 
0027 #define SLEEP_CTRL_SMPL_EN_RESET        0x04
0028 
0029 /* Regulator master enable addresses */
0030 #define REG_PM8058_VREG_EN_MSM          0x018
0031 #define REG_PM8058_VREG_EN_GRP_5_4      0x1c8
0032 
0033 /* Regulator control registers for shutdown/reset */
0034 #define PM8058_S0_CTRL              0x004
0035 #define PM8058_S1_CTRL              0x005
0036 #define PM8058_S3_CTRL              0x111
0037 #define PM8058_L21_CTRL             0x120
0038 #define PM8058_L22_CTRL             0x121
0039 
0040 #define PM8058_REGULATOR_ENABLE_MASK        0x80
0041 #define PM8058_REGULATOR_ENABLE         0x80
0042 #define PM8058_REGULATOR_DISABLE        0x00
0043 #define PM8058_REGULATOR_PULL_DOWN_MASK     0x40
0044 #define PM8058_REGULATOR_PULL_DOWN_EN       0x40
0045 
0046 /* Buck CTRL register */
0047 #define PM8058_SMPS_LEGACY_VREF_SEL     0x20
0048 #define PM8058_SMPS_LEGACY_VPROG_MASK       0x1f
0049 #define PM8058_SMPS_ADVANCED_BAND_MASK      0xC0
0050 #define PM8058_SMPS_ADVANCED_BAND_SHIFT     6
0051 #define PM8058_SMPS_ADVANCED_VPROG_MASK     0x3f
0052 
0053 /* Buck TEST2 registers for shutdown/reset */
0054 #define PM8058_S0_TEST2             0x084
0055 #define PM8058_S1_TEST2             0x085
0056 #define PM8058_S3_TEST2             0x11a
0057 
0058 #define PM8058_REGULATOR_BANK_WRITE     0x80
0059 #define PM8058_REGULATOR_BANK_MASK      0x70
0060 #define PM8058_REGULATOR_BANK_SHIFT     4
0061 #define PM8058_REGULATOR_BANK_SEL(n)    ((n) << PM8058_REGULATOR_BANK_SHIFT)
0062 
0063 /* Buck TEST2 register bank 1 */
0064 #define PM8058_SMPS_LEGACY_VLOW_SEL     0x01
0065 
0066 /* Buck TEST2 register bank 7 */
0067 #define PM8058_SMPS_ADVANCED_MODE_MASK      0x02
0068 #define PM8058_SMPS_ADVANCED_MODE       0x02
0069 #define PM8058_SMPS_LEGACY_MODE         0x00
0070 
0071 /**
0072  * struct pmic8xxx_pwrkey - pmic8xxx pwrkey information
0073  * @key_press_irq: key press irq number
0074  * @regmap: device regmap
0075  * @shutdown_fn: shutdown configuration function
0076  */
0077 struct pmic8xxx_pwrkey {
0078     int key_press_irq;
0079     struct regmap *regmap;
0080     int (*shutdown_fn)(struct pmic8xxx_pwrkey *, bool);
0081 };
0082 
0083 static irqreturn_t pwrkey_press_irq(int irq, void *_pwr)
0084 {
0085     struct input_dev *pwr = _pwr;
0086 
0087     input_report_key(pwr, KEY_POWER, 1);
0088     input_sync(pwr);
0089 
0090     return IRQ_HANDLED;
0091 }
0092 
0093 static irqreturn_t pwrkey_release_irq(int irq, void *_pwr)
0094 {
0095     struct input_dev *pwr = _pwr;
0096 
0097     input_report_key(pwr, KEY_POWER, 0);
0098     input_sync(pwr);
0099 
0100     return IRQ_HANDLED;
0101 }
0102 
0103 static int __maybe_unused pmic8xxx_pwrkey_suspend(struct device *dev)
0104 {
0105     struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
0106 
0107     if (device_may_wakeup(dev))
0108         enable_irq_wake(pwrkey->key_press_irq);
0109 
0110     return 0;
0111 }
0112 
0113 static int __maybe_unused pmic8xxx_pwrkey_resume(struct device *dev)
0114 {
0115     struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
0116 
0117     if (device_may_wakeup(dev))
0118         disable_irq_wake(pwrkey->key_press_irq);
0119 
0120     return 0;
0121 }
0122 
0123 static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops,
0124         pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume);
0125 
0126 static void pmic8xxx_pwrkey_shutdown(struct platform_device *pdev)
0127 {
0128     struct pmic8xxx_pwrkey *pwrkey = platform_get_drvdata(pdev);
0129     int error;
0130     u8 mask, val;
0131     bool reset = system_state == SYSTEM_RESTART;
0132 
0133     if (pwrkey->shutdown_fn) {
0134         error = pwrkey->shutdown_fn(pwrkey, reset);
0135         if (error)
0136             return;
0137     }
0138 
0139     /*
0140      * Select action to perform (reset or shutdown) when PS_HOLD goes low.
0141      * Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
0142      * USB charging is enabled.
0143      */
0144     mask = PON_CNTL_1_PULL_UP_EN | PON_CNTL_1_USB_PWR_EN;
0145     mask |= PON_CNTL_1_WD_EN_RESET;
0146     val = mask;
0147     if (!reset)
0148         val &= ~PON_CNTL_1_WD_EN_RESET;
0149 
0150     regmap_update_bits(pwrkey->regmap, PON_CNTL_1, mask, val);
0151 }
0152 
0153 /*
0154  * Set an SMPS regulator to be disabled in its CTRL register, but enabled
0155  * in the master enable register.  Also set it's pull down enable bit.
0156  * Take care to make sure that the output voltage doesn't change if switching
0157  * from advanced mode to legacy mode.
0158  */
0159 static int pm8058_disable_smps_locally_set_pull_down(struct regmap *regmap,
0160     u16 ctrl_addr, u16 test2_addr, u16 master_enable_addr,
0161     u8 master_enable_bit)
0162 {
0163     int error;
0164     u8 vref_sel, vlow_sel, band, vprog, bank;
0165     unsigned int reg;
0166 
0167     bank = PM8058_REGULATOR_BANK_SEL(7);
0168     error = regmap_write(regmap, test2_addr, bank);
0169     if (error)
0170         return error;
0171 
0172     error = regmap_read(regmap, test2_addr, &reg);
0173     if (error)
0174         return error;
0175 
0176     reg &= PM8058_SMPS_ADVANCED_MODE_MASK;
0177     /* Check if in advanced mode. */
0178     if (reg == PM8058_SMPS_ADVANCED_MODE) {
0179         /* Determine current output voltage. */
0180         error = regmap_read(regmap, ctrl_addr, &reg);
0181         if (error)
0182             return error;
0183 
0184         band = reg & PM8058_SMPS_ADVANCED_BAND_MASK;
0185         band >>= PM8058_SMPS_ADVANCED_BAND_SHIFT;
0186         switch (band) {
0187         case 3:
0188             vref_sel = 0;
0189             vlow_sel = 0;
0190             break;
0191         case 2:
0192             vref_sel = PM8058_SMPS_LEGACY_VREF_SEL;
0193             vlow_sel = 0;
0194             break;
0195         case 1:
0196             vref_sel = PM8058_SMPS_LEGACY_VREF_SEL;
0197             vlow_sel = PM8058_SMPS_LEGACY_VLOW_SEL;
0198             break;
0199         default:
0200             pr_err("%s: regulator already disabled\n", __func__);
0201             return -EPERM;
0202         }
0203         vprog = reg & PM8058_SMPS_ADVANCED_VPROG_MASK;
0204         /* Round up if fine step is in use. */
0205         vprog = (vprog + 1) >> 1;
0206         if (vprog > PM8058_SMPS_LEGACY_VPROG_MASK)
0207             vprog = PM8058_SMPS_LEGACY_VPROG_MASK;
0208 
0209         /* Set VLOW_SEL bit. */
0210         bank = PM8058_REGULATOR_BANK_SEL(1);
0211         error = regmap_write(regmap, test2_addr, bank);
0212         if (error)
0213             return error;
0214 
0215         error = regmap_update_bits(regmap, test2_addr,
0216             PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK
0217                 | PM8058_SMPS_LEGACY_VLOW_SEL,
0218             PM8058_REGULATOR_BANK_WRITE |
0219             PM8058_REGULATOR_BANK_SEL(1) | vlow_sel);
0220         if (error)
0221             return error;
0222 
0223         /* Switch to legacy mode */
0224         bank = PM8058_REGULATOR_BANK_SEL(7);
0225         error = regmap_write(regmap, test2_addr, bank);
0226         if (error)
0227             return error;
0228 
0229         error = regmap_update_bits(regmap, test2_addr,
0230                 PM8058_REGULATOR_BANK_WRITE |
0231                 PM8058_REGULATOR_BANK_MASK |
0232                 PM8058_SMPS_ADVANCED_MODE_MASK,
0233                 PM8058_REGULATOR_BANK_WRITE |
0234                 PM8058_REGULATOR_BANK_SEL(7) |
0235                 PM8058_SMPS_LEGACY_MODE);
0236         if (error)
0237             return error;
0238 
0239         /* Enable locally, enable pull down, keep voltage the same. */
0240         error = regmap_update_bits(regmap, ctrl_addr,
0241             PM8058_REGULATOR_ENABLE_MASK |
0242             PM8058_REGULATOR_PULL_DOWN_MASK |
0243             PM8058_SMPS_LEGACY_VREF_SEL |
0244             PM8058_SMPS_LEGACY_VPROG_MASK,
0245             PM8058_REGULATOR_ENABLE | PM8058_REGULATOR_PULL_DOWN_EN
0246                 | vref_sel | vprog);
0247         if (error)
0248             return error;
0249     }
0250 
0251     /* Enable in master control register. */
0252     error = regmap_update_bits(regmap, master_enable_addr,
0253             master_enable_bit, master_enable_bit);
0254     if (error)
0255         return error;
0256 
0257     /* Disable locally and enable pull down. */
0258     return regmap_update_bits(regmap, ctrl_addr,
0259         PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK,
0260         PM8058_REGULATOR_DISABLE | PM8058_REGULATOR_PULL_DOWN_EN);
0261 }
0262 
0263 static int pm8058_disable_ldo_locally_set_pull_down(struct regmap *regmap,
0264         u16 ctrl_addr, u16 master_enable_addr, u8 master_enable_bit)
0265 {
0266     int error;
0267 
0268     /* Enable LDO in master control register. */
0269     error = regmap_update_bits(regmap, master_enable_addr,
0270             master_enable_bit, master_enable_bit);
0271     if (error)
0272         return error;
0273 
0274     /* Disable LDO in CTRL register and set pull down */
0275     return regmap_update_bits(regmap, ctrl_addr,
0276         PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK,
0277         PM8058_REGULATOR_DISABLE | PM8058_REGULATOR_PULL_DOWN_EN);
0278 }
0279 
0280 static int pm8058_pwrkey_shutdown(struct pmic8xxx_pwrkey *pwrkey, bool reset)
0281 {
0282     int error;
0283     struct regmap *regmap = pwrkey->regmap;
0284     u8 mask, val;
0285 
0286     /* When shutting down, enable active pulldowns on important rails. */
0287     if (!reset) {
0288         /* Disable SMPS's 0,1,3 locally and set pulldown enable bits. */
0289         pm8058_disable_smps_locally_set_pull_down(regmap,
0290             PM8058_S0_CTRL, PM8058_S0_TEST2,
0291             REG_PM8058_VREG_EN_MSM, BIT(7));
0292         pm8058_disable_smps_locally_set_pull_down(regmap,
0293             PM8058_S1_CTRL, PM8058_S1_TEST2,
0294             REG_PM8058_VREG_EN_MSM, BIT(6));
0295         pm8058_disable_smps_locally_set_pull_down(regmap,
0296             PM8058_S3_CTRL, PM8058_S3_TEST2,
0297             REG_PM8058_VREG_EN_GRP_5_4, BIT(7) | BIT(4));
0298         /* Disable LDO 21 locally and set pulldown enable bit. */
0299         pm8058_disable_ldo_locally_set_pull_down(regmap,
0300             PM8058_L21_CTRL, REG_PM8058_VREG_EN_GRP_5_4,
0301             BIT(1));
0302     }
0303 
0304     /*
0305      * Fix-up: Set regulator LDO22 to 1.225 V in high power mode. Leave its
0306      * pull-down state intact. This ensures a safe shutdown.
0307      */
0308     error = regmap_update_bits(regmap, PM8058_L22_CTRL, 0xbf, 0x93);
0309     if (error)
0310         return error;
0311 
0312     /* Enable SMPL if resetting is desired */
0313     mask = SLEEP_CTRL_SMPL_EN_RESET;
0314     val = 0;
0315     if (reset)
0316         val = mask;
0317     return regmap_update_bits(regmap, PM8058_SLEEP_CTRL, mask, val);
0318 }
0319 
0320 static int pm8921_pwrkey_shutdown(struct pmic8xxx_pwrkey *pwrkey, bool reset)
0321 {
0322     struct regmap *regmap = pwrkey->regmap;
0323     u8 mask = SLEEP_CTRL_SMPL_EN_RESET;
0324     u8 val = 0;
0325 
0326     /* Enable SMPL if resetting is desired */
0327     if (reset)
0328         val = mask;
0329     return regmap_update_bits(regmap, PM8921_SLEEP_CTRL, mask, val);
0330 }
0331 
0332 static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
0333 {
0334     struct input_dev *pwr;
0335     int key_release_irq = platform_get_irq(pdev, 0);
0336     int key_press_irq = platform_get_irq(pdev, 1);
0337     int err;
0338     unsigned int delay;
0339     unsigned int pon_cntl;
0340     struct regmap *regmap;
0341     struct pmic8xxx_pwrkey *pwrkey;
0342     u32 kpd_delay;
0343     bool pull_up;
0344 
0345     if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay))
0346         kpd_delay = 15625;
0347 
0348     /* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */
0349     if (kpd_delay > USEC_PER_SEC * 2 || kpd_delay < USEC_PER_SEC / 64) {
0350         dev_err(&pdev->dev, "invalid power key trigger delay\n");
0351         return -EINVAL;
0352     }
0353 
0354     pull_up = of_property_read_bool(pdev->dev.of_node, "pull-up");
0355 
0356     regmap = dev_get_regmap(pdev->dev.parent, NULL);
0357     if (!regmap) {
0358         dev_err(&pdev->dev, "failed to locate regmap for the device\n");
0359         return -ENODEV;
0360     }
0361 
0362     pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
0363     if (!pwrkey)
0364         return -ENOMEM;
0365 
0366     pwrkey->shutdown_fn = of_device_get_match_data(&pdev->dev);
0367     pwrkey->regmap = regmap;
0368     pwrkey->key_press_irq = key_press_irq;
0369 
0370     pwr = devm_input_allocate_device(&pdev->dev);
0371     if (!pwr) {
0372         dev_dbg(&pdev->dev, "Can't allocate power button\n");
0373         return -ENOMEM;
0374     }
0375 
0376     input_set_capability(pwr, EV_KEY, KEY_POWER);
0377 
0378     pwr->name = "pmic8xxx_pwrkey";
0379     pwr->phys = "pmic8xxx_pwrkey/input0";
0380 
0381     delay = (kpd_delay << 6) / USEC_PER_SEC;
0382     delay = ilog2(delay);
0383 
0384     err = regmap_read(regmap, PON_CNTL_1, &pon_cntl);
0385     if (err < 0) {
0386         dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err);
0387         return err;
0388     }
0389 
0390     pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK;
0391     pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK);
0392     if (pull_up)
0393         pon_cntl |= PON_CNTL_PULL_UP;
0394     else
0395         pon_cntl &= ~PON_CNTL_PULL_UP;
0396 
0397     err = regmap_write(regmap, PON_CNTL_1, pon_cntl);
0398     if (err < 0) {
0399         dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err);
0400         return err;
0401     }
0402 
0403     err = devm_request_irq(&pdev->dev, key_press_irq, pwrkey_press_irq,
0404                    IRQF_TRIGGER_RISING,
0405                    "pmic8xxx_pwrkey_press", pwr);
0406     if (err) {
0407         dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
0408             key_press_irq, err);
0409         return err;
0410     }
0411 
0412     err = devm_request_irq(&pdev->dev, key_release_irq, pwrkey_release_irq,
0413                    IRQF_TRIGGER_RISING,
0414                    "pmic8xxx_pwrkey_release", pwr);
0415     if (err) {
0416         dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
0417             key_release_irq, err);
0418         return err;
0419     }
0420 
0421     err = input_register_device(pwr);
0422     if (err) {
0423         dev_err(&pdev->dev, "Can't register power key: %d\n", err);
0424         return err;
0425     }
0426 
0427     platform_set_drvdata(pdev, pwrkey);
0428     device_init_wakeup(&pdev->dev, 1);
0429 
0430     return 0;
0431 }
0432 
0433 static const struct of_device_id pm8xxx_pwr_key_id_table[] = {
0434     { .compatible = "qcom,pm8058-pwrkey", .data = &pm8058_pwrkey_shutdown },
0435     { .compatible = "qcom,pm8921-pwrkey", .data = &pm8921_pwrkey_shutdown },
0436     { }
0437 };
0438 MODULE_DEVICE_TABLE(of, pm8xxx_pwr_key_id_table);
0439 
0440 static struct platform_driver pmic8xxx_pwrkey_driver = {
0441     .probe      = pmic8xxx_pwrkey_probe,
0442     .shutdown   = pmic8xxx_pwrkey_shutdown,
0443     .driver     = {
0444         .name   = "pm8xxx-pwrkey",
0445         .pm = &pm8xxx_pwr_key_pm_ops,
0446         .of_match_table = pm8xxx_pwr_key_id_table,
0447     },
0448 };
0449 module_platform_driver(pmic8xxx_pwrkey_driver);
0450 
0451 MODULE_ALIAS("platform:pmic8xxx_pwrkey");
0452 MODULE_DESCRIPTION("PMIC8XXX Power Key driver");
0453 MODULE_LICENSE("GPL v2");
0454 MODULE_AUTHOR("Trilok Soni <tsoni@codeaurora.org>");