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

[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
* 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>;
};
};
};
...@@ -6535,6 +6535,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> ...@@ -6535,6 +6535,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git T: git git://linuxtv.org/media_tree.git
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/media/i2c/mt9v032.txt
F: drivers/media/i2c/mt9v032.c F: drivers/media/i2c/mt9v032.c
F: include/media/mt9v032.h F: include/media/mt9v032.h
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
...@@ -26,6 +28,7 @@ ...@@ -26,6 +28,7 @@
#include <media/mt9v032.h> #include <media/mt9v032.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h> #include <media/v4l2-subdev.h>
/* The first four rows are black rows. The active area spans 753x481 pixels. */ /* 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 = { ...@@ -876,10 +879,58 @@ static const struct regmap_config mt9v032_regmap_config = {
* Driver initialization and probing * 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, static int mt9v032_probe(struct i2c_client *client,
const struct i2c_device_id *did) 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; struct mt9v032 *mt9v032;
unsigned int i; unsigned int i;
int ret; int ret;
...@@ -1037,9 +1088,25 @@ static const struct i2c_device_id mt9v032_id[] = { ...@@ -1037,9 +1088,25 @@ static const struct i2c_device_id mt9v032_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, 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 = { static struct i2c_driver mt9v032_driver = {
.driver = { .driver = {
.name = "mt9v032", .name = "mt9v032",
.of_match_table = of_match_ptr(mt9v032_of_match),
}, },
.probe = mt9v032_probe, .probe = mt9v032_probe,
.remove = mt9v032_remove, .remove = mt9v032_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment