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

media: i2c: ov2740: 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 if
present, and 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
853bd2ec fdba8eba

+8 -16
+8 -16
drivers/media/i2c/ov2740.c
··· 1133 1133 struct v4l2_fwnode_endpoint bus_cfg = { 1134 1134 .bus_type = V4L2_MBUS_CSI2_DPHY 1135 1135 }; 1136 - u32 mclk; 1137 1136 int ret; 1138 1137 unsigned int i, j; 1139 1138 ··· 1144 1145 if (!ep) 1145 1146 return dev_err_probe(dev, -EPROBE_DEFER, 1146 1147 "waiting for fwnode graph endpoint\n"); 1147 - 1148 - ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); 1149 - if (ret) { 1150 - fwnode_handle_put(ep); 1151 - return dev_err_probe(dev, ret, 1152 - "reading clock-frequency property\n"); 1153 - } 1154 - 1155 - if (mclk != OV2740_MCLK) { 1156 - fwnode_handle_put(ep); 1157 - return dev_err_probe(dev, -EINVAL, 1158 - "external clock %d is not supported\n", 1159 - mclk); 1160 - } 1161 1148 1162 1149 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); 1163 1150 fwnode_handle_put(ep); ··· 1327 1342 { 1328 1343 struct device *dev = &client->dev; 1329 1344 struct ov2740 *ov2740; 1345 + unsigned long freq; 1330 1346 bool full_power; 1331 1347 unsigned int i; 1332 1348 int ret; ··· 1365 1379 msleep(20); 1366 1380 } 1367 1381 1368 - ov2740->clk = devm_clk_get_optional(dev, "clk"); 1382 + ov2740->clk = devm_v4l2_sensor_clk_get(dev, "clk"); 1369 1383 if (IS_ERR(ov2740->clk)) 1370 1384 return dev_err_probe(dev, PTR_ERR(ov2740->clk), 1371 1385 "failed to get clock\n"); 1386 + 1387 + freq = clk_get_rate(ov2740->clk); 1388 + if (freq != OV2740_MCLK) 1389 + return dev_err_probe(dev, -EINVAL, 1390 + "external clock %lu is not supported\n", 1391 + freq); 1372 1392 1373 1393 for (i = 0; i < ARRAY_SIZE(ov2740_supply_name); i++) 1374 1394 ov2740->supplies[i].supply = ov2740_supply_name[i];