1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * MAX8997-haptic controller driver 4 * 5 * Copyright (C) 2012 Samsung Electronics 6 * Donggeun Kim <dg77.kim@samsung.com> 7 * 8 * This program is not provided / owned by Maxim Integrated Products. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/slab.h> 13 #include <linux/platform_device.h> 14 #include <linux/err.h> 15 #include <linux/pwm.h> 16 #include <linux/input.h> 17 #include <linux/mfd/max8997-private.h> 18 #include <linux/mfd/max8997.h> 19 #include <linux/regulator/consumer.h> 20 21 /* Haptic configuration 2 register */ 22 #define MAX8997_MOTOR_TYPE_SHIFT 7 23 #define MAX8997_ENABLE_SHIFT 6 24 #define MAX8997_MODE_SHIFT 5 25 26 /* Haptic driver configuration register */ 27 #define MAX8997_CYCLE_SHIFT 6 28 #define MAX8997_SIG_PERIOD_SHIFT 4 29 #define MAX8997_SIG_DUTY_SHIFT 2 30 #define MAX8997_PWM_DUTY_SHIFT 0 31 32 struct max8997_haptic { 33 struct device *dev; 34 struct i2c_client *client; 35 struct input_dev *input_dev; 36 struct regulator *regulator; 37 38 struct work_struct work; 39 struct mutex mutex; 40 41 bool enabled; 42 unsigned int level; 43 44 struct pwm_device *pwm; 45 unsigned int pwm_period; 46 enum max8997_haptic_pwm_divisor pwm_divisor; 47 48 enum max8997_haptic_motor_type type; 49 enum max8997_haptic_pulse_mode mode; 50 51 unsigned int internal_mode_pattern; 52 unsigned int pattern_cycle; 53 unsigned int pattern_signal_period; 54 }; 55 56 static int max8997_haptic_set_duty_cycle(struct max8997_haptic *chip) 57 { 58 int ret = 0; 59 60 if (chip->mode == MAX8997_EXTERNAL_MODE) { 61 unsigned int duty = chip->pwm_period * chip->level / 100; 62 ret = pwm_config(chip->pwm, duty, chip->pwm_period); 63 } else { 64 u8 duty_index = 0; 65 66 duty_index = DIV_ROUND_UP(chip->level * 64, 100); 67 68 switch (chip->internal_mode_pattern) { 69 case 0: 70 max8997_write_reg(chip->client, 71 MAX8997_HAPTIC_REG_SIGPWMDC1, duty_index); 72 break; 73 case 1: 74 max8997_write_reg(chip->client, 75 MAX8997_HAPTIC_REG_SIGPWMDC2, duty_index); 76 break; 77 case 2: 78 max8997_write_reg(chip->client, 79 MAX8997_HAPTIC_REG_SIGPWMDC3, duty_index); 80 break; 81 case 3: 82 max8997_write_reg(chip->client, 83 MAX8997_HAPTIC_REG_SIGPWMDC4, duty_index); 84 break; 85 default: 86 break; 87 } 88 } 89 return ret; 90 } 91 92 static void max8997_haptic_configure(struct max8997_haptic *chip) 93 { 94 u8 value; 95 96 value = chip->type << MAX8997_MOTOR_TYPE_SHIFT | 97 chip->enabled << MAX8997_ENABLE_SHIFT | 98 chip->mode << MAX8997_MODE_SHIFT | chip->pwm_divisor; 99 max8997_write_reg(chip->client, MAX8997_HAPTIC_REG_CONF2, value); 100 101 if (chip->mode == MAX8997_INTERNAL_MODE && chip->enabled) { 102 value = chip->internal_mode_pattern << MAX8997_CYCLE_SHIFT | 103 chip->internal_mode_pattern << MAX8997_SIG_PERIOD_SHIFT | 104 chip->internal_mode_pattern << MAX8997_SIG_DUTY_SHIFT | 105 chip->internal_mode_pattern << MAX8997_PWM_DUTY_SHIFT; 106 max8997_write_reg(chip->client, 107 MAX8997_HAPTIC_REG_DRVCONF, value); 108 109 switch (chip->internal_mode_pattern) { 110 case 0: 111 value = chip->pattern_cycle << 4; 112 max8997_write_reg(chip->client, 113 MAX8997_HAPTIC_REG_CYCLECONF1, value); 114 value = chip->pattern_signal_period; 115 max8997_write_reg(chip->client, 116 MAX8997_HAPTIC_REG_SIGCONF1, value); 117 break; 118 119 case 1: 120 value = chip->pattern_cycle; 121 max8997_write_reg(chip->client, 122 MAX8997_HAPTIC_REG_CYCLECONF1, value); 123 value = chip->pattern_signal_period; 124 max8997_write_reg(chip->client, 125 MAX8997_HAPTIC_REG_SIGCONF2, value); 126 break; 127 128 case 2: 129 value = chip->pattern_cycle << 4; 130 max8997_write_reg(chip->client, 131 MAX8997_HAPTIC_REG_CYCLECONF2, value); 132 value = chip->pattern_signal_period; 133 max8997_write_reg(chip->client, 134 MAX8997_HAPTIC_REG_SIGCONF3, value); 135 break; 136 137 case 3: 138 value = chip->pattern_cycle; 139 max8997_write_reg(chip->client, 140 MAX8997_HAPTIC_REG_CYCLECONF2, value); 141 value = chip->pattern_signal_period; 142 max8997_write_reg(chip->client, 143 MAX8997_HAPTIC_REG_SIGCONF4, value); 144 break; 145 146 default: 147 break; 148 } 149 } 150 } 151 152 static void max8997_haptic_enable(struct max8997_haptic *chip) 153 { 154 int error; 155 156 mutex_lock(&chip->mutex); 157 158 error = max8997_haptic_set_duty_cycle(chip); 159 if (error) { 160 dev_err(chip->dev, "set_pwm_cycle failed, error: %d\n", error); 161 goto out; 162 } 163 164 if (!chip->enabled) { 165 error = regulator_enable(chip->regulator); 166 if (error) { 167 dev_err(chip->dev, "Failed to enable regulator\n"); 168 goto out; 169 } 170 max8997_haptic_configure(chip); 171 if (chip->mode == MAX8997_EXTERNAL_MODE) { 172 error = pwm_enable(chip->pwm); 173 if (error) { 174 dev_err(chip->dev, "Failed to enable PWM\n"); 175 regulator_disable(chip->regulator); 176 goto out; 177 } 178 } 179 chip->enabled = true; 180 } 181 182 out: 183 mutex_unlock(&chip->mutex); 184 } 185 186 static void max8997_haptic_disable(struct max8997_haptic *chip) 187 { 188 mutex_lock(&chip->mutex); 189 190 if (chip->enabled) { 191 chip->enabled = false; 192 max8997_haptic_configure(chip); 193 if (chip->mode == MAX8997_EXTERNAL_MODE) 194 pwm_disable(chip->pwm); 195 regulator_disable(chip->regulator); 196 } 197 198 mutex_unlock(&chip->mutex); 199 } 200 201 static void max8997_haptic_play_effect_work(struct work_struct *work) 202 { 203 struct max8997_haptic *chip = 204 container_of(work, struct max8997_haptic, work); 205 206 if (chip->level) 207 max8997_haptic_enable(chip); 208 else 209 max8997_haptic_disable(chip); 210 } 211 212 static int max8997_haptic_play_effect(struct input_dev *dev, void *data, 213 struct ff_effect *effect) 214 { 215 struct max8997_haptic *chip = input_get_drvdata(dev); 216 217 chip->level = effect->u.rumble.strong_magnitude; 218 if (!chip->level) 219 chip->level = effect->u.rumble.weak_magnitude; 220 221 schedule_work(&chip->work); 222 223 return 0; 224 } 225 226 static void max8997_haptic_close(struct input_dev *dev) 227 { 228 struct max8997_haptic *chip = input_get_drvdata(dev); 229 230 cancel_work_sync(&chip->work); 231 max8997_haptic_disable(chip); 232 } 233 234 static int max8997_haptic_probe(struct platform_device *pdev) 235 { 236 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); 237 const struct max8997_platform_data *pdata = 238 dev_get_platdata(iodev->dev); 239 const struct max8997_haptic_platform_data *haptic_pdata = NULL; 240 struct max8997_haptic *chip; 241 struct input_dev *input_dev; 242 int error; 243 244 if (pdata) 245 haptic_pdata = pdata->haptic_pdata; 246 247 if (!haptic_pdata) { 248 dev_err(&pdev->dev, "no haptic platform data\n"); 249 return -EINVAL; 250 } 251 252 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 253 input_dev = input_allocate_device(); 254 if (!chip || !input_dev) { 255 dev_err(&pdev->dev, "unable to allocate memory\n"); 256 error = -ENOMEM; 257 goto err_free_mem; 258 } 259 260 INIT_WORK(&chip->work, max8997_haptic_play_effect_work); 261 mutex_init(&chip->mutex); 262 263 chip->client = iodev->haptic; 264 chip->dev = &pdev->dev; 265 chip->input_dev = input_dev; 266 chip->pwm_period = haptic_pdata->pwm_period; 267 chip->type = haptic_pdata->type; 268 chip->mode = haptic_pdata->mode; 269 chip->pwm_divisor = haptic_pdata->pwm_divisor; 270 271 switch (chip->mode) { 272 case MAX8997_INTERNAL_MODE: 273 chip->internal_mode_pattern = 274 haptic_pdata->internal_mode_pattern; 275 chip->pattern_cycle = haptic_pdata->pattern_cycle; 276 chip->pattern_signal_period = 277 haptic_pdata->pattern_signal_period; 278 break; 279 280 case MAX8997_EXTERNAL_MODE: 281 chip->pwm = pwm_get(&pdev->dev, NULL); 282 if (IS_ERR(chip->pwm)) { 283 error = PTR_ERR(chip->pwm); 284 dev_err(&pdev->dev, 285 "unable to request PWM for haptic, error: %d\n", 286 error); 287 goto err_free_mem; 288 } 289 290 /* 291 * FIXME: pwm_apply_args() should be removed when switching to 292 * the atomic PWM API. 293 */ 294 pwm_apply_args(chip->pwm); 295 break; 296 297 default: 298 dev_err(&pdev->dev, 299 "Invalid chip mode specified (%d)\n", chip->mode); 300 error = -EINVAL; 301 goto err_free_mem; 302 } 303 304 chip->regulator = regulator_get(&pdev->dev, "inmotor"); 305 if (IS_ERR(chip->regulator)) { 306 error = PTR_ERR(chip->regulator); 307 dev_err(&pdev->dev, 308 "unable to get regulator, error: %d\n", 309 error); 310 goto err_free_pwm; 311 } 312 313 input_dev->name = "max8997-haptic"; 314 input_dev->id.version = 1; 315 input_dev->dev.parent = &pdev->dev; 316 input_dev->close = max8997_haptic_close; 317 input_set_drvdata(input_dev, chip); 318 input_set_capability(input_dev, EV_FF, FF_RUMBLE); 319 320 error = input_ff_create_memless(input_dev, NULL, 321 max8997_haptic_play_effect); 322 if (error) { 323 dev_err(&pdev->dev, 324 "unable to create FF device, error: %d\n", 325 error); 326 goto err_put_regulator; 327 } 328 329 error = input_register_device(input_dev); 330 if (error) { 331 dev_err(&pdev->dev, 332 "unable to register input device, error: %d\n", 333 error); 334 goto err_destroy_ff; 335 } 336 337 platform_set_drvdata(pdev, chip); 338 return 0; 339 340 err_destroy_ff: 341 input_ff_destroy(input_dev); 342 err_put_regulator: 343 regulator_put(chip->regulator); 344 err_free_pwm: 345 if (chip->mode == MAX8997_EXTERNAL_MODE) 346 pwm_put(chip->pwm); 347 err_free_mem: 348 input_free_device(input_dev); 349 kfree(chip); 350 351 return error; 352 } 353 354 static void max8997_haptic_remove(struct platform_device *pdev) 355 { 356 struct max8997_haptic *chip = platform_get_drvdata(pdev); 357 358 input_unregister_device(chip->input_dev); 359 regulator_put(chip->regulator); 360 361 if (chip->mode == MAX8997_EXTERNAL_MODE) 362 pwm_put(chip->pwm); 363 364 kfree(chip); 365 } 366 367 static int max8997_haptic_suspend(struct device *dev) 368 { 369 struct platform_device *pdev = to_platform_device(dev); 370 struct max8997_haptic *chip = platform_get_drvdata(pdev); 371 372 max8997_haptic_disable(chip); 373 374 return 0; 375 } 376 377 static DEFINE_SIMPLE_DEV_PM_OPS(max8997_haptic_pm_ops, 378 max8997_haptic_suspend, NULL); 379 380 static const struct platform_device_id max8997_haptic_id[] = { 381 { "max8997-haptic", 0 }, 382 { }, 383 }; 384 MODULE_DEVICE_TABLE(platform, max8997_haptic_id); 385 386 static struct platform_driver max8997_haptic_driver = { 387 .driver = { 388 .name = "max8997-haptic", 389 .pm = pm_sleep_ptr(&max8997_haptic_pm_ops), 390 }, 391 .probe = max8997_haptic_probe, 392 .remove_new = max8997_haptic_remove, 393 .id_table = max8997_haptic_id, 394 }; 395 module_platform_driver(max8997_haptic_driver); 396 397 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); 398 MODULE_DESCRIPTION("max8997_haptic driver"); 399 MODULE_LICENSE("GPL"); 400