.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2011 Kionix, Inc. |
---|
3 | 4 | * Written by Chris Hudson <chudson@kionix.com> |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License version 2 as |
---|
7 | | - * published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License |
---|
15 | | - * along with this program; if not, write to the Free Software |
---|
16 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
---|
17 | | - * 02111-1307, USA |
---|
18 | 5 | */ |
---|
19 | 6 | |
---|
20 | 7 | #include <linux/delay.h> |
---|
.. | .. |
---|
24 | 11 | #include <linux/module.h> |
---|
25 | 12 | #include <linux/slab.h> |
---|
26 | 13 | #include <linux/input/kxtj9.h> |
---|
27 | | -#include <linux/input-polldev.h> |
---|
28 | 14 | |
---|
29 | 15 | #define NAME "kxtj9" |
---|
30 | 16 | #define G_MAX 8000 |
---|
.. | .. |
---|
84 | 70 | struct i2c_client *client; |
---|
85 | 71 | struct kxtj9_platform_data pdata; |
---|
86 | 72 | struct input_dev *input_dev; |
---|
87 | | -#ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE |
---|
88 | | - struct input_polled_dev *poll_dev; |
---|
89 | | -#endif |
---|
90 | 73 | unsigned int last_poll_interval; |
---|
91 | 74 | u8 shift; |
---|
92 | 75 | u8 ctrl_reg1; |
---|
.. | .. |
---|
295 | 278 | kxtj9_disable(tj9); |
---|
296 | 279 | } |
---|
297 | 280 | |
---|
298 | | -static void kxtj9_init_input_device(struct kxtj9_data *tj9, |
---|
299 | | - struct input_dev *input_dev) |
---|
300 | | -{ |
---|
301 | | - __set_bit(EV_ABS, input_dev->evbit); |
---|
302 | | - input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); |
---|
303 | | - input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); |
---|
304 | | - input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); |
---|
305 | | - |
---|
306 | | - input_dev->name = "kxtj9_accel"; |
---|
307 | | - input_dev->id.bustype = BUS_I2C; |
---|
308 | | - input_dev->dev.parent = &tj9->client->dev; |
---|
309 | | -} |
---|
310 | | - |
---|
311 | | -static int kxtj9_setup_input_device(struct kxtj9_data *tj9) |
---|
312 | | -{ |
---|
313 | | - struct input_dev *input_dev; |
---|
314 | | - int err; |
---|
315 | | - |
---|
316 | | - input_dev = input_allocate_device(); |
---|
317 | | - if (!input_dev) { |
---|
318 | | - dev_err(&tj9->client->dev, "input device allocate failed\n"); |
---|
319 | | - return -ENOMEM; |
---|
320 | | - } |
---|
321 | | - |
---|
322 | | - tj9->input_dev = input_dev; |
---|
323 | | - |
---|
324 | | - input_dev->open = kxtj9_input_open; |
---|
325 | | - input_dev->close = kxtj9_input_close; |
---|
326 | | - input_set_drvdata(input_dev, tj9); |
---|
327 | | - |
---|
328 | | - kxtj9_init_input_device(tj9, input_dev); |
---|
329 | | - |
---|
330 | | - err = input_register_device(tj9->input_dev); |
---|
331 | | - if (err) { |
---|
332 | | - dev_err(&tj9->client->dev, |
---|
333 | | - "unable to register input polled device %s: %d\n", |
---|
334 | | - tj9->input_dev->name, err); |
---|
335 | | - input_free_device(tj9->input_dev); |
---|
336 | | - return err; |
---|
337 | | - } |
---|
338 | | - |
---|
339 | | - return 0; |
---|
340 | | -} |
---|
341 | | - |
---|
342 | 281 | /* |
---|
343 | 282 | * When IRQ mode is selected, we need to provide an interface to allow the user |
---|
344 | 283 | * to change the output data rate of the part. For consistency, we are using |
---|
.. | .. |
---|
404 | 343 | .attrs = kxtj9_attributes |
---|
405 | 344 | }; |
---|
406 | 345 | |
---|
407 | | - |
---|
408 | | -#ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE |
---|
409 | | -static void kxtj9_poll(struct input_polled_dev *dev) |
---|
| 346 | +static void kxtj9_poll(struct input_dev *input) |
---|
410 | 347 | { |
---|
411 | | - struct kxtj9_data *tj9 = dev->private; |
---|
412 | | - unsigned int poll_interval = dev->poll_interval; |
---|
| 348 | + struct kxtj9_data *tj9 = input_get_drvdata(input); |
---|
| 349 | + unsigned int poll_interval = input_get_poll_interval(input); |
---|
413 | 350 | |
---|
414 | 351 | kxtj9_report_acceleration_data(tj9); |
---|
415 | 352 | |
---|
.. | .. |
---|
419 | 356 | } |
---|
420 | 357 | } |
---|
421 | 358 | |
---|
422 | | -static void kxtj9_polled_input_open(struct input_polled_dev *dev) |
---|
| 359 | +static void kxtj9_platform_exit(void *data) |
---|
423 | 360 | { |
---|
424 | | - struct kxtj9_data *tj9 = dev->private; |
---|
| 361 | + struct kxtj9_data *tj9 = data; |
---|
425 | 362 | |
---|
426 | | - kxtj9_enable(tj9); |
---|
| 363 | + if (tj9->pdata.exit) |
---|
| 364 | + tj9->pdata.exit(); |
---|
427 | 365 | } |
---|
428 | | - |
---|
429 | | -static void kxtj9_polled_input_close(struct input_polled_dev *dev) |
---|
430 | | -{ |
---|
431 | | - struct kxtj9_data *tj9 = dev->private; |
---|
432 | | - |
---|
433 | | - kxtj9_disable(tj9); |
---|
434 | | -} |
---|
435 | | - |
---|
436 | | -static int kxtj9_setup_polled_device(struct kxtj9_data *tj9) |
---|
437 | | -{ |
---|
438 | | - int err; |
---|
439 | | - struct input_polled_dev *poll_dev; |
---|
440 | | - poll_dev = input_allocate_polled_device(); |
---|
441 | | - |
---|
442 | | - if (!poll_dev) { |
---|
443 | | - dev_err(&tj9->client->dev, |
---|
444 | | - "Failed to allocate polled device\n"); |
---|
445 | | - return -ENOMEM; |
---|
446 | | - } |
---|
447 | | - |
---|
448 | | - tj9->poll_dev = poll_dev; |
---|
449 | | - tj9->input_dev = poll_dev->input; |
---|
450 | | - |
---|
451 | | - poll_dev->private = tj9; |
---|
452 | | - poll_dev->poll = kxtj9_poll; |
---|
453 | | - poll_dev->open = kxtj9_polled_input_open; |
---|
454 | | - poll_dev->close = kxtj9_polled_input_close; |
---|
455 | | - |
---|
456 | | - kxtj9_init_input_device(tj9, poll_dev->input); |
---|
457 | | - |
---|
458 | | - err = input_register_polled_device(poll_dev); |
---|
459 | | - if (err) { |
---|
460 | | - dev_err(&tj9->client->dev, |
---|
461 | | - "Unable to register polled device, err=%d\n", err); |
---|
462 | | - input_free_polled_device(poll_dev); |
---|
463 | | - return err; |
---|
464 | | - } |
---|
465 | | - |
---|
466 | | - return 0; |
---|
467 | | -} |
---|
468 | | - |
---|
469 | | -static void kxtj9_teardown_polled_device(struct kxtj9_data *tj9) |
---|
470 | | -{ |
---|
471 | | - input_unregister_polled_device(tj9->poll_dev); |
---|
472 | | - input_free_polled_device(tj9->poll_dev); |
---|
473 | | -} |
---|
474 | | - |
---|
475 | | -#else |
---|
476 | | - |
---|
477 | | -static inline int kxtj9_setup_polled_device(struct kxtj9_data *tj9) |
---|
478 | | -{ |
---|
479 | | - return -ENOSYS; |
---|
480 | | -} |
---|
481 | | - |
---|
482 | | -static inline void kxtj9_teardown_polled_device(struct kxtj9_data *tj9) |
---|
483 | | -{ |
---|
484 | | -} |
---|
485 | | - |
---|
486 | | -#endif |
---|
487 | 366 | |
---|
488 | 367 | static int kxtj9_verify(struct kxtj9_data *tj9) |
---|
489 | 368 | { |
---|
.. | .. |
---|
507 | 386 | } |
---|
508 | 387 | |
---|
509 | 388 | static int kxtj9_probe(struct i2c_client *client, |
---|
510 | | - const struct i2c_device_id *id) |
---|
| 389 | + const struct i2c_device_id *id) |
---|
511 | 390 | { |
---|
512 | 391 | const struct kxtj9_platform_data *pdata = |
---|
513 | 392 | dev_get_platdata(&client->dev); |
---|
514 | 393 | struct kxtj9_data *tj9; |
---|
| 394 | + struct input_dev *input_dev; |
---|
515 | 395 | int err; |
---|
516 | 396 | |
---|
517 | 397 | if (!i2c_check_functionality(client->adapter, |
---|
.. | .. |
---|
525 | 405 | return -EINVAL; |
---|
526 | 406 | } |
---|
527 | 407 | |
---|
528 | | - tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL); |
---|
| 408 | + tj9 = devm_kzalloc(&client->dev, sizeof(*tj9), GFP_KERNEL); |
---|
529 | 409 | if (!tj9) { |
---|
530 | 410 | dev_err(&client->dev, |
---|
531 | 411 | "failed to allocate memory for module data\n"); |
---|
.. | .. |
---|
538 | 418 | if (pdata->init) { |
---|
539 | 419 | err = pdata->init(); |
---|
540 | 420 | if (err < 0) |
---|
541 | | - goto err_free_mem; |
---|
| 421 | + return err; |
---|
542 | 422 | } |
---|
| 423 | + |
---|
| 424 | + err = devm_add_action_or_reset(&client->dev, kxtj9_platform_exit, tj9); |
---|
| 425 | + if (err) |
---|
| 426 | + return err; |
---|
543 | 427 | |
---|
544 | 428 | err = kxtj9_verify(tj9); |
---|
545 | 429 | if (err < 0) { |
---|
546 | 430 | dev_err(&client->dev, "device not recognized\n"); |
---|
547 | | - goto err_pdata_exit; |
---|
| 431 | + return err; |
---|
548 | 432 | } |
---|
549 | 433 | |
---|
550 | 434 | i2c_set_clientdata(client, tj9); |
---|
.. | .. |
---|
552 | 436 | tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range; |
---|
553 | 437 | tj9->last_poll_interval = tj9->pdata.init_interval; |
---|
554 | 438 | |
---|
| 439 | + input_dev = devm_input_allocate_device(&client->dev); |
---|
| 440 | + if (!input_dev) { |
---|
| 441 | + dev_err(&client->dev, "input device allocate failed\n"); |
---|
| 442 | + return -ENOMEM; |
---|
| 443 | + } |
---|
| 444 | + |
---|
| 445 | + input_set_drvdata(input_dev, tj9); |
---|
| 446 | + tj9->input_dev = input_dev; |
---|
| 447 | + |
---|
| 448 | + input_dev->name = "kxtj9_accel"; |
---|
| 449 | + input_dev->id.bustype = BUS_I2C; |
---|
| 450 | + |
---|
| 451 | + input_dev->open = kxtj9_input_open; |
---|
| 452 | + input_dev->close = kxtj9_input_close; |
---|
| 453 | + |
---|
| 454 | + input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); |
---|
| 455 | + input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); |
---|
| 456 | + input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); |
---|
| 457 | + |
---|
| 458 | + if (client->irq <= 0) { |
---|
| 459 | + err = input_setup_polling(input_dev, kxtj9_poll); |
---|
| 460 | + if (err) |
---|
| 461 | + return err; |
---|
| 462 | + } |
---|
| 463 | + |
---|
| 464 | + err = input_register_device(input_dev); |
---|
| 465 | + if (err) { |
---|
| 466 | + dev_err(&client->dev, |
---|
| 467 | + "unable to register input polled device %s: %d\n", |
---|
| 468 | + input_dev->name, err); |
---|
| 469 | + return err; |
---|
| 470 | + } |
---|
| 471 | + |
---|
555 | 472 | if (client->irq) { |
---|
556 | 473 | /* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */ |
---|
557 | 474 | tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL; |
---|
558 | 475 | tj9->ctrl_reg1 |= DRDYE; |
---|
559 | 476 | |
---|
560 | | - err = kxtj9_setup_input_device(tj9); |
---|
561 | | - if (err) |
---|
562 | | - goto err_pdata_exit; |
---|
563 | | - |
---|
564 | | - err = request_threaded_irq(client->irq, NULL, kxtj9_isr, |
---|
565 | | - IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
---|
566 | | - "kxtj9-irq", tj9); |
---|
| 477 | + err = devm_request_threaded_irq(&client->dev, client->irq, |
---|
| 478 | + NULL, kxtj9_isr, |
---|
| 479 | + IRQF_TRIGGER_RISING | |
---|
| 480 | + IRQF_ONESHOT, |
---|
| 481 | + "kxtj9-irq", tj9); |
---|
567 | 482 | if (err) { |
---|
568 | 483 | dev_err(&client->dev, "request irq failed: %d\n", err); |
---|
569 | | - goto err_destroy_input; |
---|
| 484 | + return err; |
---|
570 | 485 | } |
---|
571 | 486 | |
---|
572 | | - err = sysfs_create_group(&client->dev.kobj, &kxtj9_attribute_group); |
---|
| 487 | + err = devm_device_add_group(&client->dev, |
---|
| 488 | + &kxtj9_attribute_group); |
---|
573 | 489 | if (err) { |
---|
574 | 490 | dev_err(&client->dev, "sysfs create failed: %d\n", err); |
---|
575 | | - goto err_free_irq; |
---|
| 491 | + return err; |
---|
576 | 492 | } |
---|
577 | | - |
---|
578 | | - } else { |
---|
579 | | - err = kxtj9_setup_polled_device(tj9); |
---|
580 | | - if (err) |
---|
581 | | - goto err_pdata_exit; |
---|
582 | 493 | } |
---|
583 | | - |
---|
584 | | - return 0; |
---|
585 | | - |
---|
586 | | -err_free_irq: |
---|
587 | | - free_irq(client->irq, tj9); |
---|
588 | | -err_destroy_input: |
---|
589 | | - input_unregister_device(tj9->input_dev); |
---|
590 | | -err_pdata_exit: |
---|
591 | | - if (tj9->pdata.exit) |
---|
592 | | - tj9->pdata.exit(); |
---|
593 | | -err_free_mem: |
---|
594 | | - kfree(tj9); |
---|
595 | | - return err; |
---|
596 | | -} |
---|
597 | | - |
---|
598 | | -static int kxtj9_remove(struct i2c_client *client) |
---|
599 | | -{ |
---|
600 | | - struct kxtj9_data *tj9 = i2c_get_clientdata(client); |
---|
601 | | - |
---|
602 | | - if (client->irq) { |
---|
603 | | - sysfs_remove_group(&client->dev.kobj, &kxtj9_attribute_group); |
---|
604 | | - free_irq(client->irq, tj9); |
---|
605 | | - input_unregister_device(tj9->input_dev); |
---|
606 | | - } else { |
---|
607 | | - kxtj9_teardown_polled_device(tj9); |
---|
608 | | - } |
---|
609 | | - |
---|
610 | | - if (tj9->pdata.exit) |
---|
611 | | - tj9->pdata.exit(); |
---|
612 | | - |
---|
613 | | - kfree(tj9); |
---|
614 | 494 | |
---|
615 | 495 | return 0; |
---|
616 | 496 | } |
---|
.. | .. |
---|
660 | 540 | .pm = &kxtj9_pm_ops, |
---|
661 | 541 | }, |
---|
662 | 542 | .probe = kxtj9_probe, |
---|
663 | | - .remove = kxtj9_remove, |
---|
664 | 543 | .id_table = kxtj9_id, |
---|
665 | 544 | }; |
---|
666 | 545 | |
---|