Message ID | 20230427-hammerhead-vibra-v1-3-e87eeb94da51@z3ntu.xyz |
---|---|
State | Accepted |
Commit | bcf784985e35fc39d682f0dde750162e7f54a1f0 |
Headers | show |
Series | Add haptics support to Nexus 5 using pwm-vibra driver | expand |
Hi, On Thu, Apr 27, 2023 at 10:34:28PM +0200, Luca Weiss wrote: > Some pwm vibrators have a dedicated enable GPIO that needs to be set > high so that the vibrator works. Add support for that optionally. > > Signed-off-by: Luca Weiss <luca@z3ntu.xyz> > --- Reviewed-by: Sebastian Reichel <sre@kernel.org> -- Sebastian > drivers/input/misc/pwm-vibra.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c > index c08971c97ad6..2ba035299db8 100644 > --- a/drivers/input/misc/pwm-vibra.c > +++ b/drivers/input/misc/pwm-vibra.c > @@ -11,6 +11,7 @@ > * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> > */ > > +#include <linux/gpio/consumer.h> > #include <linux/input.h> > #include <linux/kernel.h> > #include <linux/module.h> > @@ -23,6 +24,7 @@ > > struct pwm_vibrator { > struct input_dev *input; > + struct gpio_desc *enable_gpio; > struct pwm_device *pwm; > struct pwm_device *pwm_dir; > struct regulator *vcc; > @@ -48,6 +50,8 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) > vibrator->vcc_on = true; > } > > + gpiod_set_value_cansleep(vibrator->enable_gpio, 1); > + > pwm_get_state(vibrator->pwm, &state); > pwm_set_relative_duty_cycle(&state, vibrator->level, 0xffff); > state.enabled = true; > @@ -80,6 +84,8 @@ static void pwm_vibrator_stop(struct pwm_vibrator *vibrator) > pwm_disable(vibrator->pwm_dir); > pwm_disable(vibrator->pwm); > > + gpiod_set_value_cansleep(vibrator->enable_gpio, 0); > + > if (vibrator->vcc_on) { > regulator_disable(vibrator->vcc); > vibrator->vcc_on = false; > @@ -142,6 +148,16 @@ static int pwm_vibrator_probe(struct platform_device *pdev) > return err; > } > > + vibrator->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", > + GPIOD_OUT_LOW); > + err = PTR_ERR_OR_ZERO(vibrator->enable_gpio); > + if (err) { > + if (err != -EPROBE_DEFER) > + dev_err(&pdev->dev, "Failed to request enable gpio: %d\n", > + err); > + return err; > + } > + > vibrator->pwm = devm_pwm_get(&pdev->dev, "enable"); > err = PTR_ERR_OR_ZERO(vibrator->pwm); > if (err) { > > -- > 2.40.0 >
On Dienstag, 2. Mai 2023 02:47:29 CEST Dmitry Torokhov wrote: > On Thu, Apr 27, 2023 at 10:34:28PM +0200, Luca Weiss wrote: > > Some pwm vibrators have a dedicated enable GPIO that needs to be set > > high so that the vibrator works. Add support for that optionally. > > So this is not simply a power supply in your case controlled by a GPIO? > We truly can have both GPIO and a separate regulator? Yes it appears to be the EN pin on the ISA1000A, see https://electronics.stackexchange.com/q/380475 On apq8026-lg-lenok there is a similar setup for the vibration motor although there I don't know whether it's actually a fixed-regulator or not, but since the two devices were built in a similar time (without checking further) I could assume they both contain the same IC. Regards Luca > > Thanks.
diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index c08971c97ad6..2ba035299db8 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -11,6 +11,7 @@ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> */ +#include <linux/gpio/consumer.h> #include <linux/input.h> #include <linux/kernel.h> #include <linux/module.h> @@ -23,6 +24,7 @@ struct pwm_vibrator { struct input_dev *input; + struct gpio_desc *enable_gpio; struct pwm_device *pwm; struct pwm_device *pwm_dir; struct regulator *vcc; @@ -48,6 +50,8 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) vibrator->vcc_on = true; } + gpiod_set_value_cansleep(vibrator->enable_gpio, 1); + pwm_get_state(vibrator->pwm, &state); pwm_set_relative_duty_cycle(&state, vibrator->level, 0xffff); state.enabled = true; @@ -80,6 +84,8 @@ static void pwm_vibrator_stop(struct pwm_vibrator *vibrator) pwm_disable(vibrator->pwm_dir); pwm_disable(vibrator->pwm); + gpiod_set_value_cansleep(vibrator->enable_gpio, 0); + if (vibrator->vcc_on) { regulator_disable(vibrator->vcc); vibrator->vcc_on = false; @@ -142,6 +148,16 @@ static int pwm_vibrator_probe(struct platform_device *pdev) return err; } + vibrator->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", + GPIOD_OUT_LOW); + err = PTR_ERR_OR_ZERO(vibrator->enable_gpio); + if (err) { + if (err != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to request enable gpio: %d\n", + err); + return err; + } + vibrator->pwm = devm_pwm_get(&pdev->dev, "enable"); err = PTR_ERR_OR_ZERO(vibrator->pwm); if (err) {
Some pwm vibrators have a dedicated enable GPIO that needs to be set high so that the vibrator works. Add support for that optionally. Signed-off-by: Luca Weiss <luca@z3ntu.xyz> --- drivers/input/misc/pwm-vibra.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)