Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2272e13 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] v4l: mt9v032: Add OF support



Parse DT properties into a platform data structure when a DT node is
available.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 5888f9df
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
* Aptina 1/3-Inch WVGA CMOS Digital Image Sensor

The Aptina MT9V032 is a 1/3-inch CMOS active pixel digital image sensor with
an active array size of 752H x 480V. It is programmable through a simple
two-wire serial interface.

Required Properties:

- compatible: value should be either one among the following
	(a) "aptina,mt9v022" for MT9V022 color sensor
	(b) "aptina,mt9v022m" for MT9V022 monochrome sensor
	(c) "aptina,mt9v024" for MT9V024 color sensor
	(d) "aptina,mt9v024m" for MT9V024 monochrome sensor
	(e) "aptina,mt9v032" for MT9V032 color sensor
	(f) "aptina,mt9v032m" for MT9V032 monochrome sensor
	(g) "aptina,mt9v034" for MT9V034 color sensor
	(h) "aptina,mt9v034m" for MT9V034 monochrome sensor

Optional Properties:

- link-frequencies: List of allowed link frequencies in Hz. Each frequency is
	expressed as a 64-bit big-endian integer.

For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.

Example:

	mt9v032@5c {
		compatible = "aptina,mt9v032";
		reg = <0x5c>;

		port {
			mt9v032_out: endpoint {
				link-frequencies = /bits/ 64
					<13000000 26600000 27000000>;
			};
		};
	};
+1 −0
Original line number Diff line number Diff line
@@ -6535,6 +6535,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L:	linux-media@vger.kernel.org
T:	git git://linuxtv.org/media_tree.git
S:	Maintained
F:	Documentation/devicetree/bindings/media/i2c/mt9v032.txt
F:	drivers/media/i2c/mt9v032.c
F:	include/media/mt9v032.h

+68 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#include <linux/i2c.h>
#include <linux/log2.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
@@ -26,6 +28,7 @@
#include <media/mt9v032.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h>

/* The first four rows are black rows. The active area spans 753x481 pixels. */
@@ -876,10 +879,58 @@ static const struct regmap_config mt9v032_regmap_config = {
 * Driver initialization and probing
 */

static struct mt9v032_platform_data *
mt9v032_get_pdata(struct i2c_client *client)
{
	struct mt9v032_platform_data *pdata;
	struct v4l2_of_endpoint endpoint;
	struct device_node *np;
	struct property *prop;

	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
		return client->dev.platform_data;

	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
	if (!np)
		return NULL;

	if (v4l2_of_parse_endpoint(np, &endpoint) < 0)
		goto done;

	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		goto done;

	prop = of_find_property(np, "link-frequencies", NULL);
	if (prop) {
		u64 *link_freqs;
		size_t size = prop->length / sizeof(*link_freqs);

		link_freqs = devm_kcalloc(&client->dev, size,
					  sizeof(*link_freqs), GFP_KERNEL);
		if (!link_freqs)
			goto done;

		if (of_property_read_u64_array(np, "link-frequencies",
					       link_freqs, size) < 0)
			goto done;

		pdata->link_freqs = link_freqs;
		pdata->link_def_freq = link_freqs[0];
	}

	pdata->clk_pol = !!(endpoint.bus.parallel.flags &
			    V4L2_MBUS_PCLK_SAMPLE_RISING);

done:
	of_node_put(np);
	return pdata;
}

static int mt9v032_probe(struct i2c_client *client,
		const struct i2c_device_id *did)
{
	struct mt9v032_platform_data *pdata = client->dev.platform_data;
	struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client);
	struct mt9v032 *mt9v032;
	unsigned int i;
	int ret;
@@ -1037,9 +1088,25 @@ static const struct i2c_device_id mt9v032_id[] = {
};
MODULE_DEVICE_TABLE(i2c, mt9v032_id);

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id mt9v032_of_match[] = {
	{ .compatible = "aptina,mt9v022" },
	{ .compatible = "aptina,mt9v022m" },
	{ .compatible = "aptina,mt9v024" },
	{ .compatible = "aptina,mt9v024m" },
	{ .compatible = "aptina,mt9v032" },
	{ .compatible = "aptina,mt9v032m" },
	{ .compatible = "aptina,mt9v034" },
	{ .compatible = "aptina,mt9v034m" },
	{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, mt9v032_of_match);
#endif

static struct i2c_driver mt9v032_driver = {
	.driver = {
		.name = "mt9v032",
		.of_match_table = of_match_ptr(mt9v032_of_match),
	},
	.probe		= mt9v032_probe,
	.remove		= mt9v032_remove,