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

media: v4l2-common: Add a helper for obtaining the clock producer

Introduce a helper for v4l2 sensor drivers on both DT- and ACPI-based
platforms to retrieve a reference to the clock producer from firmware.

This helper behaves the same as devm_clk_get() except where there is
no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency"
ACPI _DSD property and register a fixed frequency clock with the frequency
indicated in the property.

This function also handles the special ACPI-based system case where:
. The clock-frequency _DSD property is present.
. A reference to the clock producer is present, where the clock is provided
by a camera sensor PMIC driver (e.g. int3472/tps68470.c)
In this case try to set the clock-frequency value to the provided clock.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Mehdi Djait <mehdi.djait@linux.intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Mehdi Djait and committed by
Hans Verkuil
7ecb662b 078f1a7e

+79
+52
drivers/media/v4l2-core/v4l2-common.c
··· 34 34 * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman) 35 35 */ 36 36 37 + #include <linux/clk.h> 38 + #include <linux/clkdev.h> 39 + #include <linux/clk-provider.h> 37 40 #include <linux/module.h> 38 41 #include <linux/types.h> 39 42 #include <linux/kernel.h> ··· 708 705 return 0; 709 706 } 710 707 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap); 708 + 709 + struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id) 710 + { 711 + const char *clk_id __free(kfree) = NULL; 712 + struct clk_hw *clk_hw; 713 + struct clk *clk; 714 + bool of_node; 715 + u32 rate; 716 + int ret; 717 + 718 + clk = devm_clk_get_optional(dev, id); 719 + if (IS_ERR(clk)) 720 + return clk; 721 + 722 + ret = device_property_read_u32(dev, "clock-frequency", &rate); 723 + of_node = is_of_node(dev_fwnode(dev)); 724 + 725 + if (clk) { 726 + if (!ret && !of_node) { 727 + ret = clk_set_rate(clk, rate); 728 + if (ret) { 729 + dev_err(dev, "Failed to set clock rate: %u\n", 730 + rate); 731 + return ERR_PTR(ret); 732 + } 733 + } 734 + return clk; 735 + } 736 + 737 + if (!IS_ENABLED(CONFIG_COMMON_CLK) || of_node) 738 + return ERR_PTR(-ENOENT); 739 + 740 + if (ret) 741 + return ERR_PTR(ret == -EINVAL ? -EPROBE_DEFER : ret); 742 + 743 + if (!id) { 744 + clk_id = kasprintf(GFP_KERNEL, "clk-%s", dev_name(dev)); 745 + if (!clk_id) 746 + return ERR_PTR(-ENOMEM); 747 + id = clk_id; 748 + } 749 + 750 + clk_hw = devm_clk_hw_register_fixed_rate(dev, id, NULL, 0, rate); 751 + if (IS_ERR(clk_hw)) 752 + return ERR_CAST(clk_hw); 753 + 754 + return clk_hw->clk; 755 + } 756 + EXPORT_SYMBOL_GPL(devm_v4l2_sensor_clk_get);
+27
include/media/v4l2-common.h
··· 97 97 98 98 /* ------------------------------------------------------------------------- */ 99 99 100 + struct clk; 100 101 struct v4l2_device; 101 102 struct v4l2_subdev; 102 103 struct v4l2_subdev_ops; ··· 620 619 const s64 *driver_link_freqs, 621 620 unsigned int num_of_driver_link_freqs, 622 621 unsigned long *bitmap); 622 + 623 + /** 624 + * devm_v4l2_sensor_clk_get - lookup and obtain a reference to a clock producer 625 + * for a camera sensor. 626 + * 627 + * @dev: device for v4l2 sensor clock "consumer" 628 + * @id: clock consumer ID 629 + * 630 + * This function behaves the same way as devm_clk_get() except where there 631 + * is no clock producer like in ACPI-based platforms. 632 + * 633 + * For ACPI-based platforms, the function will read the "clock-frequency" 634 + * ACPI _DSD property and register a fixed-clock with the frequency indicated 635 + * in the property. 636 + * 637 + * This function also handles the special ACPI-based system case where: 638 + * 639 + * * The clock-frequency _DSD property is present. 640 + * * A reference to the clock producer is present, where the clock is provided 641 + * by a camera sensor PMIC driver (e.g. int3472/tps68470.c) 642 + * 643 + * In this case try to set the clock-frequency value to the provided clock. 644 + * 645 + * Returns a pointer to a struct clk on success or an error pointer on failure. 646 + */ 647 + struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id); 623 648 624 649 static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf) 625 650 {