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.
14 #define VIB_MAX_LEVEL_mV(vib) (vib->drv2_addr ? 3544 : 3100) argument
15 #define VIB_MIN_LEVEL_mV(vib) (vib->drv2_addr ? 1504 : 1200) argument
16 #define VIB_PER_STEP_mV(vib) (vib->drv2_addr ? 8 : 100) argument
17 #define VIB_MAX_LEVELS(vib) \ argument
18 (VIB_MAX_LEVEL_mV(vib) - VIB_MIN_LEVEL_mV(vib) + VIB_PER_STEP_mV(vib))
68 * struct pm8xxx_vib - structure to hold vibrator data
79 * @reg_vib_drv: regs->drv_addr register value
96 * pm8xxx_vib_set - handler to start/stop vibration
97 * @vib: pointer to vibrator structure
100 static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on) in pm8xxx_vib_set() argument
103 unsigned int val = vib->reg_vib_drv; in pm8xxx_vib_set()
104 const struct pm8xxx_regs *regs = vib->regs; in pm8xxx_vib_set()
106 if (regs->drv_in_step) in pm8xxx_vib_set()
107 vib->level /= VIB_PER_STEP_mV(vib); in pm8xxx_vib_set()
110 val |= (vib->level << regs->drv_shift) & regs->drv_mask; in pm8xxx_vib_set()
112 val &= ~regs->drv_mask; in pm8xxx_vib_set()
114 rc = regmap_write(vib->regmap, vib->drv_addr, val); in pm8xxx_vib_set()
118 vib->reg_vib_drv = val; in pm8xxx_vib_set()
120 if (regs->drv2_mask) { in pm8xxx_vib_set()
121 val = vib->level << regs->drv2_shift; in pm8xxx_vib_set()
122 rc = regmap_write_bits(vib->regmap, vib->drv2_addr, in pm8xxx_vib_set()
123 regs->drv2_mask, on ? val : 0); in pm8xxx_vib_set()
128 if (regs->enable_mask) in pm8xxx_vib_set()
129 rc = regmap_update_bits(vib->regmap, vib->enable_addr, in pm8xxx_vib_set()
130 regs->enable_mask, on ? regs->enable_mask : 0); in pm8xxx_vib_set()
136 * pm8xxx_work_handler - worker to set vibration level
141 struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work); in pm8xxx_work_handler() local
145 rc = regmap_read(vib->regmap, vib->drv_addr, &val); in pm8xxx_work_handler()
153 if (vib->speed) { in pm8xxx_work_handler()
154 vib->active = true; in pm8xxx_work_handler()
155 vib->level = VIB_MIN_LEVEL_mV(vib); in pm8xxx_work_handler()
156 vib->level += mult_frac(VIB_MAX_LEVELS(vib), vib->speed, MAX_FF_SPEED); in pm8xxx_work_handler()
158 vib->active = false; in pm8xxx_work_handler()
159 vib->level = VIB_MIN_LEVEL_mV(vib); in pm8xxx_work_handler()
162 pm8xxx_vib_set(vib, vib->active); in pm8xxx_work_handler()
166 * pm8xxx_vib_close - callback of input close callback
173 struct pm8xxx_vib *vib = input_get_drvdata(dev); in pm8xxx_vib_close() local
175 cancel_work_sync(&vib->work); in pm8xxx_vib_close()
176 if (vib->active) in pm8xxx_vib_close()
177 pm8xxx_vib_set(vib, false); in pm8xxx_vib_close()
181 * pm8xxx_vib_play_effect - function to handle vib effects.
191 struct pm8xxx_vib *vib = input_get_drvdata(dev); in pm8xxx_vib_play_effect() local
193 vib->speed = effect->u.rumble.strong_magnitude >> 8; in pm8xxx_vib_play_effect()
194 if (!vib->speed) in pm8xxx_vib_play_effect()
195 vib->speed = effect->u.rumble.weak_magnitude >> 9; in pm8xxx_vib_play_effect()
197 schedule_work(&vib->work); in pm8xxx_vib_play_effect()
204 struct pm8xxx_vib *vib; in pm8xxx_vib_probe() local
210 vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL); in pm8xxx_vib_probe()
211 if (!vib) in pm8xxx_vib_probe()
212 return -ENOMEM; in pm8xxx_vib_probe()
214 vib->regmap = dev_get_regmap(pdev->dev.parent, NULL); in pm8xxx_vib_probe()
215 if (!vib->regmap) in pm8xxx_vib_probe()
216 return -ENODEV; in pm8xxx_vib_probe()
218 input_dev = devm_input_allocate_device(&pdev->dev); in pm8xxx_vib_probe()
220 return -ENOMEM; in pm8xxx_vib_probe()
222 INIT_WORK(&vib->work, pm8xxx_work_handler); in pm8xxx_vib_probe()
223 vib->vib_input_dev = input_dev; in pm8xxx_vib_probe()
225 error = fwnode_property_read_u32(pdev->dev.fwnode, "reg", &reg_base); in pm8xxx_vib_probe()
227 return dev_err_probe(&pdev->dev, error, "Failed to read reg address\n"); in pm8xxx_vib_probe()
229 regs = of_device_get_match_data(&pdev->dev); in pm8xxx_vib_probe()
230 vib->enable_addr = reg_base + regs->enable_offset; in pm8xxx_vib_probe()
231 vib->drv_addr = reg_base + regs->drv_offset; in pm8xxx_vib_probe()
232 vib->drv2_addr = reg_base + regs->drv2_offset; in pm8xxx_vib_probe()
235 error = regmap_read(vib->regmap, vib->drv_addr, &val); in pm8xxx_vib_probe()
239 val &= regs->drv_en_manual_mask; in pm8xxx_vib_probe()
240 error = regmap_write(vib->regmap, vib->drv_addr, val); in pm8xxx_vib_probe()
244 vib->regs = regs; in pm8xxx_vib_probe()
245 vib->reg_vib_drv = val; in pm8xxx_vib_probe()
247 input_dev->name = "pm8xxx_vib_ffmemless"; in pm8xxx_vib_probe()
248 input_dev->id.version = 1; in pm8xxx_vib_probe()
249 input_dev->close = pm8xxx_vib_close; in pm8xxx_vib_probe()
250 input_set_drvdata(input_dev, vib); in pm8xxx_vib_probe()
251 input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE); in pm8xxx_vib_probe()
256 dev_err(&pdev->dev, in pm8xxx_vib_probe()
263 dev_err(&pdev->dev, "couldn't register input device\n"); in pm8xxx_vib_probe()
267 platform_set_drvdata(pdev, vib); in pm8xxx_vib_probe()
273 struct pm8xxx_vib *vib = dev_get_drvdata(dev); in pm8xxx_vib_suspend() local
276 pm8xxx_vib_set(vib, false); in pm8xxx_vib_suspend()
284 { .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
285 { .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
286 { .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
287 { .compatible = "qcom,pmi632-vib", .data = &pmi632_regs },
295 .name = "pm8xxx-vib",
303 MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");