root/drivers/input/misc/gpio-vibra.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gpio_vibrator_start
  2. gpio_vibrator_stop
  3. gpio_vibrator_play_work
  4. gpio_vibrator_play_effect
  5. gpio_vibrator_close
  6. gpio_vibrator_probe
  7. gpio_vibrator_suspend
  8. gpio_vibrator_resume

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  *  GPIO vibrator driver
   4  *
   5  *  Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz>
   6  *
   7  *  Based on PWM vibrator driver:
   8  *  Copyright (C) 2017 Collabora Ltd.
   9  *
  10  *  Based on previous work from:
  11  *  Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com>
  12  *
  13  *  Based on PWM beeper driver:
  14  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
  15  */
  16 
  17 #include <linux/gpio/consumer.h>
  18 #include <linux/input.h>
  19 #include <linux/kernel.h>
  20 #include <linux/module.h>
  21 #include <linux/of_device.h>
  22 #include <linux/platform_device.h>
  23 #include <linux/property.h>
  24 #include <linux/regulator/consumer.h>
  25 #include <linux/slab.h>
  26 
  27 struct gpio_vibrator {
  28         struct input_dev *input;
  29         struct gpio_desc *gpio;
  30         struct regulator *vcc;
  31 
  32         struct work_struct play_work;
  33         bool running;
  34         bool vcc_on;
  35 };
  36 
  37 static int gpio_vibrator_start(struct gpio_vibrator *vibrator)
  38 {
  39         struct device *pdev = vibrator->input->dev.parent;
  40         int err;
  41 
  42         if (!vibrator->vcc_on) {
  43                 err = regulator_enable(vibrator->vcc);
  44                 if (err) {
  45                         dev_err(pdev, "failed to enable regulator: %d\n", err);
  46                         return err;
  47                 }
  48                 vibrator->vcc_on = true;
  49         }
  50 
  51         gpiod_set_value_cansleep(vibrator->gpio, 1);
  52 
  53         return 0;
  54 }
  55 
  56 static void gpio_vibrator_stop(struct gpio_vibrator *vibrator)
  57 {
  58         gpiod_set_value_cansleep(vibrator->gpio, 0);
  59 
  60         if (vibrator->vcc_on) {
  61                 regulator_disable(vibrator->vcc);
  62                 vibrator->vcc_on = false;
  63         }
  64 }
  65 
  66 static void gpio_vibrator_play_work(struct work_struct *work)
  67 {
  68         struct gpio_vibrator *vibrator =
  69                 container_of(work, struct gpio_vibrator, play_work);
  70 
  71         if (vibrator->running)
  72                 gpio_vibrator_start(vibrator);
  73         else
  74                 gpio_vibrator_stop(vibrator);
  75 }
  76 
  77 static int gpio_vibrator_play_effect(struct input_dev *dev, void *data,
  78                                      struct ff_effect *effect)
  79 {
  80         struct gpio_vibrator *vibrator = input_get_drvdata(dev);
  81         int level;
  82 
  83         level = effect->u.rumble.strong_magnitude;
  84         if (!level)
  85                 level = effect->u.rumble.weak_magnitude;
  86 
  87         vibrator->running = level;
  88         schedule_work(&vibrator->play_work);
  89 
  90         return 0;
  91 }
  92 
  93 static void gpio_vibrator_close(struct input_dev *input)
  94 {
  95         struct gpio_vibrator *vibrator = input_get_drvdata(input);
  96 
  97         cancel_work_sync(&vibrator->play_work);
  98         gpio_vibrator_stop(vibrator);
  99         vibrator->running = false;
 100 }
 101 
 102 static int gpio_vibrator_probe(struct platform_device *pdev)
 103 {
 104         struct gpio_vibrator *vibrator;
 105         int err;
 106 
 107         vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
 108         if (!vibrator)
 109                 return -ENOMEM;
 110 
 111         vibrator->input = devm_input_allocate_device(&pdev->dev);
 112         if (!vibrator->input)
 113                 return -ENOMEM;
 114 
 115         vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
 116         err = PTR_ERR_OR_ZERO(vibrator->vcc);
 117         if (err) {
 118                 if (err != -EPROBE_DEFER)
 119                         dev_err(&pdev->dev, "Failed to request regulator: %d\n",
 120                                 err);
 121                 return err;
 122         }
 123 
 124         vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
 125         err = PTR_ERR_OR_ZERO(vibrator->gpio);
 126         if (err) {
 127                 if (err != -EPROBE_DEFER)
 128                         dev_err(&pdev->dev, "Failed to request main gpio: %d\n",
 129                                 err);
 130                 return err;
 131         }
 132 
 133         INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
 134 
 135         vibrator->input->name = "gpio-vibrator";
 136         vibrator->input->id.bustype = BUS_HOST;
 137         vibrator->input->close = gpio_vibrator_close;
 138 
 139         input_set_drvdata(vibrator->input, vibrator);
 140         input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
 141 
 142         err = input_ff_create_memless(vibrator->input, NULL,
 143                                       gpio_vibrator_play_effect);
 144         if (err) {
 145                 dev_err(&pdev->dev, "Couldn't create FF dev: %d\n", err);
 146                 return err;
 147         }
 148 
 149         err = input_register_device(vibrator->input);
 150         if (err) {
 151                 dev_err(&pdev->dev, "Couldn't register input dev: %d\n", err);
 152                 return err;
 153         }
 154 
 155         platform_set_drvdata(pdev, vibrator);
 156 
 157         return 0;
 158 }
 159 
 160 static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
 161 {
 162         struct platform_device *pdev = to_platform_device(dev);
 163         struct gpio_vibrator *vibrator = platform_get_drvdata(pdev);
 164 
 165         cancel_work_sync(&vibrator->play_work);
 166         if (vibrator->running)
 167                 gpio_vibrator_stop(vibrator);
 168 
 169         return 0;
 170 }
 171 
 172 static int __maybe_unused gpio_vibrator_resume(struct device *dev)
 173 {
 174         struct platform_device *pdev = to_platform_device(dev);
 175         struct gpio_vibrator *vibrator = platform_get_drvdata(pdev);
 176 
 177         if (vibrator->running)
 178                 gpio_vibrator_start(vibrator);
 179 
 180         return 0;
 181 }
 182 
 183 static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops,
 184                          gpio_vibrator_suspend, gpio_vibrator_resume);
 185 
 186 #ifdef CONFIG_OF
 187 static const struct of_device_id gpio_vibra_dt_match_table[] = {
 188         { .compatible = "gpio-vibrator" },
 189         {}
 190 };
 191 MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table);
 192 #endif
 193 
 194 static struct platform_driver gpio_vibrator_driver = {
 195         .probe  = gpio_vibrator_probe,
 196         .driver = {
 197                 .name   = "gpio-vibrator",
 198                 .pm     = &gpio_vibrator_pm_ops,
 199                 .of_match_table = of_match_ptr(gpio_vibra_dt_match_table),
 200         },
 201 };
 202 module_platform_driver(gpio_vibrator_driver);
 203 
 204 MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>");
 205 MODULE_DESCRIPTION("GPIO vibrator driver");
 206 MODULE_LICENSE("GPL");
 207 MODULE_ALIAS("platform:gpio-vibrator");

/* [<][>][^][v][top][bottom][index][help] */