Skip to content

Commit

Permalink
[media] media: atmel-isi: add primary DT support
Browse files Browse the repository at this point in the history
This patch add the DT support for Atmel ISI driver.
It use the same v4l2 DT interface that defined in video-interfaces.txt.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
Cc: devicetree@vger.kernel.org
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
  • Loading branch information
Josh Wu authored and Mauro Carvalho Chehab committed Jul 30, 2014
1 parent 833e106 commit 8ff19bc
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 2 deletions.
51 changes: 51 additions & 0 deletions Documentation/devicetree/bindings/media/atmel-isi.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Atmel Image Sensor Interface (ISI) SoC Camera Subsystem
----------------------------------------------

Required properties:
- compatible: must be "atmel,at91sam9g45-isi"
- reg: physical base address and length of the registers set for the device;
- interrupts: should contain IRQ line for the ISI;
- clocks: list of clock specifiers, corresponding to entries in
the clock-names property;
- clock-names: must contain "isi_clk", which is the isi peripherial clock.

ISI supports a single port node with parallel bus. It should contain one
'port' child node with child 'endpoint' node. Please refer to the bindings
defined in Documentation/devicetree/bindings/media/video-interfaces.txt.

Example:
isi: isi@f0034000 {
compatible = "atmel,at91sam9g45-isi";
reg = <0xf0034000 0x4000>;
interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>;

clocks = <&isi_clk>;
clock-names = "isi_clk";

pinctrl-names = "default";
pinctrl-0 = <&pinctrl_isi>;

port {
#address-cells = <1>;
#size-cells = <0>;

isi_0: endpoint {
remote-endpoint = <&ov2640_0>;
bus-width = <8>;
};
};
};

i2c1: i2c@f0018000 {
ov2640: camera@0x30 {
compatible = "omnivision,ov2640";
reg = <0x30>;

port {
ov2640_0: endpoint {
remote-endpoint = <&isi_0>;
bus-width = <8>;
};
};
};
};
65 changes: 63 additions & 2 deletions drivers/media/platform/soc_camera/atmel-isi.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <media/atmel-isi.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <media/v4l2-of.h>
#include <media/videobuf2-dma-contig.h>

#define MAX_BUFFER_NUM 32
Expand All @@ -33,6 +34,7 @@
#define VID_LIMIT_BYTES (16 * 1024 * 1024)
#define MIN_FRAME_RATE 15
#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
#define ISI_DEFAULT_MCLK_FREQ 25000000

/* Frame buffer descriptor */
struct fbd {
Expand Down Expand Up @@ -876,6 +878,51 @@ static int atmel_isi_remove(struct platform_device *pdev)
return 0;
}

static int atmel_isi_probe_dt(struct atmel_isi *isi,
struct platform_device *pdev)
{
struct device_node *np= pdev->dev.of_node;
struct v4l2_of_endpoint ep;
int err;

/* Default settings for ISI */
isi->pdata.full_mode = 1;
isi->pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ;
isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;

np = of_graph_get_next_endpoint(np, NULL);
if (!np) {
dev_err(&pdev->dev, "Could not find the endpoint\n");
return -EINVAL;
}

err = v4l2_of_parse_endpoint(np, &ep);
if (err) {
dev_err(&pdev->dev, "Could not parse the endpoint\n");
goto err_probe_dt;
}

switch (ep.bus.parallel.bus_width) {
case 8:
isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
break;
case 10:
isi->pdata.data_width_flags =
ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
break;
default:
dev_err(&pdev->dev, "Unsupported bus width: %d\n",
ep.bus.parallel.bus_width);
err = -EINVAL;
goto err_probe_dt;
}

err_probe_dt:
of_node_put(np);

return err;
}

static int atmel_isi_probe(struct platform_device *pdev)
{
unsigned int irq;
Expand All @@ -887,7 +934,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
struct isi_platform_data *pdata;

pdata = dev->platform_data;
if (!pdata || !pdata->data_width_flags) {
if ((!pdata || !pdata->data_width_flags) && !pdev->dev.of_node) {
dev_err(&pdev->dev,
"No config available for Atmel ISI\n");
return -EINVAL;
Expand All @@ -903,7 +950,14 @@ static int atmel_isi_probe(struct platform_device *pdev)
if (IS_ERR(isi->pclk))
return PTR_ERR(isi->pclk);

memcpy(&isi->pdata, pdata, sizeof(isi->pdata));
if (pdata) {
memcpy(&isi->pdata, pdata, sizeof(isi->pdata));
} else {
ret = atmel_isi_probe_dt(isi, pdev);
if (ret)
return ret;
}

isi->active = NULL;
spin_lock_init(&isi->lock);
INIT_LIST_HEAD(&isi->video_buffer_list);
Expand Down Expand Up @@ -1005,11 +1059,18 @@ static int atmel_isi_probe(struct platform_device *pdev)
return ret;
}

static const struct of_device_id atmel_isi_of_match[] = {
{ .compatible = "atmel,at91sam9g45-isi" },
{ }
};
MODULE_DEVICE_TABLE(of, atmel_isi_of_match);

static struct platform_driver atmel_isi_driver = {
.remove = atmel_isi_remove,
.driver = {
.name = "atmel_isi",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(atmel_isi_of_match),
},
};

Expand Down

0 comments on commit 8ff19bc

Please sign in to comment.