aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2014-07-05 18:26:22 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 18:34:45 -0400
commit47c71bd61b772cd72159dff4aae43734257a485a (patch)
tree9511f78c0482c90e76b5105edd300cabf9319cb2
parente9a1d94fa85542d4f3046ac82d234a3c8349c948 (diff)
[media] rcar_vin: add devicetree support
Add support for devicetree probe for the rcar-vin driver. Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> [g.liakhovetski@gmx.de fix a typo, sort headers alphabetically] Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--Documentation/devicetree/bindings/media/rcar_vin.txt86
-rw-r--r--drivers/media/platform/soc_camera/rcar_vin.c72
2 files changed, 151 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
new file mode 100644
index 000000000000..ba61782c2af9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -0,0 +1,86 @@
1Renesas RCar Video Input driver (rcar_vin)
2------------------------------------------
3
4The rcar_vin device provides video input capabilities for the Renesas R-Car
5family of devices. The current blocks are always slaves and suppot one input
6channel which can be either RGB, YUYV or BT656.
7
8 - compatible: Must be one of the following
9 - "renesas,vin-r8a7791" for the R8A7791 device
10 - "renesas,vin-r8a7790" for the R8A7790 device
11 - "renesas,vin-r8a7779" for the R8A7779 device
12 - "renesas,vin-r8a7778" for the R8A7778 device
13 - reg: the register base and size for the device registers
14 - interrupts: the interrupt for the device
15 - clocks: Reference to the parent clock
16
17Additionally, an alias named vinX will need to be created to specify
18which video input device this is.
19
20The per-board settings:
21 - port sub-node describing a single endpoint connected to the vin
22 as described in video-interfaces.txt[1]. Only the first one will
23 be considered as each vin interface has one input port.
24
25 These settings are used to work out video input format and widths
26 into the system.
27
28
29Device node example
30-------------------
31
32 aliases {
33 vin0 = &vin0;
34 };
35
36 vin0: vin@0xe6ef0000 {
37 compatible = "renesas,vin-r8a7790";
38 clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
39 reg = <0 0xe6ef0000 0 0x1000>;
40 interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
41 status = "disabled";
42 };
43
44Board setup example (vin1 composite video input)
45------------------------------------------------
46
47&i2c2 {
48 status = "ok";
49 pinctrl-0 = <&i2c2_pins>;
50 pinctrl-names = "default";
51
52 adv7180@20 {
53 compatible = "adi,adv7180";
54 reg = <0x20>;
55 remote = <&vin1>;
56
57 port {
58 adv7180: endpoint {
59 bus-width = <8>;
60 remote-endpoint = <&vin1ep0>;
61 };
62 };
63 };
64};
65
66/* composite video input */
67&vin1 {
68 pinctrl-0 = <&vin1_pins>;
69 pinctrl-names = "default";
70
71 status = "ok";
72
73 port {
74 #address-cells = <1>;
75 #size-cells = <0>;
76
77 vin1ep0: endpoint {
78 remote-endpoint = <&adv7180>;
79 bus-width = <8>;
80 };
81 };
82};
83
84
85
86[1] video-interfaces.txt common video media interface
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
index 7c4299d9a100..85d579f65f52 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -19,6 +19,8 @@
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_device.h>
22#include <linux/platform_data/camera-rcar.h> 24#include <linux/platform_data/camera-rcar.h>
23#include <linux/platform_device.h> 25#include <linux/platform_device.h>
24#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
@@ -31,6 +33,7 @@
31#include <media/v4l2-dev.h> 33#include <media/v4l2-dev.h>
32#include <media/v4l2-device.h> 34#include <media/v4l2-device.h>
33#include <media/v4l2-mediabus.h> 35#include <media/v4l2-mediabus.h>
36#include <media/v4l2-of.h>
34#include <media/v4l2-subdev.h> 37#include <media/v4l2-subdev.h>
35#include <media/videobuf2-dma-contig.h> 38#include <media/videobuf2-dma-contig.h>
36 39
@@ -1390,6 +1393,17 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
1390 .init_videobuf2 = rcar_vin_init_videobuf2, 1393 .init_videobuf2 = rcar_vin_init_videobuf2,
1391}; 1394};
1392 1395
1396#ifdef CONFIG_OF
1397static struct of_device_id rcar_vin_of_table[] = {
1398 { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
1399 { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
1400 { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
1401 { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
1402 { },
1403};
1404MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1405#endif
1406
1393static struct platform_device_id rcar_vin_id_table[] = { 1407static struct platform_device_id rcar_vin_id_table[] = {
1394 { "r8a7791-vin", RCAR_GEN2 }, 1408 { "r8a7791-vin", RCAR_GEN2 },
1395 { "r8a7790-vin", RCAR_GEN2 }, 1409 { "r8a7790-vin", RCAR_GEN2 },
@@ -1402,15 +1416,52 @@ MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1402 1416
1403static int rcar_vin_probe(struct platform_device *pdev) 1417static int rcar_vin_probe(struct platform_device *pdev)
1404{ 1418{
1419 const struct of_device_id *match = NULL;
1405 struct rcar_vin_priv *priv; 1420 struct rcar_vin_priv *priv;
1406 struct resource *mem; 1421 struct resource *mem;
1407 struct rcar_vin_platform_data *pdata; 1422 struct rcar_vin_platform_data *pdata;
1423 unsigned int pdata_flags;
1408 int irq, ret; 1424 int irq, ret;
1409 1425
1410 pdata = pdev->dev.platform_data; 1426 if (pdev->dev.of_node) {
1411 if (!pdata || !pdata->flags) { 1427 struct v4l2_of_endpoint ep;
1412 dev_err(&pdev->dev, "platform data not set\n"); 1428 struct device_node *np;
1413 return -EINVAL; 1429
1430 match = of_match_device(of_match_ptr(rcar_vin_of_table),
1431 &pdev->dev);
1432
1433 np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1434 if (!np) {
1435 dev_err(&pdev->dev, "could not find endpoint\n");
1436 return -EINVAL;
1437 }
1438
1439 ret = v4l2_of_parse_endpoint(np, &ep);
1440 if (ret) {
1441 dev_err(&pdev->dev, "could not parse endpoint\n");
1442 return ret;
1443 }
1444
1445 if (ep.bus_type == V4L2_MBUS_BT656)
1446 pdata_flags = RCAR_VIN_BT656;
1447 else {
1448 pdata_flags = 0;
1449 if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1450 pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
1451 if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1452 pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
1453 }
1454
1455 of_node_put(np);
1456
1457 dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1458 } else {
1459 pdata = pdev->dev.platform_data;
1460 if (!pdata || !pdata->flags) {
1461 dev_err(&pdev->dev, "platform data not set\n");
1462 return -EINVAL;
1463 }
1464 pdata_flags = pdata->flags;
1414 } 1465 }
1415 1466
1416 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1467 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1441,12 +1492,18 @@ static int rcar_vin_probe(struct platform_device *pdev)
1441 1492
1442 priv->ici.priv = priv; 1493 priv->ici.priv = priv;
1443 priv->ici.v4l2_dev.dev = &pdev->dev; 1494 priv->ici.v4l2_dev.dev = &pdev->dev;
1444 priv->ici.nr = pdev->id;
1445 priv->ici.drv_name = dev_name(&pdev->dev); 1495 priv->ici.drv_name = dev_name(&pdev->dev);
1446 priv->ici.ops = &rcar_vin_host_ops; 1496 priv->ici.ops = &rcar_vin_host_ops;
1447 1497
1448 priv->pdata_flags = pdata->flags; 1498 priv->pdata_flags = pdata_flags;
1449 priv->chip = pdev->id_entry->driver_data; 1499 if (!match) {
1500 priv->ici.nr = pdev->id;
1501 priv->chip = pdev->id_entry->driver_data;
1502 } else {
1503 priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1504 priv->chip = (enum chip_id)match->data;
1505 };
1506
1450 spin_lock_init(&priv->lock); 1507 spin_lock_init(&priv->lock);
1451 INIT_LIST_HEAD(&priv->capture); 1508 INIT_LIST_HEAD(&priv->capture);
1452 1509
@@ -1487,6 +1544,7 @@ static struct platform_driver rcar_vin_driver = {
1487 .driver = { 1544 .driver = {
1488 .name = DRV_NAME, 1545 .name = DRV_NAME,
1489 .owner = THIS_MODULE, 1546 .owner = THIS_MODULE,
1547 .of_match_table = of_match_ptr(rcar_vin_of_table),
1490 }, 1548 },
1491 .id_table = rcar_vin_id_table, 1549 .id_table = rcar_vin_id_table,
1492}; 1550};