Commit e781bbe3 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] exynos4-is: Add fimc-is subdevs registration

This patch adds support for registration of the FIMC-IS device
represented by the FIMC-IS-ISP subdev to the top level media device
driver. The FIMC-IS subsystem is available on Exynos4x12 SoCs which
support only device tree based booting.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 0580abc2
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "media-dev.h" #include "media-dev.h"
#include "fimc-core.h" #include "fimc-core.h"
#include "fimc-is.h"
#include "fimc-lite.h" #include "fimc-lite.h"
#include "mipi-csis.h" #include "mipi-csis.h"
...@@ -85,9 +86,11 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p, ...@@ -85,9 +86,11 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
case GRP_ID_FIMC: case GRP_ID_FIMC:
/* No need to control FIMC subdev through subdev ops */ /* No need to control FIMC subdev through subdev ops */
break; break;
case GRP_ID_FIMC_IS:
p->subdevs[IDX_IS_ISP] = sd;
break;
default: default:
pr_warn("%s: Unknown subdev grp_id: %#x\n", break;
__func__, sd->grp_id);
} }
me = &sd->entity; me = &sd->entity;
if (me->num_pads == 1) if (me->num_pads == 1)
...@@ -322,6 +325,7 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) ...@@ -322,6 +325,7 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
if (!client) if (!client)
return; return;
v4l2_device_unregister_subdev(sd); v4l2_device_unregister_subdev(sd);
if (!client->dev.of_node) { if (!client->dev.of_node) {
...@@ -372,7 +376,11 @@ static int fimc_md_of_add_sensor(struct fimc_md *fmd, ...@@ -372,7 +376,11 @@ static int fimc_md_of_add_sensor(struct fimc_md *fmd,
goto mod_put; goto mod_put;
v4l2_set_subdev_hostdata(sd, si); v4l2_set_subdev_hostdata(sd, si);
if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
sd->grp_id = GRP_ID_FIMC_IS_SENSOR;
else
sd->grp_id = GRP_ID_SENSOR; sd->grp_id = GRP_ID_SENSOR;
si->subdev = sd; si->subdev = sd;
v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n", v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
sd->name, fmd->num_sensors); sd->name, fmd->num_sensors);
...@@ -652,6 +660,22 @@ static int register_csis_entity(struct fimc_md *fmd, ...@@ -652,6 +660,22 @@ static int register_csis_entity(struct fimc_md *fmd,
return ret; return ret;
} }
static int register_fimc_is_entity(struct fimc_md *fmd, struct fimc_is *is)
{
struct v4l2_subdev *sd = &is->isp.subdev;
int ret;
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
if (ret) {
v4l2_err(&fmd->v4l2_dev,
"Failed to register FIMC-ISP (%d)\n", ret);
return ret;
}
fmd->fimc_is = is;
return 0;
}
static int fimc_md_register_platform_entity(struct fimc_md *fmd, static int fimc_md_register_platform_entity(struct fimc_md *fmd,
struct platform_device *pdev, struct platform_device *pdev,
int plat_entity) int plat_entity)
...@@ -679,6 +703,9 @@ static int fimc_md_register_platform_entity(struct fimc_md *fmd, ...@@ -679,6 +703,9 @@ static int fimc_md_register_platform_entity(struct fimc_md *fmd,
case IDX_CSIS: case IDX_CSIS:
ret = register_csis_entity(fmd, pdev, drvdata); ret = register_csis_entity(fmd, pdev, drvdata);
break; break;
case IDX_IS_ISP:
ret = register_fimc_is_entity(fmd, drvdata);
break;
default: default:
ret = -ENODEV; ret = -ENODEV;
} }
...@@ -742,6 +769,8 @@ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd, ...@@ -742,6 +769,8 @@ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd,
/* If driver of any entity isn't ready try all again later. */ /* If driver of any entity isn't ready try all again later. */
if (!strcmp(node->name, CSIS_OF_NODE_NAME)) if (!strcmp(node->name, CSIS_OF_NODE_NAME))
plat_entity = IDX_CSIS; plat_entity = IDX_CSIS;
else if (!strcmp(node->name, FIMC_IS_OF_NODE_NAME))
plat_entity = IDX_IS_ISP;
else if (!strcmp(node->name, FIMC_LITE_OF_NODE_NAME)) else if (!strcmp(node->name, FIMC_LITE_OF_NODE_NAME))
plat_entity = IDX_FLITE; plat_entity = IDX_FLITE;
else if (!strcmp(node->name, FIMC_OF_NODE_NAME) && else if (!strcmp(node->name, FIMC_OF_NODE_NAME) &&
...@@ -1308,6 +1337,8 @@ static int fimc_md_probe(struct platform_device *pdev) ...@@ -1308,6 +1337,8 @@ static int fimc_md_probe(struct platform_device *pdev)
v4l2_dev->notify = fimc_sensor_notify; v4l2_dev->notify = fimc_sensor_notify;
strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name));
fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
ret = v4l2_device_register(dev, &fmd->v4l2_dev); ret = v4l2_device_register(dev, &fmd->v4l2_dev);
if (ret < 0) { if (ret < 0) {
v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <media/media-device.h> #include <media/media-device.h>
#include <media/media-entity.h> #include <media/media-entity.h>
...@@ -80,6 +81,7 @@ struct fimc_sensor_info { ...@@ -80,6 +81,7 @@ struct fimc_sensor_info {
* @num_sensors: actual number of registered sensors * @num_sensors: actual number of registered sensors
* @camclk: external sensor clock information * @camclk: external sensor clock information
* @fimc: array of registered fimc devices * @fimc: array of registered fimc devices
* @fimc_is: fimc-is data structure
* @use_isp: set to true when FIMC-IS subsystem is used * @use_isp: set to true when FIMC-IS subsystem is used
* @pmf: handle to the CAMCLK clock control FIMC helper device * @pmf: handle to the CAMCLK clock control FIMC helper device
* @media_dev: top level media device * @media_dev: top level media device
...@@ -99,6 +101,7 @@ struct fimc_md { ...@@ -99,6 +101,7 @@ struct fimc_md {
struct clk *wbclk[FIMC_MAX_WBCLKS]; struct clk *wbclk[FIMC_MAX_WBCLKS];
struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS]; struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
struct fimc_dev *fimc[FIMC_MAX_DEVS]; struct fimc_dev *fimc[FIMC_MAX_DEVS];
struct fimc_is *fimc_is;
bool use_isp; bool use_isp;
struct device *pmf; struct device *pmf;
struct media_device media_dev; struct media_device media_dev;
...@@ -139,4 +142,14 @@ static inline void fimc_md_graph_unlock(struct fimc_dev *fimc) ...@@ -139,4 +142,14 @@ static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
#ifdef CONFIG_OF
static inline bool fimc_md_is_isp_available(struct device_node *node)
{
node = of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);
return node ? of_device_is_available(node) : false;
}
#else
#define fimc_md_is_isp_available(node) (false)
#endif /* CONFIG_OF */
#endif #endif
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