]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Input: aw86927 - add support for Awinic AW86938
authorGriffin Kroah-Hartman <griffin.kroah@fairphone.com>
Wed, 4 Mar 2026 01:40:41 +0000 (17:40 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 1 Apr 2026 16:08:33 +0000 (09:08 -0700)
Add support for the I2C-connected Awinic AW86938 LRA haptic controller.

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@fairphone.com>
Link: https://patch.msgid.link/20260302-aw86938-driver-v4-3-92c865df9cca@fairphone.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/misc/aw86927.c

index 454e1af23df05d041ef20f6a27fd895a30e10ccd..f53b8f004cb3691b3b0c3362f970d731e9f4ffc7 100644 (file)
 #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
 #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;
@@ -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,7 +746,14 @@ static int aw86927_detect(struct aw86927_data *haptics)
 
        chip_id = be16_to_cpu(read_buf);
 
-       if (chip_id != AW86927_CHIPID) {
+       switch (chip_id) {
+       case AW86927_CHIPID:
+               haptics->model = AW86927;
+               break;
+       case AW86938_CHIPID:
+               haptics->model = AW86938;
+               break;
+       default:
                dev_err(haptics->dev, "Unexpected CHIPID value 0x%x\n", chip_id);
                return -ENODEV;
        }