[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20260128-aw86938-driver-v2-2-b51ee086aaf5@fairphone.com>
Date: Wed, 28 Jan 2026 16:51:14 +0100
From: Griffin Kroah-Hartman <griffin.kroah@...rphone.com>
To: Dmitry Torokhov <dmitry.torokhov@...il.com>,
Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>, Bjorn Andersson <andersson@...nel.org>,
Konrad Dybcio <konradybcio@...nel.org>,
Luca Weiss <luca.weiss@...rphone.com>
Cc: linux-input@...r.kernel.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-arm-msm@...r.kernel.org,
Griffin Kroah-Hartman <griffin.kroah@...rphone.com>
Subject: [PATCH v2 2/3] Input: aw86938 - add driver for Awinic AW86938
Add support for the I2C-connected Awinic AW86938 LRA haptic driver.
The AW86938 has a similar but slightly different register layout. In
particular, the boost mode register values.
The AW86938 also has some extra features that aren't implemented
in this driver yet.
Signed-off-by: Griffin Kroah-Hartman <griffin.kroah@...rphone.com>
---
drivers/input/misc/aw86927.c | 65 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 53 insertions(+), 12 deletions(-)
diff --git a/drivers/input/misc/aw86927.c b/drivers/input/misc/aw86927.c
index 8ad361239cfe3a888628b15e4dbdeed0c9ca3d1a..28ec6e42fd452a0edf1e1b9a9614e2723c6d9f93 100644
--- a/drivers/input/misc/aw86927.c
+++ b/drivers/input/misc/aw86927.c
@@ -43,6 +43,12 @@
#define AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK GENMASK(6, 0)
#define AW86927_PLAYCFG1_BST_8500MV 0x50
+#define AW86938_PLAYCFG1_REG 0x06
+#define AW86938_PLAYCFG1_BST_MODE_MASK GENMASK(5, 5)
+#define AW86938_PLAYCFG1_BST_MODE_BYPASS 0
+#define AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK GENMASK(4, 0)
+#define AW86938_PLAYCFG1_BST_7000MV 0x11
+
#define AW86927_PLAYCFG2_REG 0x07
#define AW86927_PLAYCFG3_REG 0x08
@@ -140,6 +146,7 @@
#define AW86927_CHIPIDH_REG 0x57
#define AW86927_CHIPIDL_REG 0x58
#define AW86927_CHIPID 0x9270
+#define AW86938_CHIPID 0x9380
#define AW86927_TMCFG_REG 0x5b
#define AW86927_TMCFG_UNLOCK 0x7d
@@ -173,7 +180,13 @@ enum aw86927_work_mode {
AW86927_RAM_MODE,
};
+enum aw86927_model {
+ AW86927,
+ AW86938,
+};
+
struct aw86927_data {
+ enum aw86927_model model;
struct work_struct play_work;
struct device *dev;
struct input_dev *input_dev;
@@ -377,7 +390,7 @@ static int aw86927_play_sine(struct aw86927_data *haptics)
return err;
/* set gain to value lower than 0x80 to avoid distorted playback */
- err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x7c);
+ err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x45);
if (err)
return err;
@@ -565,13 +578,26 @@ static int aw86927_haptic_init(struct aw86927_data *haptics)
if (err)
return err;
- err = regmap_update_bits(haptics->regmap,
- AW86927_PLAYCFG1_REG,
- AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
- FIELD_PREP(AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
- AW86927_PLAYCFG1_BST_8500MV));
- if (err)
- return err;
+ switch (haptics->model) {
+ case AW86927:
+ err = regmap_update_bits(haptics->regmap,
+ AW86927_PLAYCFG1_REG,
+ AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ FIELD_PREP(AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ AW86927_PLAYCFG1_BST_8500MV));
+ if (err)
+ return err;
+ break;
+ case AW86938:
+ err = regmap_update_bits(haptics->regmap,
+ AW86938_PLAYCFG1_REG,
+ AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ FIELD_PREP(AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ AW86938_PLAYCFG1_BST_7000MV));
+ if (err)
+ return err;
+ break;
+ }
err = regmap_update_bits(haptics->regmap,
AW86927_PLAYCFG3_REG,
@@ -599,6 +625,9 @@ static int aw86927_ram_init(struct aw86927_data *haptics)
FIELD_PREP(AW86927_SYSCTRL3_EN_RAMINIT_MASK,
AW86927_SYSCTRL3_EN_RAMINIT_ON));
+ /* AW86938 wants a 1ms delay here */
+ usleep_range(1000, 1500);
+
/* Set base address for the start of the SRAM waveforms */
err = regmap_write(haptics->regmap,
AW86927_BASEADDRH_REG, AW86927_BASEADDRH_VAL);
@@ -717,9 +746,19 @@ static int aw86927_detect(struct aw86927_data *haptics)
chip_id = be16_to_cpu(read_buf);
- if (chip_id != AW86927_CHIPID) {
- dev_err(haptics->dev, "Unexpected CHIPID value 0x%x\n", chip_id);
- return -ENODEV;
+ switch (haptics->model) {
+ case AW86927:
+ if (chip_id != AW86927_CHIPID) {
+ dev_err(haptics->dev, "Unexpected CHIPID value 0x%x\n", chip_id);
+ return -ENODEV;
+ }
+ break;
+ case AW86938:
+ if (chip_id != AW86938_CHIPID) {
+ dev_err(haptics->dev, "Unexpected CHIPID value 0x%x\n", chip_id);
+ return -ENODEV;
+ }
+ break;
}
return 0;
@@ -736,6 +775,7 @@ static int aw86927_probe(struct i2c_client *client)
haptics->dev = &client->dev;
haptics->client = client;
+ haptics->model = (enum aw86927_model)device_get_match_data(&client->dev);
i2c_set_clientdata(client, haptics);
@@ -825,7 +865,8 @@ static int aw86927_probe(struct i2c_client *client)
}
static const struct of_device_id aw86927_of_id[] = {
- { .compatible = "awinic,aw86927" },
+ { .compatible = "awinic,aw86927", .data = (void *)AW86927 },
+ { .compatible = "awinic,aw86938", .data = (void *)AW86938 },
{ /* sentinel */ }
};
--
2.43.0
Powered by blists - more mailing lists