On 18/06/2024 15:59, Dzmitry Sankouski wrote: > Add support for haptic controller on MAX77705 Multifunction > device. > > This driver supports external pwm and LRA (Linear Resonant Actuator) motor. > User can control the haptic device via force feedback framework. > > Signed-off-by: Dzmitry Sankouski <dsankouski@xxxxxxxxx> > --- > +static int max77705_haptic_bias(struct max77705_haptic *haptic, bool on) > +{ > + int error; > + > + error = regmap_update_bits(haptic->regmap_haptic, > + MAX77705_PMIC_REG_MAINCTRL1, > + MAX77705_MAINCTRL1_BIASEN_MASK, > + on << MAX77705_MAINCTRL1_BIASEN_SHIFT); > + > + if (error) { > + dev_err(haptic->dev, "failed to %s bias: %d\n", > + on ? "enable" : "disable", error); > + return error; > + } > + > + return 0; > +} > + > +static int max77705_haptic_configure(struct max77705_haptic *haptic, > + bool enable) > +{ > + unsigned int value, config_reg; > + int error; > + > + value = ((haptic->type << MAX77705_CONFIG2_MODE_SHIFT) | > + (enable << MAX77705_CONFIG2_MEN_SHIFT) | > + (haptic->mode << MAX77705_CONFIG2_HTYP_SHIFT) | > + MAX77705_HAPTIC_PWM_DIVISOR_128); > + config_reg = MAX77705_PMIC_REG_MCONFIG; > + > + error = regmap_write(haptic->regmap_haptic, > + config_reg, value); > + if (error) { > + dev_err(haptic->dev, > + "failed to update haptic config: %d\n", error); > + return error; > + } > + > + return 0; > +} > + > +static void max77705_haptic_enable(struct max77705_haptic *haptic) > +{ > + int error; > + > + if (haptic->enabled) > + return; > + > + error = pwm_enable(haptic->pwm_dev); > + if (error) { > + dev_err(haptic->dev, > + "failed to enable haptic pwm device: %d\n", error); > + return; > + } > + > + error = max77705_haptic_configure(haptic, true); > + if (error) > + goto err_enable_config; > + > + haptic->enabled = true; > + > + return; > + > +err_enable_config: > + pwm_disable(haptic->pwm_dev); > +} > + > +static void max77705_haptic_disable(struct max77705_haptic *haptic) > +{ > + int error; > + > + if (!haptic->enabled) > + return; > + > + error = max77705_haptic_configure(haptic, false); > + if (error) > + return; > + > + pwm_disable(haptic->pwm_dev); > + haptic->enabled = false; > +} > + > +static void max77705_haptic_play_work(struct work_struct *work) > +{ > + struct max77705_haptic *haptic = > + container_of(work, struct max77705_haptic, work); > + int error; > + > + error = max77705_haptic_set_duty_cycle(haptic); > + if (error) { > + dev_err(haptic->dev, "failed to set duty cycle: %d\n", error); > + return; > + } > + > + if (haptic->magnitude) > + max77705_haptic_enable(haptic); > + else > + max77705_haptic_disable(haptic); > +} > + > +static int max77705_haptic_play_effect(struct input_dev *dev, void *data, > + struct ff_effect *effect) > +{ > + struct max77705_haptic *haptic = input_get_drvdata(dev); > + struct pwm_args pargs; > + u64 period_mag_multi; > + > + haptic->magnitude = effect->u.rumble.strong_magnitude; > + if (!haptic->magnitude) > + haptic->magnitude = effect->u.rumble.weak_magnitude; > + > + /* > + * The magnitude comes from force-feedback interface. > + * The formula to convert magnitude to pwm_duty as follows: > + * - pwm_duty = (magnitude * pwm_period) / MAX_MAGNITUDE(0xFFFF) > + */ > + pr_info("magnitude: %d(%x)", haptic->magnitude, haptic->magnitude); Do not use pr_xxx in your drivers. That's a generic comment so please apply it everywhere. Anyway driver should be silent. > + pwm_get_args(haptic->pwm_dev, &pargs); > + period_mag_multi = (u64)pargs.period * haptic->magnitude; > + haptic->pwm_duty = (unsigned int)(period_mag_multi >> > + MAX_MAGNITUDE_SHIFT); > + > + schedule_work(&haptic->work); > + > + return 0; > +} > + > +static DEFINE_SIMPLE_DEV_PM_OPS(max77705_haptic_pm_ops, > + max77705_haptic_suspend, > + max77705_haptic_resume); > + > +static const struct of_device_id of_max77705_haptic_dt_match[] = { > + { .compatible = "maxim,max77705-haptic", }, > + { /* sentinel */ }, > +}; > +MODULE_DEVICE_TABLE(of, of_max77705_haptic_dt_match); > + > +static struct platform_driver max77705_haptic_driver = { > + .driver = { > + .name = "max77705-haptic", > + .pm = pm_sleep_ptr(&max77705_haptic_pm_ops), > + .of_match_table = of_max77705_haptic_dt_match, > + }, > + .probe = max77705_haptic_probe, > + .remove_new = max77705_haptic_remove, > +}; > +module_platform_driver(max77705_haptic_driver); > + > +MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@xxxxxxxxx>"); > +MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@xxxxxxxxxxx>"); > +MODULE_AUTHOR("Krzysztof Kozlowski <krzk@xxxxxxxxxx>"); I doubt that this driver is needed. Everything is copy of max777693. Best regards, Krzysztof