| .. | .. |
|---|
| 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 | |
|---|