Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

input: pm8xxx-vibrator: refactor to support new SPMI vibrator

Currently, vibrator control register addresses are hard coded,
including the base address and offsets, it's not flexible to
support new SPMI vibrator module which is usually included in
different PMICs with different base address. Refactor it by using
the base address defined in devicetree.

Signed-off-by: Fenglin Wu <quic_fenglinw@quicinc.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20240416-pm8xxx-vibrator-new-design-v11-1-7b1c951e1515@quicinc.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Fenglin Wu and committed by
Dmitry Torokhov
6d84ec25 48c0687a

+25 -16
+25 -16
drivers/input/misc/pm8xxx-vibrator.c
··· 19 19 #define MAX_FF_SPEED 0xff 20 20 21 21 struct pm8xxx_regs { 22 - unsigned int enable_addr; 22 + unsigned int enable_offset; 23 23 unsigned int enable_mask; 24 24 25 - unsigned int drv_addr; 25 + unsigned int drv_offset; 26 26 unsigned int drv_mask; 27 27 unsigned int drv_shift; 28 28 unsigned int drv_en_manual_mask; 29 29 }; 30 30 31 31 static const struct pm8xxx_regs pm8058_regs = { 32 - .drv_addr = 0x4A, 33 - .drv_mask = 0xf8, 32 + .drv_offset = 0, 33 + .drv_mask = GENMASK(7, 3), 34 34 .drv_shift = 3, 35 35 .drv_en_manual_mask = 0xfc, 36 36 }; 37 37 38 38 static struct pm8xxx_regs pm8916_regs = { 39 - .enable_addr = 0xc046, 39 + .enable_offset = 0x46, 40 40 .enable_mask = BIT(7), 41 - .drv_addr = 0xc041, 42 - .drv_mask = 0x1F, 41 + .drv_offset = 0x41, 42 + .drv_mask = GENMASK(4, 0), 43 43 .drv_shift = 0, 44 44 .drv_en_manual_mask = 0, 45 45 }; ··· 50 50 * @work: work structure to set the vibration parameters 51 51 * @regmap: regmap for register read/write 52 52 * @regs: registers' info 53 + * @enable_addr: vibrator enable register 54 + * @drv_addr: vibrator drive strength register 53 55 * @speed: speed of vibration set from userland 54 56 * @active: state of vibrator 55 57 * @level: level of vibration to set in the chip ··· 62 60 struct work_struct work; 63 61 struct regmap *regmap; 64 62 const struct pm8xxx_regs *regs; 63 + unsigned int enable_addr; 64 + unsigned int drv_addr; 65 65 int speed; 66 66 int level; 67 67 bool active; ··· 86 82 else 87 83 val &= ~regs->drv_mask; 88 84 89 - rc = regmap_write(vib->regmap, regs->drv_addr, val); 85 + rc = regmap_write(vib->regmap, vib->drv_addr, val); 90 86 if (rc < 0) 91 87 return rc; 92 88 93 89 vib->reg_vib_drv = val; 94 90 95 91 if (regs->enable_mask) 96 - rc = regmap_update_bits(vib->regmap, regs->enable_addr, 97 - regs->enable_mask, on ? ~0 : 0); 92 + rc = regmap_update_bits(vib->regmap, vib->enable_addr, 93 + regs->enable_mask, on ? regs->enable_mask : 0); 98 94 99 95 return rc; 100 96 } ··· 106 102 static void pm8xxx_work_handler(struct work_struct *work) 107 103 { 108 104 struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work); 109 - const struct pm8xxx_regs *regs = vib->regs; 110 - int rc; 111 105 unsigned int val; 106 + int rc; 112 107 113 - rc = regmap_read(vib->regmap, regs->drv_addr, &val); 108 + rc = regmap_read(vib->regmap, vib->drv_addr, &val); 114 109 if (rc < 0) 115 110 return; 116 111 ··· 172 169 struct pm8xxx_vib *vib; 173 170 struct input_dev *input_dev; 174 171 int error; 175 - unsigned int val; 172 + unsigned int val, reg_base = 0; 176 173 const struct pm8xxx_regs *regs; 177 174 178 175 vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL); ··· 190 187 INIT_WORK(&vib->work, pm8xxx_work_handler); 191 188 vib->vib_input_dev = input_dev; 192 189 190 + error = fwnode_property_read_u32(pdev->dev.fwnode, "reg", &reg_base); 191 + if (error < 0) 192 + return dev_err_probe(&pdev->dev, error, "Failed to read reg address\n"); 193 + 193 194 regs = of_device_get_match_data(&pdev->dev); 195 + vib->enable_addr = reg_base + regs->enable_offset; 196 + vib->drv_addr = reg_base + regs->drv_offset; 194 197 195 198 /* operate in manual mode */ 196 - error = regmap_read(vib->regmap, regs->drv_addr, &val); 199 + error = regmap_read(vib->regmap, vib->drv_addr, &val); 197 200 if (error < 0) 198 201 return error; 199 202 200 203 val &= regs->drv_en_manual_mask; 201 - error = regmap_write(vib->regmap, regs->drv_addr, val); 204 + error = regmap_write(vib->regmap, vib->drv_addr, val); 202 205 if (error < 0) 203 206 return error; 204 207