| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * drivers/leds/leds-as3645a.c - AS3645A and LM3555 flash controllers driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 7 | 8 | * Based on drivers/media/i2c/as3645a.c. |
|---|
| 8 | 9 | * |
|---|
| 9 | 10 | * Contact: Sakari Ailus <sakari.ailus@iki.fi> |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or |
|---|
| 12 | | - * modify it under the terms of the GNU General Public License |
|---|
| 13 | | - * version 2 as published by the Free Software Foundation. |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 16 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 18 | | - * General Public License for more details. |
|---|
| 19 | 11 | */ |
|---|
| 20 | 12 | |
|---|
| 21 | 13 | #include <linux/delay.h> |
|---|
| .. | .. |
|---|
| 25 | 17 | #include <linux/leds.h> |
|---|
| 26 | 18 | #include <linux/module.h> |
|---|
| 27 | 19 | #include <linux/mutex.h> |
|---|
| 28 | | -#include <linux/of.h> |
|---|
| 20 | +#include <linux/property.h> |
|---|
| 29 | 21 | #include <linux/slab.h> |
|---|
| 30 | 22 | |
|---|
| 31 | 23 | #include <media/v4l2-flash-led-class.h> |
|---|
| .. | .. |
|---|
| 132 | 124 | u32 peak; |
|---|
| 133 | 125 | }; |
|---|
| 134 | 126 | |
|---|
| 135 | | -struct as3645a_names { |
|---|
| 136 | | - char flash[32]; |
|---|
| 137 | | - char indicator[32]; |
|---|
| 138 | | -}; |
|---|
| 139 | | - |
|---|
| 140 | 127 | struct as3645a { |
|---|
| 141 | 128 | struct i2c_client *client; |
|---|
| 142 | 129 | |
|---|
| .. | .. |
|---|
| 148 | 135 | struct v4l2_flash *vf; |
|---|
| 149 | 136 | struct v4l2_flash *vfind; |
|---|
| 150 | 137 | |
|---|
| 151 | | - struct device_node *flash_node; |
|---|
| 152 | | - struct device_node *indicator_node; |
|---|
| 138 | + struct fwnode_handle *flash_node; |
|---|
| 139 | + struct fwnode_handle *indicator_node; |
|---|
| 153 | 140 | |
|---|
| 154 | 141 | struct as3645a_config cfg; |
|---|
| 155 | 142 | |
|---|
| .. | .. |
|---|
| 492 | 479 | } |
|---|
| 493 | 480 | |
|---|
| 494 | 481 | static int as3645a_parse_node(struct as3645a *flash, |
|---|
| 495 | | - struct as3645a_names *names, |
|---|
| 496 | | - struct device_node *node) |
|---|
| 482 | + struct fwnode_handle *fwnode) |
|---|
| 497 | 483 | { |
|---|
| 498 | 484 | struct as3645a_config *cfg = &flash->cfg; |
|---|
| 499 | | - struct device_node *child; |
|---|
| 500 | | - const char *name; |
|---|
| 485 | + struct fwnode_handle *child; |
|---|
| 501 | 486 | int rval; |
|---|
| 502 | 487 | |
|---|
| 503 | | - for_each_child_of_node(node, child) { |
|---|
| 488 | + fwnode_for_each_child_node(fwnode, child) { |
|---|
| 504 | 489 | u32 id = 0; |
|---|
| 505 | 490 | |
|---|
| 506 | | - of_property_read_u32(child, "reg", &id); |
|---|
| 491 | + fwnode_property_read_u32(child, "reg", &id); |
|---|
| 507 | 492 | |
|---|
| 508 | 493 | switch (id) { |
|---|
| 509 | 494 | case AS_LED_FLASH: |
|---|
| 510 | | - flash->flash_node = of_node_get(child); |
|---|
| 495 | + flash->flash_node = child; |
|---|
| 496 | + fwnode_handle_get(child); |
|---|
| 511 | 497 | break; |
|---|
| 512 | 498 | case AS_LED_INDICATOR: |
|---|
| 513 | | - flash->indicator_node = of_node_get(child); |
|---|
| 499 | + flash->indicator_node = child; |
|---|
| 500 | + fwnode_handle_get(child); |
|---|
| 514 | 501 | break; |
|---|
| 515 | 502 | default: |
|---|
| 516 | 503 | dev_warn(&flash->client->dev, |
|---|
| .. | .. |
|---|
| 524 | 511 | return -ENODEV; |
|---|
| 525 | 512 | } |
|---|
| 526 | 513 | |
|---|
| 527 | | - rval = of_property_read_string(flash->flash_node, "label", &name); |
|---|
| 528 | | - if (!rval) |
|---|
| 529 | | - strlcpy(names->flash, name, sizeof(names->flash)); |
|---|
| 530 | | - else |
|---|
| 531 | | - snprintf(names->flash, sizeof(names->flash), |
|---|
| 532 | | - "%s:flash", node->name); |
|---|
| 533 | | - |
|---|
| 534 | | - rval = of_property_read_u32(flash->flash_node, "flash-timeout-us", |
|---|
| 535 | | - &cfg->flash_timeout_us); |
|---|
| 514 | + rval = fwnode_property_read_u32(flash->flash_node, "flash-timeout-us", |
|---|
| 515 | + &cfg->flash_timeout_us); |
|---|
| 536 | 516 | if (rval < 0) { |
|---|
| 537 | 517 | dev_err(&flash->client->dev, |
|---|
| 538 | 518 | "can't read flash-timeout-us property for flash\n"); |
|---|
| 539 | 519 | goto out_err; |
|---|
| 540 | 520 | } |
|---|
| 541 | 521 | |
|---|
| 542 | | - rval = of_property_read_u32(flash->flash_node, "flash-max-microamp", |
|---|
| 543 | | - &cfg->flash_max_ua); |
|---|
| 522 | + rval = fwnode_property_read_u32(flash->flash_node, "flash-max-microamp", |
|---|
| 523 | + &cfg->flash_max_ua); |
|---|
| 544 | 524 | if (rval < 0) { |
|---|
| 545 | 525 | dev_err(&flash->client->dev, |
|---|
| 546 | 526 | "can't read flash-max-microamp property for flash\n"); |
|---|
| 547 | 527 | goto out_err; |
|---|
| 548 | 528 | } |
|---|
| 549 | 529 | |
|---|
| 550 | | - rval = of_property_read_u32(flash->flash_node, "led-max-microamp", |
|---|
| 551 | | - &cfg->assist_max_ua); |
|---|
| 530 | + rval = fwnode_property_read_u32(flash->flash_node, "led-max-microamp", |
|---|
| 531 | + &cfg->assist_max_ua); |
|---|
| 552 | 532 | if (rval < 0) { |
|---|
| 553 | 533 | dev_err(&flash->client->dev, |
|---|
| 554 | 534 | "can't read led-max-microamp property for flash\n"); |
|---|
| 555 | 535 | goto out_err; |
|---|
| 556 | 536 | } |
|---|
| 557 | 537 | |
|---|
| 558 | | - of_property_read_u32(flash->flash_node, "voltage-reference", |
|---|
| 559 | | - &cfg->voltage_reference); |
|---|
| 538 | + fwnode_property_read_u32(flash->flash_node, "voltage-reference", |
|---|
| 539 | + &cfg->voltage_reference); |
|---|
| 560 | 540 | |
|---|
| 561 | | - of_property_read_u32(flash->flash_node, "ams,input-max-microamp", |
|---|
| 562 | | - &cfg->peak); |
|---|
| 541 | + fwnode_property_read_u32(flash->flash_node, "ams,input-max-microamp", |
|---|
| 542 | + &cfg->peak); |
|---|
| 563 | 543 | cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak); |
|---|
| 564 | 544 | |
|---|
| 565 | 545 | if (!flash->indicator_node) { |
|---|
| .. | .. |
|---|
| 569 | 549 | goto out_err; |
|---|
| 570 | 550 | } |
|---|
| 571 | 551 | |
|---|
| 572 | | - rval = of_property_read_string(flash->indicator_node, "label", &name); |
|---|
| 573 | | - if (!rval) |
|---|
| 574 | | - strlcpy(names->indicator, name, sizeof(names->indicator)); |
|---|
| 575 | | - else |
|---|
| 576 | | - snprintf(names->indicator, sizeof(names->indicator), |
|---|
| 577 | | - "%s:indicator", node->name); |
|---|
| 578 | 552 | |
|---|
| 579 | | - rval = of_property_read_u32(flash->indicator_node, "led-max-microamp", |
|---|
| 580 | | - &cfg->indicator_max_ua); |
|---|
| 553 | + rval = fwnode_property_read_u32(flash->indicator_node, |
|---|
| 554 | + "led-max-microamp", |
|---|
| 555 | + &cfg->indicator_max_ua); |
|---|
| 581 | 556 | if (rval < 0) { |
|---|
| 582 | 557 | dev_err(&flash->client->dev, |
|---|
| 583 | 558 | "can't read led-max-microamp property for indicator\n"); |
|---|
| .. | .. |
|---|
| 587 | 562 | return 0; |
|---|
| 588 | 563 | |
|---|
| 589 | 564 | out_err: |
|---|
| 590 | | - of_node_put(flash->flash_node); |
|---|
| 591 | | - of_node_put(flash->indicator_node); |
|---|
| 565 | + fwnode_handle_put(flash->flash_node); |
|---|
| 566 | + fwnode_handle_put(flash->indicator_node); |
|---|
| 592 | 567 | |
|---|
| 593 | 568 | return rval; |
|---|
| 594 | 569 | } |
|---|
| 595 | 570 | |
|---|
| 596 | | -static int as3645a_led_class_setup(struct as3645a *flash, |
|---|
| 597 | | - struct as3645a_names *names) |
|---|
| 571 | +static int as3645a_led_class_setup(struct as3645a *flash) |
|---|
| 598 | 572 | { |
|---|
| 599 | 573 | struct led_classdev *fled_cdev = &flash->fled.led_cdev; |
|---|
| 600 | 574 | struct led_classdev *iled_cdev = &flash->iled_cdev; |
|---|
| 575 | + struct led_init_data init_data = {}; |
|---|
| 601 | 576 | struct led_flash_setting *cfg; |
|---|
| 602 | 577 | int rval; |
|---|
| 603 | 578 | |
|---|
| 604 | | - iled_cdev->name = names->indicator; |
|---|
| 605 | 579 | iled_cdev->brightness_set_blocking = as3645a_set_indicator_brightness; |
|---|
| 606 | 580 | iled_cdev->max_brightness = |
|---|
| 607 | 581 | flash->cfg.indicator_max_ua / AS_INDICATOR_INTENSITY_STEP; |
|---|
| 608 | 582 | iled_cdev->flags = LED_CORE_SUSPENDRESUME; |
|---|
| 609 | 583 | |
|---|
| 610 | | - rval = led_classdev_register(&flash->client->dev, iled_cdev); |
|---|
| 584 | + init_data.fwnode = flash->indicator_node; |
|---|
| 585 | + init_data.devicename = AS_NAME; |
|---|
| 586 | + init_data.default_label = "indicator"; |
|---|
| 587 | + |
|---|
| 588 | + rval = led_classdev_register_ext(&flash->client->dev, iled_cdev, |
|---|
| 589 | + &init_data); |
|---|
| 611 | 590 | if (rval < 0) |
|---|
| 612 | 591 | return rval; |
|---|
| 613 | 592 | |
|---|
| .. | .. |
|---|
| 625 | 604 | |
|---|
| 626 | 605 | flash->fled.ops = &as3645a_led_flash_ops; |
|---|
| 627 | 606 | |
|---|
| 628 | | - fled_cdev->name = names->flash; |
|---|
| 629 | 607 | fled_cdev->brightness_set_blocking = as3645a_set_assist_brightness; |
|---|
| 630 | 608 | /* Value 0 is off in LED class. */ |
|---|
| 631 | 609 | fled_cdev->max_brightness = |
|---|
| .. | .. |
|---|
| 633 | 611 | flash->cfg.assist_max_ua) + 1; |
|---|
| 634 | 612 | fled_cdev->flags = LED_DEV_CAP_FLASH | LED_CORE_SUSPENDRESUME; |
|---|
| 635 | 613 | |
|---|
| 636 | | - rval = led_classdev_flash_register(&flash->client->dev, &flash->fled); |
|---|
| 637 | | - if (rval) { |
|---|
| 638 | | - led_classdev_unregister(iled_cdev); |
|---|
| 639 | | - dev_err(&flash->client->dev, |
|---|
| 640 | | - "led_classdev_flash_register() failed, error %d\n", |
|---|
| 641 | | - rval); |
|---|
| 642 | | - } |
|---|
| 614 | + init_data.fwnode = flash->flash_node; |
|---|
| 615 | + init_data.devicename = AS_NAME; |
|---|
| 616 | + init_data.default_label = "flash"; |
|---|
| 643 | 617 | |
|---|
| 618 | + rval = led_classdev_flash_register_ext(&flash->client->dev, |
|---|
| 619 | + &flash->fled, &init_data); |
|---|
| 620 | + if (rval) |
|---|
| 621 | + goto out_err; |
|---|
| 622 | + |
|---|
| 623 | + return rval; |
|---|
| 624 | + |
|---|
| 625 | +out_err: |
|---|
| 626 | + led_classdev_unregister(iled_cdev); |
|---|
| 627 | + dev_err(&flash->client->dev, |
|---|
| 628 | + "led_classdev_flash_register() failed, error %d\n", |
|---|
| 629 | + rval); |
|---|
| 644 | 630 | return rval; |
|---|
| 645 | 631 | } |
|---|
| 646 | 632 | |
|---|
| .. | .. |
|---|
| 665 | 651 | }, |
|---|
| 666 | 652 | }; |
|---|
| 667 | 653 | |
|---|
| 668 | | - strlcpy(cfg.dev_name, led->name, sizeof(cfg.dev_name)); |
|---|
| 669 | | - strlcpy(cfgind.dev_name, flash->iled_cdev.name, sizeof(cfg.dev_name)); |
|---|
| 654 | + strlcpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name)); |
|---|
| 655 | + strlcpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name, |
|---|
| 656 | + sizeof(cfgind.dev_name)); |
|---|
| 670 | 657 | |
|---|
| 671 | 658 | flash->vf = v4l2_flash_init( |
|---|
| 672 | | - &flash->client->dev, of_fwnode_handle(flash->flash_node), |
|---|
| 673 | | - &flash->fled, NULL, &cfg); |
|---|
| 659 | + &flash->client->dev, flash->flash_node, &flash->fled, NULL, |
|---|
| 660 | + &cfg); |
|---|
| 674 | 661 | if (IS_ERR(flash->vf)) |
|---|
| 675 | 662 | return PTR_ERR(flash->vf); |
|---|
| 676 | 663 | |
|---|
| 677 | 664 | flash->vfind = v4l2_flash_indicator_init( |
|---|
| 678 | | - &flash->client->dev, of_fwnode_handle(flash->indicator_node), |
|---|
| 679 | | - &flash->iled_cdev, &cfgind); |
|---|
| 665 | + &flash->client->dev, flash->indicator_node, &flash->iled_cdev, |
|---|
| 666 | + &cfgind); |
|---|
| 680 | 667 | if (IS_ERR(flash->vfind)) { |
|---|
| 681 | 668 | v4l2_flash_release(flash->vf); |
|---|
| 682 | 669 | return PTR_ERR(flash->vfind); |
|---|
| .. | .. |
|---|
| 687 | 674 | |
|---|
| 688 | 675 | static int as3645a_probe(struct i2c_client *client) |
|---|
| 689 | 676 | { |
|---|
| 690 | | - struct as3645a_names names; |
|---|
| 691 | 677 | struct as3645a *flash; |
|---|
| 692 | 678 | int rval; |
|---|
| 693 | 679 | |
|---|
| 694 | | - if (client->dev.of_node == NULL) |
|---|
| 680 | + if (!dev_fwnode(&client->dev)) |
|---|
| 695 | 681 | return -ENODEV; |
|---|
| 696 | 682 | |
|---|
| 697 | 683 | flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 700 | 686 | |
|---|
| 701 | 687 | flash->client = client; |
|---|
| 702 | 688 | |
|---|
| 703 | | - rval = as3645a_parse_node(flash, &names, client->dev.of_node); |
|---|
| 689 | + rval = as3645a_parse_node(flash, dev_fwnode(&client->dev)); |
|---|
| 704 | 690 | if (rval < 0) |
|---|
| 705 | 691 | return rval; |
|---|
| 706 | 692 | |
|---|
| .. | .. |
|---|
| 715 | 701 | if (rval) |
|---|
| 716 | 702 | goto out_mutex_destroy; |
|---|
| 717 | 703 | |
|---|
| 718 | | - rval = as3645a_led_class_setup(flash, &names); |
|---|
| 704 | + rval = as3645a_led_class_setup(flash); |
|---|
| 719 | 705 | if (rval) |
|---|
| 720 | 706 | goto out_mutex_destroy; |
|---|
| 721 | 707 | |
|---|
| .. | .. |
|---|
| 732 | 718 | mutex_destroy(&flash->mutex); |
|---|
| 733 | 719 | |
|---|
| 734 | 720 | out_put_nodes: |
|---|
| 735 | | - of_node_put(flash->flash_node); |
|---|
| 736 | | - of_node_put(flash->indicator_node); |
|---|
| 721 | + fwnode_handle_put(flash->flash_node); |
|---|
| 722 | + fwnode_handle_put(flash->indicator_node); |
|---|
| 737 | 723 | |
|---|
| 738 | 724 | return rval; |
|---|
| 739 | 725 | } |
|---|
| .. | .. |
|---|
| 752 | 738 | |
|---|
| 753 | 739 | mutex_destroy(&flash->mutex); |
|---|
| 754 | 740 | |
|---|
| 755 | | - of_node_put(flash->flash_node); |
|---|
| 756 | | - of_node_put(flash->indicator_node); |
|---|
| 741 | + fwnode_handle_put(flash->flash_node); |
|---|
| 742 | + fwnode_handle_put(flash->indicator_node); |
|---|
| 757 | 743 | |
|---|
| 758 | 744 | return 0; |
|---|
| 759 | 745 | } |
|---|