[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1560280855-18085-4-git-send-email-luis.oliveira@synopsys.com>
Date: Tue, 11 Jun 2019 21:20:52 +0200
From: Luis Oliveira <Luis.Oliveira@...opsys.com>
To: mchehab@...nel.org, davem@...emloft.net,
gregkh@...uxfoundation.org, Jonathan.Cameron@...wei.com,
robh@...nel.org, nicolas.ferre@...rochip.com,
paulmck@...ux.ibm.com, mark.rutland@....com, kishon@...com,
devicetree@...r.kernel.org, linux-media@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: Joao.Pinto@...opsys.com, Luis Oliveira <Luis.Oliveira@...opsys.com>
Subject: [v4 3/6] media: platform: dwc: Add MIPI CSI-2 platform data
This allows the driver loading via platform data which makes the driver
not device tree dependent.
Signed-off-by: Luis Oliveira <luis.oliveira@...opsys.com>
---
Changelog
v3-v4
- not present on v3, allows configuration using pdata
MAINTAINERS | 1 +
drivers/media/platform/dwc/dw-csi-plat.c | 105 +++++++++++++++++++++----------
include/media/dwc/dw-csi-data.h | 26 ++++++++
3 files changed, 100 insertions(+), 32 deletions(-)
create mode 100644 include/media/dwc/dw-csi-data.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 6ffe4fd..2df1f7c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15193,6 +15193,7 @@ L: linux-media@...r.kernel.org
T: git git://linuxtv.org/media_tree.git
S: Maintained
F: drivers/media/platform/dwc
+F: include/media/dwc/dw-csi-data.h
F: Documentation/devicetree/bindings/media/snps,dw-csi.txt
SYNOPSYS DESIGNWARE DMAC DRIVER
diff --git a/drivers/media/platform/dwc/dw-csi-plat.c b/drivers/media/platform/dwc/dw-csi-plat.c
index 9828d55..c7117c6 100644
--- a/drivers/media/platform/dwc/dw-csi-plat.c
+++ b/drivers/media/platform/dwc/dw-csi-plat.c
@@ -8,6 +8,7 @@
* Author: Luis Oliveira <luis.oliveira@...opsys.com>
*/
+#include <media/dwc/dw-csi-data.h>
#include <media/dwc/dw-dphy-data.h>
#include "dw-csi-plat.h"
@@ -312,12 +313,16 @@ static const struct of_device_id dw_mipi_csi_of_match[];
static int dw_csi_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id = NULL;
+ struct dw_csih_pdata *pdata;
struct device *dev = &pdev->dev;
struct resource *res = NULL;
struct dw_csi *csi;
struct v4l2_subdev *sd;
int ret;
+ if (!IS_ENABLED(CONFIG_OF))
+ pdata = pdev->dev.platform_data;
+
dev_vdbg(dev, "Probing started\n");
/* Resource allocation */
@@ -329,18 +334,29 @@ static int dw_csi_probe(struct platform_device *pdev)
spin_lock_init(&csi->slock);
csi->dev = dev;
- of_id = of_match_node(dw_mipi_csi_of_match, dev->of_node);
- if (!of_id)
- return -EINVAL;
+ if (dev->of_node) {
+ of_id = of_match_node(dw_mipi_csi_of_match, dev->of_node);
+ if (!of_id)
+ return -EINVAL;
- ret = dw_mipi_csi_parse_dt(pdev, csi);
- if (ret < 0)
- return ret;
+ ret = dw_mipi_csi_parse_dt(pdev, csi);
+ if (ret < 0)
+ return ret;
- csi->phy = devm_of_phy_get(dev, dev->of_node, NULL);
- if (IS_ERR(csi->phy)) {
- dev_err(dev, "No DPHY available\n");
- return PTR_ERR(csi->phy);
+ csi->phy = devm_of_phy_get(dev, dev->of_node, NULL);
+ if (IS_ERR(csi->phy)) {
+ dev_err(dev, "No DPHY available\n");
+ return PTR_ERR(csi->phy);
+ }
+ } else {
+ csi->phy = devm_phy_get(dev, phys[pdata->id].name);
+ if (IS_ERR(csi->phy)) {
+ dev_err(dev, "No '%s' DPHY available\n",
+ phys[pdata->id].name);
+ return PTR_ERR(csi->phy);
+ }
+ dev_vdbg(dev, "got D-PHY %s with id %d\n", phys[pdata->id].name,
+ csi->phy->id);
}
/* Registers mapping */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -370,7 +386,10 @@ static int dw_csi_probe(struct platform_device *pdev)
dw_mipi_csi_irq1, IRQF_SHARED,
dev_name(dev), csi);
if (ret) {
- dev_err(dev, "irq csi %s failed\n", of_id->name);
+ if (dev->of_node)
+ dev_err(dev, "irq csi %s failed\n", of_id->name);
+ else
+ dev_err(dev, "irq csi %d failed\n", pdata->id);
goto end;
}
@@ -379,25 +398,44 @@ static int dw_csi_probe(struct platform_device *pdev)
v4l2_subdev_init(sd, &dw_mipi_csi_subdev_ops);
csi->sd.owner = THIS_MODULE;
- snprintf(sd->name, sizeof(sd->name), "%s.%d",
- "dw-csi", csi->index);
+ if (dev->of_node) {
+ snprintf(sd->name, sizeof(sd->name), "%s.%d",
+ "dw-csi", csi->index);
- csi->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ csi->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ } else {
+ strlcpy(sd->name, dev_name(dev), sizeof(sd->name));
+ strlcpy(csi->v4l2_dev.name, dev_name(dev),
+ sizeof(csi->v4l2_dev.name));
+ }
csi->fmt = &dw_mipi_csi_formats[0];
csi->format.code = dw_mipi_csi_formats[0].mbus_code;
sd->entity.function = MEDIA_ENT_F_IO_V4L;
- csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&csi->sd.entity,
- CSI_PADS_NUM, csi->pads);
- dev_vdbg(dev, "v4l2.name: %s\n", csi->v4l2_dev.name);
+ if (dev->of_node) {
+ csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- if (ret < 0) {
- dev_err(dev, "media entity init failed\n");
- goto end;
+ ret = media_entity_pads_init(&csi->sd.entity,
+ CSI_PADS_NUM, csi->pads);
+ if (ret < 0) {
+ dev_err(dev, "media entity init failed\n");
+ goto end;
+ }
+ } else {
+ csi->hw.num_lanes = pdata->lanes;
+ csi->hw.pclk = pdata->pclk;
+ csi->hw.fps = pdata->fps;
+ csi->hw.dphy_freq = pdata->hs_freq;
+
+ ret = v4l2_device_register(NULL, &csi->v4l2_dev);
+ if (ret) {
+ dev_err(dev, "failed to register v4l2 device\n");
+ goto end;
+ }
}
+ dev_vdbg(dev, "v4l2.name: %s\n", csi->v4l2_dev.name);
v4l2_set_subdevdata(&csi->sd, pdev);
platform_set_drvdata(pdev, &csi->sd);
@@ -405,6 +443,7 @@ static int dw_csi_probe(struct platform_device *pdev)
if (csi->rst)
reset_control_deassert(csi->rst);
+
#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
dw_csi_create_capabilities_sysfs(pdev);
#endif
@@ -418,11 +457,12 @@ static int dw_csi_probe(struct platform_device *pdev)
phy_init(csi->phy);
return 0;
-
end:
+#if IS_ENABLED(CONFIG_OF)
media_entity_cleanup(&csi->sd.entity);
+ return ret;
+#endif
v4l2_device_unregister(csi->vdev.v4l2_dev);
-
return ret;
}
@@ -436,35 +476,36 @@ static int dw_csi_remove(struct platform_device *pdev)
struct v4l2_subdev *sd = platform_get_drvdata(pdev);
struct dw_csi *mipi_csi = sd_to_mipi_csi_dev(sd);
- dev_dbg(&pdev->dev, "Removing MIPI CSI-2 module\n");
+ dev_dbg(&pdev->dev, "Removing DW MIPI CSI-2 Host module\n");
if (mipi_csi->rst)
reset_control_assert(mipi_csi->rst);
+#if IS_ENABLED(CONFIG_OF)
media_entity_cleanup(&mipi_csi->sd.entity);
-
+#else
+ v4l2_device_unregister(mipi_csi->vdev.v4l2_dev);
+#endif
return 0;
}
-/**
- * @short of_device_id structure
- */
+#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id dw_mipi_csi_of_match[] = {
{ .compatible = "snps,dw-csi" },
{},
};
MODULE_DEVICE_TABLE(of, dw_mipi_csi_of_match);
+#endif
-/**
- * @short Platform driver structure
- */
static struct platform_driver dw_mipi_csi_driver = {
.remove = dw_csi_remove,
.probe = dw_csi_probe,
.driver = {
.name = "dw-csi",
.owner = THIS_MODULE,
+#if IS_ENABLED(CONFIG_OF)
.of_match_table = of_match_ptr(dw_mipi_csi_of_match),
+#endif
},
};
diff --git a/include/media/dwc/dw-csi-data.h b/include/media/dwc/dw-csi-data.h
new file mode 100644
index 0000000..87942ab
--- /dev/null
+++ b/include/media/dwc/dw-csi-data.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates.
+ *
+ * Synopsys DesignWare MIPI CSI-2 platform data
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@...opsys.com>
+ */
+
+#include <linux/kernel.h>
+#include <media/dwc/dw-mipi-csi-pltfrm.h>
+
+struct dw_csih_pdata {
+ u8 eotp_enabled;
+ u32 hs_freq;
+ u32 lanes;
+ u32 pclk;
+ u32 fps;
+ u32 bpp;
+ u8 id;
+};
+
+static const struct pdata_names csis[] = {
+ { .name = "dw-csi.0", },
+ { .name = "dw-csi.1", },
+};
--
2.7.4
Powered by blists - more mailing lists