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

media: i2c: imx319: Use V4L2 sensor clock helper

Several camera sensor drivers access the "clock-frequency" property
directly to retrieve the external clock rate, or modify the clock rate
of the external clock programmatically. Both behaviours are valid on
a subset of ACPI platforms, but are considered deprecated on OF
platforms, and do not support ACPI platforms that implement MIPI DisCo
for Imaging. Implementing them manually in drivers is deprecated, as
that can encourage cargo-cult and lead to differences in behaviour
between drivers. Instead, drivers should use the
devm_v4l2_sensor_clk_get() helper.

This driver supports ACPI platforms only. It retrieves the clock rate
from the "clock-frequency" property. If the rate does not match the
expected rate, the driver fails probing. This is correct behaviour for
ACPI.

Switch to using the devm_v4l2_sensor_clk_get() helper. This does not
change the behaviour on ACPI platforms that specify a clock-frequency
property and don't provide a clock. On ACPI platforms that provide a
clock, the clock rate will be set to the value of the clock-frequency
property. This should not change the behaviour either as this driver
expects the clock to be set to that rate, and wouldn't operate correctly
otherwise.

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

authored by

Laurent Pinchart and committed by
Mauro Carvalho Chehab
047119e3 df294262

+14 -15
+14 -15
drivers/media/i2c/imx319.c
··· 2 2 // Copyright (C) 2018 Intel Corporation 3 3 4 4 #include <linux/acpi.h> 5 + #include <linux/clk.h> 5 6 #include <linux/i2c.h> 6 7 #include <linux/module.h> 7 8 #include <linux/pm_runtime.h> ··· 108 107 }; 109 108 110 109 struct imx319_hwcfg { 111 - u32 ext_clk; /* sensor external clk */ 112 110 unsigned long link_freq_bitmap; 113 111 }; 114 112 ··· 2347 2347 if (!cfg) 2348 2348 goto out_err; 2349 2349 2350 - ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", 2351 - &cfg->ext_clk); 2352 - if (ret) { 2353 - dev_err(dev, "can't get clock frequency"); 2354 - goto out_err; 2355 - } 2356 - 2357 - dev_dbg(dev, "ext clk: %d", cfg->ext_clk); 2358 - if (cfg->ext_clk != IMX319_EXT_CLK) { 2359 - dev_err(dev, "external clock %d is not supported", 2360 - cfg->ext_clk); 2361 - goto out_err; 2362 - } 2363 - 2364 2350 ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, 2365 2351 bus_cfg.nr_of_link_frequencies, 2366 2352 link_freq_menu_items, ··· 2368 2382 static int imx319_probe(struct i2c_client *client) 2369 2383 { 2370 2384 struct imx319 *imx319; 2385 + unsigned long freq; 2386 + struct clk *clk; 2371 2387 bool full_power; 2372 2388 int ret; 2373 2389 ··· 2380 2392 imx319->dev = &client->dev; 2381 2393 2382 2394 mutex_init(&imx319->mutex); 2395 + 2396 + clk = devm_v4l2_sensor_clk_get(imx319->dev, NULL); 2397 + if (IS_ERR(clk)) 2398 + return dev_err_probe(imx319->dev, PTR_ERR(clk), 2399 + "failed to acquire clock\n"); 2400 + 2401 + freq = clk_get_rate(clk); 2402 + if (freq != IMX319_EXT_CLK) 2403 + return dev_err_probe(imx319->dev, -EINVAL, 2404 + "external clock %lu is not supported", 2405 + freq); 2383 2406 2384 2407 /* Initialize subdev */ 2385 2408 v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);