diff options
author | Ben Dooks <ben.dooks@codethink.co.uk> | 2014-07-05 18:26:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-07-30 18:34:45 -0400 |
commit | 47c71bd61b772cd72159dff4aae43734257a485a (patch) | |
tree | 9511f78c0482c90e76b5105edd300cabf9319cb2 /drivers/media | |
parent | e9a1d94fa85542d4f3046ac82d234a3c8349c948 (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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/soc_camera/rcar_vin.c | 72 |
1 files changed, 65 insertions, 7 deletions
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 | ||
1397 | static 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 | }; | ||
1404 | MODULE_DEVICE_TABLE(of, rcar_vin_of_table); | ||
1405 | #endif | ||
1406 | |||
1393 | static struct platform_device_id rcar_vin_id_table[] = { | 1407 | static 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 | ||
1403 | static int rcar_vin_probe(struct platform_device *pdev) | 1417 | static 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 | }; |