0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/bitfield.h>
0011 #include <linux/init.h>
0012 #include <linux/input.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/kernel.h>
0015 #include <linux/mfd/palmas.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/slab.h>
0020
0021 #define PALMAS_LPK_TIME_MASK 0x0c
0022 #define PALMAS_PWRON_DEBOUNCE_MASK 0x03
0023 #define PALMAS_PWR_KEY_Q_TIME_MS 20
0024
0025
0026
0027
0028
0029
0030
0031
0032 struct palmas_pwron {
0033 struct palmas *palmas;
0034 struct input_dev *input_dev;
0035 struct delayed_work input_work;
0036 int irq;
0037 };
0038
0039
0040
0041
0042
0043
0044 struct palmas_pwron_config {
0045 u8 long_press_time_val;
0046 u8 pwron_debounce_val;
0047 };
0048
0049
0050
0051
0052
0053 static void palmas_power_button_work(struct work_struct *work)
0054 {
0055 struct palmas_pwron *pwron = container_of(work,
0056 struct palmas_pwron,
0057 input_work.work);
0058 struct input_dev *input_dev = pwron->input_dev;
0059 unsigned int reg;
0060 int error;
0061
0062 error = palmas_read(pwron->palmas, PALMAS_INTERRUPT_BASE,
0063 PALMAS_INT1_LINE_STATE, ®);
0064 if (error) {
0065 dev_err(input_dev->dev.parent,
0066 "Cannot read palmas PWRON status: %d\n", error);
0067 } else if (reg & BIT(1)) {
0068
0069 input_report_key(input_dev, KEY_POWER, 0);
0070 input_sync(input_dev);
0071 } else {
0072
0073 schedule_delayed_work(&pwron->input_work,
0074 msecs_to_jiffies(PALMAS_PWR_KEY_Q_TIME_MS));
0075 }
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085 static irqreturn_t pwron_irq(int irq, void *palmas_pwron)
0086 {
0087 struct palmas_pwron *pwron = palmas_pwron;
0088 struct input_dev *input_dev = pwron->input_dev;
0089
0090 input_report_key(input_dev, KEY_POWER, 1);
0091 pm_wakeup_event(input_dev->dev.parent, 0);
0092 input_sync(input_dev);
0093
0094 mod_delayed_work(system_wq, &pwron->input_work,
0095 msecs_to_jiffies(PALMAS_PWR_KEY_Q_TIME_MS));
0096
0097 return IRQ_HANDLED;
0098 }
0099
0100
0101
0102
0103
0104
0105 static void palmas_pwron_params_ofinit(struct device *dev,
0106 struct palmas_pwron_config *config)
0107 {
0108 struct device_node *np;
0109 u32 val;
0110 int i, error;
0111 static const u8 lpk_times[] = { 6, 8, 10, 12 };
0112 static const int pwr_on_deb_ms[] = { 15, 100, 500, 1000 };
0113
0114 memset(config, 0, sizeof(*config));
0115
0116
0117 config->long_press_time_val = ARRAY_SIZE(lpk_times) - 1;
0118
0119 np = dev->of_node;
0120 if (!np)
0121 return;
0122
0123 error = of_property_read_u32(np, "ti,palmas-long-press-seconds", &val);
0124 if (!error) {
0125 for (i = 0; i < ARRAY_SIZE(lpk_times); i++) {
0126 if (val <= lpk_times[i]) {
0127 config->long_press_time_val = i;
0128 break;
0129 }
0130 }
0131 }
0132
0133 error = of_property_read_u32(np,
0134 "ti,palmas-pwron-debounce-milli-seconds",
0135 &val);
0136 if (!error) {
0137 for (i = 0; i < ARRAY_SIZE(pwr_on_deb_ms); i++) {
0138 if (val <= pwr_on_deb_ms[i]) {
0139 config->pwron_debounce_val = i;
0140 break;
0141 }
0142 }
0143 }
0144
0145 dev_info(dev, "h/w controlled shutdown duration=%d seconds\n",
0146 lpk_times[config->long_press_time_val]);
0147 }
0148
0149
0150
0151
0152
0153
0154
0155 static int palmas_pwron_probe(struct platform_device *pdev)
0156 {
0157 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
0158 struct device *dev = &pdev->dev;
0159 struct input_dev *input_dev;
0160 struct palmas_pwron *pwron;
0161 struct palmas_pwron_config config;
0162 int val;
0163 int error;
0164
0165 palmas_pwron_params_ofinit(dev, &config);
0166
0167 pwron = kzalloc(sizeof(*pwron), GFP_KERNEL);
0168 if (!pwron)
0169 return -ENOMEM;
0170
0171 input_dev = input_allocate_device();
0172 if (!input_dev) {
0173 dev_err(dev, "Can't allocate power button\n");
0174 error = -ENOMEM;
0175 goto err_free_mem;
0176 }
0177
0178 input_dev->name = "palmas_pwron";
0179 input_dev->phys = "palmas_pwron/input0";
0180 input_dev->dev.parent = dev;
0181
0182 input_set_capability(input_dev, EV_KEY, KEY_POWER);
0183
0184
0185
0186
0187
0188 val = FIELD_PREP(PALMAS_LPK_TIME_MASK, config.long_press_time_val) |
0189 FIELD_PREP(PALMAS_PWRON_DEBOUNCE_MASK, config.pwron_debounce_val);
0190 error = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
0191 PALMAS_LONG_PRESS_KEY,
0192 PALMAS_LPK_TIME_MASK |
0193 PALMAS_PWRON_DEBOUNCE_MASK,
0194 val);
0195 if (error) {
0196 dev_err(dev, "LONG_PRESS_KEY_UPDATE failed: %d\n", error);
0197 goto err_free_input;
0198 }
0199
0200 pwron->palmas = palmas;
0201 pwron->input_dev = input_dev;
0202
0203 INIT_DELAYED_WORK(&pwron->input_work, palmas_power_button_work);
0204
0205 pwron->irq = platform_get_irq(pdev, 0);
0206 if (pwron->irq < 0) {
0207 error = pwron->irq;
0208 goto err_free_input;
0209 }
0210
0211 error = request_threaded_irq(pwron->irq, NULL, pwron_irq,
0212 IRQF_TRIGGER_HIGH |
0213 IRQF_TRIGGER_LOW |
0214 IRQF_ONESHOT,
0215 dev_name(dev), pwron);
0216 if (error) {
0217 dev_err(dev, "Can't get IRQ for pwron: %d\n", error);
0218 goto err_free_input;
0219 }
0220
0221 error = input_register_device(input_dev);
0222 if (error) {
0223 dev_err(dev, "Can't register power button: %d\n", error);
0224 goto err_free_irq;
0225 }
0226
0227 platform_set_drvdata(pdev, pwron);
0228 device_init_wakeup(dev, true);
0229
0230 return 0;
0231
0232 err_free_irq:
0233 cancel_delayed_work_sync(&pwron->input_work);
0234 free_irq(pwron->irq, pwron);
0235 err_free_input:
0236 input_free_device(input_dev);
0237 err_free_mem:
0238 kfree(pwron);
0239 return error;
0240 }
0241
0242
0243
0244
0245
0246
0247
0248 static int palmas_pwron_remove(struct platform_device *pdev)
0249 {
0250 struct palmas_pwron *pwron = platform_get_drvdata(pdev);
0251
0252 free_irq(pwron->irq, pwron);
0253 cancel_delayed_work_sync(&pwron->input_work);
0254
0255 input_unregister_device(pwron->input_dev);
0256 kfree(pwron);
0257
0258 return 0;
0259 }
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 static int __maybe_unused palmas_pwron_suspend(struct device *dev)
0270 {
0271 struct platform_device *pdev = to_platform_device(dev);
0272 struct palmas_pwron *pwron = platform_get_drvdata(pdev);
0273
0274 cancel_delayed_work_sync(&pwron->input_work);
0275
0276 if (device_may_wakeup(dev))
0277 enable_irq_wake(pwron->irq);
0278
0279 return 0;
0280 }
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 static int __maybe_unused palmas_pwron_resume(struct device *dev)
0291 {
0292 struct platform_device *pdev = to_platform_device(dev);
0293 struct palmas_pwron *pwron = platform_get_drvdata(pdev);
0294
0295 if (device_may_wakeup(dev))
0296 disable_irq_wake(pwron->irq);
0297
0298 return 0;
0299 }
0300
0301 static SIMPLE_DEV_PM_OPS(palmas_pwron_pm,
0302 palmas_pwron_suspend, palmas_pwron_resume);
0303
0304 #ifdef CONFIG_OF
0305 static const struct of_device_id of_palmas_pwr_match[] = {
0306 { .compatible = "ti,palmas-pwrbutton" },
0307 { },
0308 };
0309
0310 MODULE_DEVICE_TABLE(of, of_palmas_pwr_match);
0311 #endif
0312
0313 static struct platform_driver palmas_pwron_driver = {
0314 .probe = palmas_pwron_probe,
0315 .remove = palmas_pwron_remove,
0316 .driver = {
0317 .name = "palmas_pwrbutton",
0318 .of_match_table = of_match_ptr(of_palmas_pwr_match),
0319 .pm = &palmas_pwron_pm,
0320 },
0321 };
0322 module_platform_driver(palmas_pwron_driver);
0323
0324 MODULE_ALIAS("platform:palmas-pwrbutton");
0325 MODULE_DESCRIPTION("Palmas Power Button");
0326 MODULE_LICENSE("GPL v2");
0327 MODULE_AUTHOR("Texas Instruments Inc.");