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

media: i2c: ov08d10: 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 prints a warning. 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
1e921b26 4e2b34c3

+12 -11
+12 -11
drivers/media/i2c/ov08d10.c
··· 516 516 517 517 struct ov08d10 { 518 518 struct device *dev; 519 + struct clk *clk; 519 520 520 521 struct v4l2_subdev sd; 521 522 struct media_pad pad; 522 523 struct v4l2_ctrl_handler ctrl_handler; 523 - 524 - struct clk *xvclk; 525 524 526 525 /* V4L2 Controls */ 527 526 struct v4l2_ctrl *link_freq; ··· 1308 1309 struct v4l2_fwnode_endpoint bus_cfg = { 1309 1310 .bus_type = V4L2_MBUS_CSI2_DPHY 1310 1311 }; 1311 - u32 xvclk_rate; 1312 1312 unsigned int i, j; 1313 1313 int ret; 1314 1314 1315 1315 if (!fwnode) 1316 1316 return -ENXIO; 1317 - 1318 - ret = fwnode_property_read_u32(fwnode, "clock-frequency", &xvclk_rate); 1319 - if (ret) 1320 - return ret; 1321 - 1322 - if (xvclk_rate != OV08D10_XVCLK_19_2) 1323 - dev_warn(dev, "external clock rate %u is unsupported", 1324 - xvclk_rate); 1325 1317 1326 1318 ep = fwnode_graph_get_next_endpoint(fwnode, NULL); 1327 1319 if (!ep) ··· 1378 1388 static int ov08d10_probe(struct i2c_client *client) 1379 1389 { 1380 1390 struct ov08d10 *ov08d10; 1391 + unsigned long freq; 1381 1392 int ret; 1382 1393 1383 1394 ov08d10 = devm_kzalloc(&client->dev, sizeof(*ov08d10), GFP_KERNEL); ··· 1386 1395 return -ENOMEM; 1387 1396 1388 1397 ov08d10->dev = &client->dev; 1398 + 1399 + ov08d10->clk = devm_v4l2_sensor_clk_get(ov08d10->dev, NULL); 1400 + if (IS_ERR(ov08d10->clk)) 1401 + return dev_err_probe(ov08d10->dev, PTR_ERR(ov08d10->clk), 1402 + "failed to get clock\n"); 1403 + 1404 + freq = clk_get_rate(ov08d10->clk); 1405 + if (freq != OV08D10_XVCLK_19_2) 1406 + dev_warn(ov08d10->dev, 1407 + "external clock rate %lu is not supported\n", freq); 1389 1408 1390 1409 ret = ov08d10_get_hwcfg(ov08d10); 1391 1410 if (ret) {