Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  PWM vibrator driver
0004  *
0005  *  Copyright (C) 2017 Collabora Ltd.
0006  *
0007  *  Based on previous work from:
0008  *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
0009  *
0010  *  Based on PWM beeper driver:
0011  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
0012  */
0013 
0014 #include <linux/input.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/of_device.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/property.h>
0020 #include <linux/pwm.h>
0021 #include <linux/regulator/consumer.h>
0022 #include <linux/slab.h>
0023 
0024 struct pwm_vibrator {
0025     struct input_dev *input;
0026     struct pwm_device *pwm;
0027     struct pwm_device *pwm_dir;
0028     struct regulator *vcc;
0029 
0030     struct work_struct play_work;
0031     u16 level;
0032     u32 direction_duty_cycle;
0033     bool vcc_on;
0034 };
0035 
0036 static int pwm_vibrator_start(struct pwm_vibrator *vibrator)
0037 {
0038     struct device *pdev = vibrator->input->dev.parent;
0039     struct pwm_state state;
0040     int err;
0041 
0042     if (!vibrator->vcc_on) {
0043         err = regulator_enable(vibrator->vcc);
0044         if (err) {
0045             dev_err(pdev, "failed to enable regulator: %d", err);
0046             return err;
0047         }
0048         vibrator->vcc_on = true;
0049     }
0050 
0051     pwm_get_state(vibrator->pwm, &state);
0052     pwm_set_relative_duty_cycle(&state, vibrator->level, 0xffff);
0053     state.enabled = true;
0054 
0055     err = pwm_apply_state(vibrator->pwm, &state);
0056     if (err) {
0057         dev_err(pdev, "failed to apply pwm state: %d", err);
0058         return err;
0059     }
0060 
0061     if (vibrator->pwm_dir) {
0062         pwm_get_state(vibrator->pwm_dir, &state);
0063         state.duty_cycle = vibrator->direction_duty_cycle;
0064         state.enabled = true;
0065 
0066         err = pwm_apply_state(vibrator->pwm_dir, &state);
0067         if (err) {
0068             dev_err(pdev, "failed to apply dir-pwm state: %d", err);
0069             pwm_disable(vibrator->pwm);
0070             return err;
0071         }
0072     }
0073 
0074     return 0;
0075 }
0076 
0077 static void pwm_vibrator_stop(struct pwm_vibrator *vibrator)
0078 {
0079     if (vibrator->pwm_dir)
0080         pwm_disable(vibrator->pwm_dir);
0081     pwm_disable(vibrator->pwm);
0082 
0083     if (vibrator->vcc_on) {
0084         regulator_disable(vibrator->vcc);
0085         vibrator->vcc_on = false;
0086     }
0087 }
0088 
0089 static void pwm_vibrator_play_work(struct work_struct *work)
0090 {
0091     struct pwm_vibrator *vibrator = container_of(work,
0092                     struct pwm_vibrator, play_work);
0093 
0094     if (vibrator->level)
0095         pwm_vibrator_start(vibrator);
0096     else
0097         pwm_vibrator_stop(vibrator);
0098 }
0099 
0100 static int pwm_vibrator_play_effect(struct input_dev *dev, void *data,
0101                     struct ff_effect *effect)
0102 {
0103     struct pwm_vibrator *vibrator = input_get_drvdata(dev);
0104 
0105     vibrator->level = effect->u.rumble.strong_magnitude;
0106     if (!vibrator->level)
0107         vibrator->level = effect->u.rumble.weak_magnitude;
0108 
0109     schedule_work(&vibrator->play_work);
0110 
0111     return 0;
0112 }
0113 
0114 static void pwm_vibrator_close(struct input_dev *input)
0115 {
0116     struct pwm_vibrator *vibrator = input_get_drvdata(input);
0117 
0118     cancel_work_sync(&vibrator->play_work);
0119     pwm_vibrator_stop(vibrator);
0120 }
0121 
0122 static int pwm_vibrator_probe(struct platform_device *pdev)
0123 {
0124     struct pwm_vibrator *vibrator;
0125     struct pwm_state state;
0126     int err;
0127 
0128     vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
0129     if (!vibrator)
0130         return -ENOMEM;
0131 
0132     vibrator->input = devm_input_allocate_device(&pdev->dev);
0133     if (!vibrator->input)
0134         return -ENOMEM;
0135 
0136     vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
0137     err = PTR_ERR_OR_ZERO(vibrator->vcc);
0138     if (err) {
0139         if (err != -EPROBE_DEFER)
0140             dev_err(&pdev->dev, "Failed to request regulator: %d",
0141                 err);
0142         return err;
0143     }
0144 
0145     vibrator->pwm = devm_pwm_get(&pdev->dev, "enable");
0146     err = PTR_ERR_OR_ZERO(vibrator->pwm);
0147     if (err) {
0148         if (err != -EPROBE_DEFER)
0149             dev_err(&pdev->dev, "Failed to request main pwm: %d",
0150                 err);
0151         return err;
0152     }
0153 
0154     INIT_WORK(&vibrator->play_work, pwm_vibrator_play_work);
0155 
0156     /* Sync up PWM state and ensure it is off. */
0157     pwm_init_state(vibrator->pwm, &state);
0158     state.enabled = false;
0159     err = pwm_apply_state(vibrator->pwm, &state);
0160     if (err) {
0161         dev_err(&pdev->dev, "failed to apply initial PWM state: %d",
0162             err);
0163         return err;
0164     }
0165 
0166     vibrator->pwm_dir = devm_pwm_get(&pdev->dev, "direction");
0167     err = PTR_ERR_OR_ZERO(vibrator->pwm_dir);
0168     switch (err) {
0169     case 0:
0170         /* Sync up PWM state and ensure it is off. */
0171         pwm_init_state(vibrator->pwm_dir, &state);
0172         state.enabled = false;
0173         err = pwm_apply_state(vibrator->pwm_dir, &state);
0174         if (err) {
0175             dev_err(&pdev->dev, "failed to apply initial PWM state: %d",
0176                 err);
0177             return err;
0178         }
0179 
0180         vibrator->direction_duty_cycle =
0181             pwm_get_period(vibrator->pwm_dir) / 2;
0182         device_property_read_u32(&pdev->dev, "direction-duty-cycle-ns",
0183                      &vibrator->direction_duty_cycle);
0184         break;
0185 
0186     case -ENODATA:
0187         /* Direction PWM is optional */
0188         vibrator->pwm_dir = NULL;
0189         break;
0190 
0191     default:
0192         dev_err(&pdev->dev, "Failed to request direction pwm: %d", err);
0193         fallthrough;
0194 
0195     case -EPROBE_DEFER:
0196         return err;
0197     }
0198 
0199     vibrator->input->name = "pwm-vibrator";
0200     vibrator->input->id.bustype = BUS_HOST;
0201     vibrator->input->dev.parent = &pdev->dev;
0202     vibrator->input->close = pwm_vibrator_close;
0203 
0204     input_set_drvdata(vibrator->input, vibrator);
0205     input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
0206 
0207     err = input_ff_create_memless(vibrator->input, NULL,
0208                       pwm_vibrator_play_effect);
0209     if (err) {
0210         dev_err(&pdev->dev, "Couldn't create FF dev: %d", err);
0211         return err;
0212     }
0213 
0214     err = input_register_device(vibrator->input);
0215     if (err) {
0216         dev_err(&pdev->dev, "Couldn't register input dev: %d", err);
0217         return err;
0218     }
0219 
0220     platform_set_drvdata(pdev, vibrator);
0221 
0222     return 0;
0223 }
0224 
0225 static int __maybe_unused pwm_vibrator_suspend(struct device *dev)
0226 {
0227     struct pwm_vibrator *vibrator = dev_get_drvdata(dev);
0228 
0229     cancel_work_sync(&vibrator->play_work);
0230     if (vibrator->level)
0231         pwm_vibrator_stop(vibrator);
0232 
0233     return 0;
0234 }
0235 
0236 static int __maybe_unused pwm_vibrator_resume(struct device *dev)
0237 {
0238     struct pwm_vibrator *vibrator = dev_get_drvdata(dev);
0239 
0240     if (vibrator->level)
0241         pwm_vibrator_start(vibrator);
0242 
0243     return 0;
0244 }
0245 
0246 static SIMPLE_DEV_PM_OPS(pwm_vibrator_pm_ops,
0247              pwm_vibrator_suspend, pwm_vibrator_resume);
0248 
0249 #ifdef CONFIG_OF
0250 static const struct of_device_id pwm_vibra_dt_match_table[] = {
0251     { .compatible = "pwm-vibrator" },
0252     {},
0253 };
0254 MODULE_DEVICE_TABLE(of, pwm_vibra_dt_match_table);
0255 #endif
0256 
0257 static struct platform_driver pwm_vibrator_driver = {
0258     .probe  = pwm_vibrator_probe,
0259     .driver = {
0260         .name   = "pwm-vibrator",
0261         .pm = &pwm_vibrator_pm_ops,
0262         .of_match_table = of_match_ptr(pwm_vibra_dt_match_table),
0263     },
0264 };
0265 module_platform_driver(pwm_vibrator_driver);
0266 
0267 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
0268 MODULE_DESCRIPTION("PWM vibrator driver");
0269 MODULE_LICENSE("GPL");
0270 MODULE_ALIAS("platform:pwm-vibrator");