Lines Matching +full:pm8058 +full:- +full:vib
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
16 #define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
47 * struct pm8xxx_vib - structure to hold vibrator data
55 * @reg_vib_drv: regs->drv_addr register value
69 * pm8xxx_vib_set - handler to start/stop vibration
70 * @vib: pointer to vibrator structure
73 static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on) in pm8xxx_vib_set() argument
76 unsigned int val = vib->reg_vib_drv; in pm8xxx_vib_set()
77 const struct pm8xxx_regs *regs = vib->regs; in pm8xxx_vib_set()
80 val |= (vib->level << regs->drv_shift) & regs->drv_mask; in pm8xxx_vib_set()
82 val &= ~regs->drv_mask; in pm8xxx_vib_set()
84 rc = regmap_write(vib->regmap, regs->drv_addr, val); in pm8xxx_vib_set()
88 vib->reg_vib_drv = val; in pm8xxx_vib_set()
90 if (regs->enable_mask) in pm8xxx_vib_set()
91 rc = regmap_update_bits(vib->regmap, regs->enable_addr, in pm8xxx_vib_set()
92 regs->enable_mask, on ? ~0 : 0); in pm8xxx_vib_set()
98 * pm8xxx_work_handler - worker to set vibration level
103 struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work); in pm8xxx_work_handler() local
104 const struct pm8xxx_regs *regs = vib->regs; in pm8xxx_work_handler()
108 rc = regmap_read(vib->regmap, regs->drv_addr, &val); in pm8xxx_work_handler()
116 if (vib->speed) { in pm8xxx_work_handler()
117 vib->active = true; in pm8xxx_work_handler()
118 vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) + in pm8xxx_work_handler()
120 vib->level /= 100; in pm8xxx_work_handler()
122 vib->active = false; in pm8xxx_work_handler()
123 vib->level = VIB_MIN_LEVEL_mV / 100; in pm8xxx_work_handler()
126 pm8xxx_vib_set(vib, vib->active); in pm8xxx_work_handler()
130 * pm8xxx_vib_close - callback of input close callback
137 struct pm8xxx_vib *vib = input_get_drvdata(dev); in pm8xxx_vib_close() local
139 cancel_work_sync(&vib->work); in pm8xxx_vib_close()
140 if (vib->active) in pm8xxx_vib_close()
141 pm8xxx_vib_set(vib, false); in pm8xxx_vib_close()
145 * pm8xxx_vib_play_effect - function to handle vib effects.
155 struct pm8xxx_vib *vib = input_get_drvdata(dev); in pm8xxx_vib_play_effect() local
157 vib->speed = effect->u.rumble.strong_magnitude >> 8; in pm8xxx_vib_play_effect()
158 if (!vib->speed) in pm8xxx_vib_play_effect()
159 vib->speed = effect->u.rumble.weak_magnitude >> 9; in pm8xxx_vib_play_effect()
161 schedule_work(&vib->work); in pm8xxx_vib_play_effect()
168 struct pm8xxx_vib *vib; in pm8xxx_vib_probe() local
174 vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL); in pm8xxx_vib_probe()
175 if (!vib) in pm8xxx_vib_probe()
176 return -ENOMEM; in pm8xxx_vib_probe()
178 vib->regmap = dev_get_regmap(pdev->dev.parent, NULL); in pm8xxx_vib_probe()
179 if (!vib->regmap) in pm8xxx_vib_probe()
180 return -ENODEV; in pm8xxx_vib_probe()
182 input_dev = devm_input_allocate_device(&pdev->dev); in pm8xxx_vib_probe()
184 return -ENOMEM; in pm8xxx_vib_probe()
186 INIT_WORK(&vib->work, pm8xxx_work_handler); in pm8xxx_vib_probe()
187 vib->vib_input_dev = input_dev; in pm8xxx_vib_probe()
189 regs = of_device_get_match_data(&pdev->dev); in pm8xxx_vib_probe()
192 error = regmap_read(vib->regmap, regs->drv_addr, &val); in pm8xxx_vib_probe()
196 val &= regs->drv_en_manual_mask; in pm8xxx_vib_probe()
197 error = regmap_write(vib->regmap, regs->drv_addr, val); in pm8xxx_vib_probe()
201 vib->regs = regs; in pm8xxx_vib_probe()
202 vib->reg_vib_drv = val; in pm8xxx_vib_probe()
204 input_dev->name = "pm8xxx_vib_ffmemless"; in pm8xxx_vib_probe()
205 input_dev->id.version = 1; in pm8xxx_vib_probe()
206 input_dev->close = pm8xxx_vib_close; in pm8xxx_vib_probe()
207 input_set_drvdata(input_dev, vib); in pm8xxx_vib_probe()
208 input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE); in pm8xxx_vib_probe()
213 dev_err(&pdev->dev, in pm8xxx_vib_probe()
220 dev_err(&pdev->dev, "couldn't register input device\n"); in pm8xxx_vib_probe()
224 platform_set_drvdata(pdev, vib); in pm8xxx_vib_probe()
230 struct pm8xxx_vib *vib = dev_get_drvdata(dev); in pm8xxx_vib_suspend() local
233 pm8xxx_vib_set(vib, false); in pm8xxx_vib_suspend()
241 { .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
242 { .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
243 { .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
251 .name = "pm8xxx-vib",
259 MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");