Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

HID: haptic: initialize haptic device

Add hid_haptic_init(). Parse autotrigger report to retrieve ordinals for
press and release waveforms.
Implement force feedback functions.

Signed-off-by: Angela Czubak <aczubak@google.com>
Co-developed-by: Jonathan Denose <jdenose@google.com>
Signed-off-by: Jonathan Denose <jdenose@google.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>

authored by

Angela Czubak and committed by
Benjamin Tissoires
344ff358 7a56e7b2

+443
+438
drivers/hid/hid-haptic.c
··· 5 5 * Copyright (c) 2021 Angela Czubak <acz@semihalf.com> 6 6 */ 7 7 8 + #include <linux/module.h> 9 + 8 10 #include "hid-haptic.h" 9 11 10 12 void hid_haptic_feature_mapping(struct hid_device *hdev, 11 13 struct hid_haptic_device *haptic, 12 14 struct hid_field *field, struct hid_usage *usage) 13 15 { 16 + u16 usage_hid; 17 + 14 18 if (usage->hid == HID_HP_AUTOTRIGGER) { 15 19 if (usage->usage_index >= field->report_count) { 16 20 dev_err(&hdev->dev, ··· 29 25 haptic->default_auto_trigger = 30 26 field->value[usage->usage_index]; 31 27 haptic->auto_trigger_report = field->report; 28 + } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ORDINAL) { 29 + usage_hid = usage->hid & HID_USAGE; 30 + switch (field->logical) { 31 + case HID_HP_WAVEFORMLIST: 32 + if (usage_hid > haptic->max_waveform_id) 33 + haptic->max_waveform_id = usage_hid; 34 + break; 35 + case HID_HP_DURATIONLIST: 36 + if (usage_hid > haptic->max_duration_id) 37 + haptic->max_duration_id = usage_hid; 38 + break; 39 + default: 40 + break; 41 + } 32 42 } 33 43 } 34 44 EXPORT_SYMBOL_GPL(hid_haptic_feature_mapping); ··· 88 70 return -1; 89 71 } 90 72 EXPORT_SYMBOL_GPL(hid_haptic_input_configured); 73 + 74 + static void parse_auto_trigger_field(struct hid_haptic_device *haptic, 75 + struct hid_field *field) 76 + { 77 + int count = field->report_count; 78 + int n; 79 + u16 usage_hid; 80 + 81 + for (n = 0; n < count; n++) { 82 + switch (field->usage[n].hid & HID_USAGE_PAGE) { 83 + case HID_UP_ORDINAL: 84 + usage_hid = field->usage[n].hid & HID_USAGE; 85 + switch (field->logical) { 86 + case HID_HP_WAVEFORMLIST: 87 + haptic->hid_usage_map[usage_hid] = field->value[n]; 88 + if (field->value[n] == 89 + (HID_HP_WAVEFORMPRESS & HID_USAGE)) { 90 + haptic->press_ordinal = usage_hid; 91 + } else if (field->value[n] == 92 + (HID_HP_WAVEFORMRELEASE & HID_USAGE)) { 93 + haptic->release_ordinal = usage_hid; 94 + } 95 + break; 96 + case HID_HP_DURATIONLIST: 97 + haptic->duration_map[usage_hid] = 98 + field->value[n]; 99 + break; 100 + default: 101 + break; 102 + } 103 + break; 104 + case HID_UP_HAPTIC: 105 + switch (field->usage[n].hid) { 106 + case HID_HP_WAVEFORMVENDORID: 107 + haptic->vendor_id = field->value[n]; 108 + break; 109 + case HID_HP_WAVEFORMVENDORPAGE: 110 + haptic->vendor_page = field->value[n]; 111 + break; 112 + default: 113 + break; 114 + } 115 + break; 116 + default: 117 + /* Should not really happen */ 118 + break; 119 + } 120 + } 121 + } 122 + 123 + static void fill_effect_buf(struct hid_haptic_device *haptic, 124 + struct ff_haptic_effect *effect, 125 + struct hid_haptic_effect *haptic_effect, 126 + int waveform_ordinal) 127 + { 128 + struct hid_report *rep = haptic->manual_trigger_report; 129 + struct hid_usage *usage; 130 + struct hid_field *field; 131 + s32 value; 132 + int i, j; 133 + u8 *buf = haptic_effect->report_buf; 134 + 135 + mutex_lock(&haptic->manual_trigger_mutex); 136 + for (i = 0; i < rep->maxfield; i++) { 137 + field = rep->field[i]; 138 + /* Ignore if report count is out of bounds. */ 139 + if (field->report_count < 1) 140 + continue; 141 + 142 + for (j = 0; j < field->maxusage; j++) { 143 + usage = &field->usage[j]; 144 + 145 + switch (usage->hid) { 146 + case HID_HP_INTENSITY: 147 + if (effect->intensity > 100) { 148 + value = field->logical_maximum; 149 + } else { 150 + value = field->logical_minimum + 151 + effect->intensity * 152 + (field->logical_maximum - 153 + field->logical_minimum) / 100; 154 + } 155 + break; 156 + case HID_HP_REPEATCOUNT: 157 + value = effect->repeat_count; 158 + break; 159 + case HID_HP_RETRIGGERPERIOD: 160 + value = effect->retrigger_period; 161 + break; 162 + case HID_HP_MANUALTRIGGER: 163 + value = waveform_ordinal; 164 + break; 165 + default: 166 + break; 167 + } 168 + 169 + field->value[j] = value; 170 + } 171 + } 172 + 173 + hid_output_report(rep, buf); 174 + mutex_unlock(&haptic->manual_trigger_mutex); 175 + } 176 + 177 + static int hid_haptic_upload_effect(struct input_dev *dev, struct ff_effect *effect, 178 + struct ff_effect *old) 179 + { 180 + struct ff_device *ff = dev->ff; 181 + struct hid_haptic_device *haptic = ff->private; 182 + int i, ordinal = 0; 183 + 184 + /* If vendor range, check vendor id and page */ 185 + if (effect->u.haptic.hid_usage >= (HID_HP_VENDORWAVEFORMMIN & HID_USAGE) && 186 + effect->u.haptic.hid_usage <= (HID_HP_VENDORWAVEFORMMAX & HID_USAGE) && 187 + (effect->u.haptic.vendor_id != haptic->vendor_id || 188 + effect->u.haptic.vendor_waveform_page != haptic->vendor_page)) 189 + return -EINVAL; 190 + 191 + /* Check hid_usage */ 192 + for (i = 1; i <= haptic->max_waveform_id; i++) { 193 + if (haptic->hid_usage_map[i] == effect->u.haptic.hid_usage) { 194 + ordinal = i; 195 + break; 196 + } 197 + } 198 + if (ordinal < 1) 199 + return -EINVAL; 200 + 201 + /* Fill the buffer for the effect id */ 202 + fill_effect_buf(haptic, &effect->u.haptic, &haptic->effect[effect->id], 203 + ordinal); 204 + 205 + return 0; 206 + } 207 + 208 + static int play_effect(struct hid_device *hdev, struct hid_haptic_device *haptic, 209 + struct hid_haptic_effect *effect) 210 + { 211 + int ret; 212 + 213 + ret = hid_hw_output_report(hdev, effect->report_buf, 214 + haptic->manual_trigger_report_len); 215 + if (ret < 0) { 216 + ret = hid_hw_raw_request(hdev, 217 + haptic->manual_trigger_report->id, 218 + effect->report_buf, 219 + haptic->manual_trigger_report_len, 220 + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 221 + } 222 + 223 + return ret; 224 + } 225 + 226 + static void haptic_work_handler(struct work_struct *work) 227 + { 228 + 229 + struct hid_haptic_effect *effect = container_of(work, 230 + struct hid_haptic_effect, 231 + work); 232 + struct input_dev *dev = effect->input_dev; 233 + struct hid_device *hdev = input_get_drvdata(dev); 234 + struct hid_haptic_device *haptic = dev->ff->private; 235 + 236 + mutex_lock(&haptic->manual_trigger_mutex); 237 + if (effect != &haptic->stop_effect) 238 + play_effect(hdev, haptic, &haptic->stop_effect); 239 + 240 + play_effect(hdev, haptic, effect); 241 + mutex_unlock(&haptic->manual_trigger_mutex); 242 + 243 + } 244 + 245 + static int hid_haptic_playback(struct input_dev *dev, int effect_id, int value) 246 + { 247 + struct hid_haptic_device *haptic = dev->ff->private; 248 + 249 + if (value) 250 + queue_work(haptic->wq, &haptic->effect[effect_id].work); 251 + else 252 + queue_work(haptic->wq, &haptic->stop_effect.work); 253 + 254 + return 0; 255 + } 256 + 257 + static void effect_set_default(struct ff_effect *effect) 258 + { 259 + effect->type = FF_HAPTIC; 260 + effect->id = -1; 261 + effect->u.haptic.hid_usage = HID_HP_WAVEFORMNONE & HID_USAGE; 262 + effect->u.haptic.intensity = 100; 263 + effect->u.haptic.retrigger_period = 0; 264 + effect->u.haptic.repeat_count = 0; 265 + } 266 + 267 + static int hid_haptic_erase(struct input_dev *dev, int effect_id) 268 + { 269 + struct hid_haptic_device *haptic = dev->ff->private; 270 + struct ff_effect effect; 271 + int ordinal; 272 + 273 + effect_set_default(&effect); 274 + 275 + if (effect.u.haptic.hid_usage == (HID_HP_WAVEFORMRELEASE & HID_USAGE)) { 276 + ordinal = haptic->release_ordinal; 277 + if (!ordinal) 278 + ordinal = HID_HAPTIC_ORDINAL_WAVEFORMNONE; 279 + else 280 + effect.u.haptic.hid_usage = HID_HP_WAVEFORMRELEASE & 281 + HID_USAGE; 282 + fill_effect_buf(haptic, &effect.u.haptic, &haptic->effect[effect_id], 283 + ordinal); 284 + } else if (effect.u.haptic.hid_usage == (HID_HP_WAVEFORMPRESS & HID_USAGE)) { 285 + ordinal = haptic->press_ordinal; 286 + if (!ordinal) 287 + ordinal = HID_HAPTIC_ORDINAL_WAVEFORMNONE; 288 + else 289 + effect.u.haptic.hid_usage = HID_HP_WAVEFORMPRESS & 290 + HID_USAGE; 291 + fill_effect_buf(haptic, &effect.u.haptic, &haptic->effect[effect_id], 292 + ordinal); 293 + } 294 + 295 + return 0; 296 + } 297 + 298 + static void hid_haptic_destroy(struct ff_device *ff) 299 + { 300 + struct hid_haptic_device *haptic = ff->private; 301 + struct hid_device *hdev = haptic->hdev; 302 + int r; 303 + 304 + if (hdev) 305 + put_device(&hdev->dev); 306 + 307 + kfree(haptic->stop_effect.report_buf); 308 + haptic->stop_effect.report_buf = NULL; 309 + 310 + if (haptic->effect) { 311 + for (r = 0; r < ff->max_effects; r++) 312 + kfree(haptic->effect[r].report_buf); 313 + kfree(haptic->effect); 314 + } 315 + haptic->effect = NULL; 316 + 317 + destroy_workqueue(haptic->wq); 318 + haptic->wq = NULL; 319 + 320 + kfree(haptic->duration_map); 321 + haptic->duration_map = NULL; 322 + 323 + kfree(haptic->hid_usage_map); 324 + haptic->hid_usage_map = NULL; 325 + 326 + module_put(THIS_MODULE); 327 + } 328 + 329 + int hid_haptic_init(struct hid_device *hdev, 330 + struct hid_haptic_device **haptic_ptr) 331 + { 332 + struct hid_haptic_device *haptic = *haptic_ptr; 333 + struct input_dev *dev = NULL; 334 + struct hid_input *hidinput; 335 + struct ff_device *ff; 336 + int ret = 0, r; 337 + struct ff_haptic_effect stop_effect = { 338 + .hid_usage = HID_HP_WAVEFORMSTOP & HID_USAGE, 339 + }; 340 + const char *prefix = "hid-haptic"; 341 + char *name; 342 + int (*flush)(struct input_dev *dev, struct file *file); 343 + int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 344 + 345 + haptic->hdev = hdev; 346 + haptic->max_waveform_id = max(2u, haptic->max_waveform_id); 347 + haptic->max_duration_id = max(2u, haptic->max_duration_id); 348 + 349 + haptic->hid_usage_map = kcalloc(haptic->max_waveform_id + 1, 350 + sizeof(u16), GFP_KERNEL); 351 + if (!haptic->hid_usage_map) { 352 + ret = -ENOMEM; 353 + goto exit; 354 + } 355 + haptic->duration_map = kcalloc(haptic->max_duration_id + 1, 356 + sizeof(u32), GFP_KERNEL); 357 + if (!haptic->duration_map) { 358 + ret = -ENOMEM; 359 + goto usage_map; 360 + } 361 + 362 + if (haptic->max_waveform_id != haptic->max_duration_id) 363 + dev_warn(&hdev->dev, 364 + "Haptic duration and waveform lists have different max id (%u and %u).\n", 365 + haptic->max_duration_id, haptic->max_waveform_id); 366 + 367 + haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMNONE] = 368 + HID_HP_WAVEFORMNONE & HID_USAGE; 369 + haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMSTOP] = 370 + HID_HP_WAVEFORMSTOP & HID_USAGE; 371 + 372 + for (r = 0; r < haptic->auto_trigger_report->maxfield; r++) 373 + parse_auto_trigger_field(haptic, haptic->auto_trigger_report->field[r]); 374 + 375 + list_for_each_entry(hidinput, &hdev->inputs, list) { 376 + if (hidinput->application == HID_DG_TOUCHPAD) { 377 + dev = hidinput->input; 378 + break; 379 + } 380 + } 381 + 382 + if (!dev) { 383 + dev_err(&hdev->dev, "Failed to find the input device\n"); 384 + ret = -ENODEV; 385 + goto duration_map; 386 + } 387 + 388 + haptic->input_dev = dev; 389 + haptic->manual_trigger_report_len = 390 + hid_report_len(haptic->manual_trigger_report); 391 + mutex_init(&haptic->manual_trigger_mutex); 392 + name = kmalloc(strlen(prefix) + strlen(hdev->name) + 2, GFP_KERNEL); 393 + if (name) { 394 + sprintf(name, "%s %s", prefix, hdev->name); 395 + haptic->wq = create_singlethread_workqueue(name); 396 + kfree(name); 397 + } 398 + if (!haptic->wq) { 399 + ret = -ENOMEM; 400 + goto duration_map; 401 + } 402 + haptic->effect = kcalloc(FF_MAX_EFFECTS, 403 + sizeof(struct hid_haptic_effect), GFP_KERNEL); 404 + if (!haptic->effect) { 405 + ret = -ENOMEM; 406 + goto output_queue; 407 + } 408 + for (r = 0; r < FF_MAX_EFFECTS; r++) { 409 + haptic->effect[r].report_buf = 410 + hid_alloc_report_buf(haptic->manual_trigger_report, 411 + GFP_KERNEL); 412 + if (!haptic->effect[r].report_buf) { 413 + dev_err(&hdev->dev, 414 + "Failed to allocate a buffer for an effect.\n"); 415 + ret = -ENOMEM; 416 + goto buffer_free; 417 + } 418 + haptic->effect[r].input_dev = dev; 419 + INIT_WORK(&haptic->effect[r].work, haptic_work_handler); 420 + } 421 + haptic->stop_effect.report_buf = 422 + hid_alloc_report_buf(haptic->manual_trigger_report, 423 + GFP_KERNEL); 424 + if (!haptic->stop_effect.report_buf) { 425 + dev_err(&hdev->dev, 426 + "Failed to allocate a buffer for stop effect.\n"); 427 + ret = -ENOMEM; 428 + goto buffer_free; 429 + } 430 + haptic->stop_effect.input_dev = dev; 431 + INIT_WORK(&haptic->stop_effect.work, haptic_work_handler); 432 + fill_effect_buf(haptic, &stop_effect, &haptic->stop_effect, 433 + HID_HAPTIC_ORDINAL_WAVEFORMSTOP); 434 + 435 + input_set_capability(dev, EV_FF, FF_HAPTIC); 436 + 437 + flush = dev->flush; 438 + event = dev->event; 439 + ret = input_ff_create(dev, FF_MAX_EFFECTS); 440 + if (ret) { 441 + dev_err(&hdev->dev, "Failed to create ff device.\n"); 442 + goto stop_buffer_free; 443 + } 444 + 445 + ff = dev->ff; 446 + ff->private = haptic; 447 + ff->upload = hid_haptic_upload_effect; 448 + ff->playback = hid_haptic_playback; 449 + ff->erase = hid_haptic_erase; 450 + ff->destroy = hid_haptic_destroy; 451 + if (!try_module_get(THIS_MODULE)) { 452 + dev_err(&hdev->dev, "Failed to increase module count.\n"); 453 + goto input_free; 454 + } 455 + if (!get_device(&hdev->dev)) { 456 + dev_err(&hdev->dev, "Failed to get hdev device.\n"); 457 + module_put(THIS_MODULE); 458 + goto input_free; 459 + } 460 + return 0; 461 + 462 + input_free: 463 + input_ff_destroy(dev); 464 + /* Do not let double free happen, input_ff_destroy will call 465 + * hid_haptic_destroy. 466 + */ 467 + *haptic_ptr = NULL; 468 + /* Restore dev flush and event */ 469 + dev->flush = flush; 470 + dev->event = event; 471 + return ret; 472 + stop_buffer_free: 473 + kfree(haptic->stop_effect.report_buf); 474 + haptic->stop_effect.report_buf = NULL; 475 + buffer_free: 476 + while (--r >= 0) 477 + kfree(haptic->effect[r].report_buf); 478 + kfree(haptic->effect); 479 + haptic->effect = NULL; 480 + output_queue: 481 + destroy_workqueue(haptic->wq); 482 + haptic->wq = NULL; 483 + duration_map: 484 + kfree(haptic->duration_map); 485 + haptic->duration_map = NULL; 486 + usage_map: 487 + kfree(haptic->hid_usage_map); 488 + haptic->hid_usage_map = NULL; 489 + exit: 490 + return ret; 491 + } 492 + EXPORT_SYMBOL_GPL(hid_haptic_init);
+5
drivers/hid/hid-haptic.h
··· 69 69 int hid_haptic_input_configured(struct hid_device *hdev, 70 70 struct hid_haptic_device *haptic, 71 71 struct hid_input *hi); 72 + int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr); 72 73 #else 73 74 static inline 74 75 void hid_haptic_feature_mapping(struct hid_device *hdev, ··· 96 95 int hid_haptic_input_configured(struct hid_device *hdev, 97 96 struct hid_haptic_device *haptic, 98 97 struct hid_input *hi) 98 + { 99 + return 0; 100 + } 101 + int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr) 99 102 { 100 103 return 0; 101 104 }