1/* 2 * MAXIM MAX77693 Haptic device driver 3 * 4 * Copyright (C) 2015 Samsung Electronics 5 * Author: Jaewon Kim <jaewon02.kim@samsung.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13#include <linux/err.h> 14#include <linux/i2c.h> 15#include <linux/init.h> 16#include <linux/input.h> 17#include <linux/mfd/max77843-private.h> 18#include <linux/module.h> 19#include <linux/platform_device.h> 20#include <linux/pwm.h> 21#include <linux/regmap.h> 22#include <linux/regulator/consumer.h> 23#include <linux/slab.h> 24#include <linux/workqueue.h> 25 26#define MAX_MAGNITUDE_SHIFT 16 27 28enum max77843_haptic_motor_type { 29 MAX77843_HAPTIC_ERM = 0, 30 MAX77843_HAPTIC_LRA, 31}; 32 33enum max77843_haptic_pwm_divisor { 34 MAX77843_HAPTIC_PWM_DIVISOR_32 = 0, 35 MAX77843_HAPTIC_PWM_DIVISOR_64, 36 MAX77843_HAPTIC_PWM_DIVISOR_128, 37 MAX77843_HAPTIC_PWM_DIVISOR_256, 38}; 39 40struct max77843_haptic { 41 struct regmap *regmap_haptic; 42 struct device *dev; 43 struct input_dev *input_dev; 44 struct pwm_device *pwm_dev; 45 struct regulator *motor_reg; 46 struct work_struct work; 47 struct mutex mutex; 48 49 unsigned int magnitude; 50 unsigned int pwm_duty; 51 52 bool active; 53 bool suspended; 54 55 enum max77843_haptic_motor_type type; 56 enum max77843_haptic_pwm_divisor pwm_divisor; 57}; 58 59static int max77843_haptic_set_duty_cycle(struct max77843_haptic *haptic) 60{ 61 int delta = (haptic->pwm_dev->period + haptic->pwm_duty) / 2; 62 int error; 63 64 error = pwm_config(haptic->pwm_dev, delta, haptic->pwm_dev->period); 65 if (error) { 66 dev_err(haptic->dev, "failed to configure pwm: %d\n", error); 67 return error; 68 } 69 70 return 0; 71} 72 73static int max77843_haptic_bias(struct max77843_haptic *haptic, bool on) 74{ 75 int error; 76 77 error = regmap_update_bits(haptic->regmap_haptic, 78 MAX77843_SYS_REG_MAINCTRL1, 79 MAX77843_MAINCTRL1_BIASEN_MASK, 80 on << MAINCTRL1_BIASEN_SHIFT); 81 if (error) { 82 dev_err(haptic->dev, "failed to %s bias: %d\n", 83 on ? "enable" : "disable", error); 84 return error; 85 } 86 87 return 0; 88} 89 90static int max77843_haptic_config(struct max77843_haptic *haptic, bool enable) 91{ 92 unsigned int value; 93 int error; 94 95 value = (haptic->type << MCONFIG_MODE_SHIFT) | 96 (enable << MCONFIG_MEN_SHIFT) | 97 (haptic->pwm_divisor << MCONFIG_PDIV_SHIFT); 98 99 error = regmap_write(haptic->regmap_haptic, 100 MAX77843_HAP_REG_MCONFIG, value); 101 if (error) { 102 dev_err(haptic->dev, 103 "failed to update haptic config: %d\n", error); 104 return error; 105 } 106 107 return 0; 108} 109 110static int max77843_haptic_enable(struct max77843_haptic *haptic) 111{ 112 int error; 113 114 if (haptic->active) 115 return 0; 116 117 error = pwm_enable(haptic->pwm_dev); 118 if (error) { 119 dev_err(haptic->dev, 120 "failed to enable pwm device: %d\n", error); 121 return error; 122 } 123 124 error = max77843_haptic_config(haptic, true); 125 if (error) 126 goto err_config; 127 128 haptic->active = true; 129 130 return 0; 131 132err_config: 133 pwm_disable(haptic->pwm_dev); 134 135 return error; 136} 137 138static int max77843_haptic_disable(struct max77843_haptic *haptic) 139{ 140 int error; 141 142 if (!haptic->active) 143 return 0; 144 145 error = max77843_haptic_config(haptic, false); 146 if (error) 147 return error; 148 149 pwm_disable(haptic->pwm_dev); 150 151 haptic->active = false; 152 153 return 0; 154} 155 156static void max77843_haptic_play_work(struct work_struct *work) 157{ 158 struct max77843_haptic *haptic = 159 container_of(work, struct max77843_haptic, work); 160 int error; 161 162 mutex_lock(&haptic->mutex); 163 164 if (haptic->suspended) 165 goto out_unlock; 166 167 if (haptic->magnitude) { 168 error = max77843_haptic_set_duty_cycle(haptic); 169 if (error) { 170 dev_err(haptic->dev, 171 "failed to set duty cycle: %d\n", error); 172 goto out_unlock; 173 } 174 175 error = max77843_haptic_enable(haptic); 176 if (error) 177 dev_err(haptic->dev, 178 "cannot enable haptic: %d\n", error); 179 } else { 180 error = max77843_haptic_disable(haptic); 181 if (error) 182 dev_err(haptic->dev, 183 "cannot disable haptic: %d\n", error); 184 } 185 186out_unlock: 187 mutex_unlock(&haptic->mutex); 188} 189 190static int max77843_haptic_play_effect(struct input_dev *dev, void *data, 191 struct ff_effect *effect) 192{ 193 struct max77843_haptic *haptic = input_get_drvdata(dev); 194 u64 period_mag_multi; 195 196 haptic->magnitude = effect->u.rumble.strong_magnitude; 197 if (!haptic->magnitude) 198 haptic->magnitude = effect->u.rumble.weak_magnitude; 199 200 period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude; 201 haptic->pwm_duty = (unsigned int)(period_mag_multi >> 202 MAX_MAGNITUDE_SHIFT); 203 204 schedule_work(&haptic->work); 205 206 return 0; 207} 208 209static int max77843_haptic_open(struct input_dev *dev) 210{ 211 struct max77843_haptic *haptic = input_get_drvdata(dev); 212 int error; 213 214 error = max77843_haptic_bias(haptic, true); 215 if (error) 216 return error; 217 218 error = regulator_enable(haptic->motor_reg); 219 if (error) { 220 dev_err(haptic->dev, 221 "failed to enable regulator: %d\n", error); 222 return error; 223 } 224 225 return 0; 226} 227 228static void max77843_haptic_close(struct input_dev *dev) 229{ 230 struct max77843_haptic *haptic = input_get_drvdata(dev); 231 int error; 232 233 cancel_work_sync(&haptic->work); 234 max77843_haptic_disable(haptic); 235 236 error = regulator_disable(haptic->motor_reg); 237 if (error) 238 dev_err(haptic->dev, 239 "failed to disable regulator: %d\n", error); 240 241 max77843_haptic_bias(haptic, false); 242} 243 244static int max77843_haptic_probe(struct platform_device *pdev) 245{ 246 struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent); 247 struct max77843_haptic *haptic; 248 int error; 249 250 haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL); 251 if (!haptic) 252 return -ENOMEM; 253 254 haptic->regmap_haptic = max77843->regmap; 255 haptic->dev = &pdev->dev; 256 haptic->type = MAX77843_HAPTIC_LRA; 257 haptic->pwm_divisor = MAX77843_HAPTIC_PWM_DIVISOR_128; 258 259 INIT_WORK(&haptic->work, max77843_haptic_play_work); 260 mutex_init(&haptic->mutex); 261 262 haptic->pwm_dev = devm_pwm_get(&pdev->dev, NULL); 263 if (IS_ERR(haptic->pwm_dev)) { 264 dev_err(&pdev->dev, "failed to get pwm device\n"); 265 return PTR_ERR(haptic->pwm_dev); 266 } 267 268 haptic->motor_reg = devm_regulator_get_exclusive(&pdev->dev, "haptic"); 269 if (IS_ERR(haptic->motor_reg)) { 270 dev_err(&pdev->dev, "failed to get regulator\n"); 271 return PTR_ERR(haptic->motor_reg); 272 } 273 274 haptic->input_dev = devm_input_allocate_device(&pdev->dev); 275 if (!haptic->input_dev) { 276 dev_err(&pdev->dev, "failed to allocate input device\n"); 277 return -ENOMEM; 278 } 279 280 haptic->input_dev->name = "max77843-haptic"; 281 haptic->input_dev->id.version = 1; 282 haptic->input_dev->dev.parent = &pdev->dev; 283 haptic->input_dev->open = max77843_haptic_open; 284 haptic->input_dev->close = max77843_haptic_close; 285 input_set_drvdata(haptic->input_dev, haptic); 286 input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE); 287 288 error = input_ff_create_memless(haptic->input_dev, NULL, 289 max77843_haptic_play_effect); 290 if (error) { 291 dev_err(&pdev->dev, "failed to create force-feedback\n"); 292 return error; 293 } 294 295 error = input_register_device(haptic->input_dev); 296 if (error) { 297 dev_err(&pdev->dev, "failed to register input device\n"); 298 return error; 299 } 300 301 platform_set_drvdata(pdev, haptic); 302 303 return 0; 304} 305 306static int __maybe_unused max77843_haptic_suspend(struct device *dev) 307{ 308 struct platform_device *pdev = to_platform_device(dev); 309 struct max77843_haptic *haptic = platform_get_drvdata(pdev); 310 int error; 311 312 error = mutex_lock_interruptible(&haptic->mutex); 313 if (error) 314 return error; 315 316 max77843_haptic_disable(haptic); 317 318 haptic->suspended = true; 319 320 mutex_unlock(&haptic->mutex); 321 322 return 0; 323} 324 325static int __maybe_unused max77843_haptic_resume(struct device *dev) 326{ 327 struct platform_device *pdev = to_platform_device(dev); 328 struct max77843_haptic *haptic = platform_get_drvdata(pdev); 329 unsigned int magnitude; 330 331 mutex_lock(&haptic->mutex); 332 333 haptic->suspended = false; 334 335 magnitude = ACCESS_ONCE(haptic->magnitude); 336 if (magnitude) 337 max77843_haptic_enable(haptic); 338 339 mutex_unlock(&haptic->mutex); 340 341 return 0; 342} 343 344static SIMPLE_DEV_PM_OPS(max77843_haptic_pm_ops, 345 max77843_haptic_suspend, max77843_haptic_resume); 346 347static struct platform_driver max77843_haptic_driver = { 348 .driver = { 349 .name = "max77843-haptic", 350 .pm = &max77843_haptic_pm_ops, 351 }, 352 .probe = max77843_haptic_probe, 353}; 354module_platform_driver(max77843_haptic_driver); 355 356MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>"); 357MODULE_DESCRIPTION("MAXIM MAX77843 Haptic driver"); 358MODULE_LICENSE("GPL"); 359