From: sashiko-bot@kernel.org
To: "Griffin Kroah-Hartman" <griffin.kroah@fairphone.com>
Cc: linux-input@vger.kernel.org, devicetree@vger.kernel.org,
robh@kernel.org, conor+dt@kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH v3 2/4] Input - aw8695: Add driver for AW8695 haptics
Date: Thu, 22 Oct 2026 09:35:41 +0000 [thread overview]
Message-ID: <sashiko-outbox-181268@kernel.org> (raw)
In-Reply-To: <20261022-aw8695_haptic_fp4_driver-v3-2-ac8c14377e82@fairphone.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] Input: aw8695: aw8695_play_sine() never programs haptics->level into hardware
- [Medium] Input: aw8695: stale haptics->level after aw8695_stop() in suspend and close
- [Medium] Input: aw8695: broken PM state and work ordering in aw8695_resume()
--
commit bce746a2c97df6a59e51d7534cd56d7486fc93b8
Author: Luca Weiss <luca.weiss@fairphone.com>
Input - aw8695: Add driver for AW8695 haptics
This commit adds an input force-feedback driver for the Awinic AW8695
haptic controller using RAM mode playback of a sine wave.
> diff --git a/drivers/input/misc/aw8695.c b/drivers/input/misc/aw8695.c
> new file mode 100644
> index 0000000000000..45c68c673c26c
> --- /dev/null
> +++ b/drivers/input/misc/aw8695.c
> @@ -0,0 +1,805 @@
[ ... ]
> +static int aw8695_haptics_play(struct input_dev *dev, void *data,
> + struct ff_effect *effect)
> +{
> + struct aw8695_data *haptics = input_get_drvdata(dev);
> + int level;
> +
> + level = effect->u.rumble.strong_magnitude;
> + if (!level)
> + level = effect->u.rumble.weak_magnitude;
> +
> + if (haptics->level == level)
> + return 0;
> +
> + haptics->level = level;
> + schedule_work(&haptics->play_work);
> +
> + return 0;
> +}
[ ... ]
> +static int aw8695_play_sine(struct aw8695_data *haptics)
> +{
> + int err;
> +
> + err = aw8695_stop(haptics);
> + if (err)
> + return err;
> +
> + /*
> + * Configure for waveform #1 to be played infinitely,
> + * and waveform #2 to not be played.
> + */
> + err = regmap_write(haptics->regmap, AW8695_WAVSEQ1_REG, 0x1);
> + if (err)
> + return err;
> +
> + err = regmap_write(haptics->regmap, AW8695_WAVSEQ2_REG, 0x0);
> + if (err)
> + return err;
> +
> + err = regmap_write(haptics->regmap, AW8695_WAVLOOP1_REG,
> + FIELD_PREP(AW8695_WAVLOOP1_SEQ1_MASK,
> + AW8695_WAVLOOP_INFINITE) |
> + FIELD_PREP(AW8695_WAVLOOP1_SEQ2_MASK, 0));
> + if (err)
> + return err;
> +
> + /* Configure for RAM mode */
> + err = aw8695_play_mode(haptics, AW8695_RAM_MODE);
> + if (err)
> + return err;
> +
> + /* Start vibration */
> + err = regmap_update_bits(haptics->regmap, AW8695_GO_REG,
> + AW8695_GO_ENABLE, AW8695_GO_ENABLE);
> + if (err)
> + return err;
> +
> + return 0;
> +}
> +
> +static void aw8695_close(struct input_dev *input)
> +{
> + struct aw8695_data *haptics = input_get_drvdata(input);
> + struct device *dev = &haptics->client->dev;
> + int err;
> +
> + cancel_work_sync(&haptics->play_work);
> + err = aw8695_stop(haptics);
> + if (err)
> + dev_err(dev, "Failed to stop haptics: %d\n", err);
> +}
[Severity: Medium]
When aw8695_close() or aw8695_suspend() stops the motor via aw8695_stop(),
haptics->level is not reset to 0. Similarly, if aw8695_haptics_play() is
called while play_work is disabled during system suspend, haptics->level is
updated even though schedule_work(&haptics->play_work) does not queue the
work and aw8695_resume() does not restart playback.
If a subsequent effect is played with the same magnitude after the device is
reopened or resumed, won't aw8695_haptics_play() see haptics->level == level
and return early without starting vibration?
> +
> +static void aw8695_haptics_play_work(struct work_struct *work)
> +{
> + struct aw8695_data *haptics =
> + container_of(work, struct aw8695_data, play_work);
> + struct device *dev = &haptics->client->dev;
> + int err;
> +
> + if (haptics->suspend)
> + return;
> +
> + if (haptics->level)
> + err = aw8695_play_sine(haptics);
> + else
> + err = aw8695_stop(haptics);
> +
> + if (err)
> + dev_err(dev, "Failed to execute work command: %d\n", err);
> +}
[Severity: Medium]
In aw8695_haptics_play(), the 16-bit rumble magnitude is stored in
haptics->level and play_work is scheduled whenever that value changes.
However, aw8695_haptics_play_work() only checks whether haptics->level is
non-zero, and aw8695_play_sine() never writes a scaled gain value to the
hardware.
As a result, all effects play at a fixed amplitude, and any change between
two non-zero magnitudes (for example, during an ff-memless periodic envelope
fade in ml_effect_timer() or a gain update) causes aw8695_play_sine() to call
aw8695_stop(), poll AW8695_GLB_STATE_REG for standby, and restart the same
fixed-amplitude waveform from the beginning.
Should aw8695_play_sine() program a hardware gain register based on
haptics->level?
[ ... ]
> +static int aw8695_suspend(struct device *dev)
> +{
> + struct aw8695_data *haptics = dev_get_drvdata(dev);
> +
> + if (haptics->suspend)
> + return 0;
> +
> + disable_work_sync(&haptics->play_work);
> + aw8695_stop(haptics);
> + haptics->suspend = true;
> + return 0;
> +}
> +
> +static int aw8695_resume(struct device *dev)
> +{
> + struct aw8695_data *haptics = dev_get_drvdata(dev);
> +
> + if (!haptics->suspend)
> + return 0;
> +
> + enable_work(&haptics->play_work);
> + aw8695_haptic_set_active(haptics);
> + haptics->suspend = false;
> + return 0;
> +}
[Severity: Medium]
There seem to be a few issues in aw8695_suspend() and aw8695_resume():
First, during normal operation aw8695_init() and aw8695_stop() leave the
device in AW8695_STANDBY_MODE when idle, only entering AW8695_SYSCTRL_ACTIVE
via aw8695_play_mode() when aw8695_play_sine() starts playback. However,
aw8695_resume() unconditionally calls aw8695_haptic_set_active(), which puts
the chip into active mode and clears AW8695_SYSINTM_UVLO_OFF even when no
effect is playing.
Second, aw8695_resume() calls enable_work(&haptics->play_work) before the
blocking regmap accesses in aw8695_haptic_set_active() and before clearing
haptics->suspend. If play_work is scheduled and runs during that window,
aw8695_haptics_play_work() will see haptics->suspend set to true and return
early, dropping the playback request.
Third, both aw8695_suspend() and aw8695_resume() ignore the error values
returned by aw8695_stop() and aw8695_haptic_set_active().
Could aw8695_resume() avoid forcing the chip active when idle, clear
haptics->suspend before calling enable_work(), and propagate errors from the
hardware helper calls?
[ ... ]
> +}
> +
> +module_i2c_driver(aw8695_driver);
> +
> +MODULE_AUTHOR("Luca Weiss <luca.weiss@fairphone.com>");
> +MODULE_DESCRIPTION("AW8695 LRA Haptic Driver");
> +MODULE_LICENSE("GPL");
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261022-aw8695_haptic_fp4_driver-v3-0-ac8c14377e82@fairphone.com?part=2
next prev parent reply other threads:[~2026-10-22 9:35 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 9:19 [PATCH v3 0/4] AW8695 haptic driver Griffin Kroah-Hartman
2026-10-22 9:19 ` [PATCH v3 1/4] dt-bindings: input: Add compatibility for Awinic AW8695 Griffin Kroah-Hartman
2026-10-22 14:27 ` Rob Herring
2026-10-22 9:19 ` [PATCH v3 2/4] Input - aw8695: Add driver for AW8695 haptics Griffin Kroah-Hartman
2026-10-22 9:35 ` sashiko-bot [this message]
2026-10-22 9:19 ` [PATCH v3 3/4] arm64: dts: qcom: sm7225-fairphone-fp4: Add " Griffin Kroah-Hartman
2026-10-22 9:39 ` sashiko-bot
2026-10-22 9:19 ` [PATCH v3 4/4] MAINTAINERS: add entry for AWINIC haptic driver family Griffin Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-181268@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=griffin.kroah@fairphone.com \
--cc=linux-input@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.