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