#include "media-dev.h"
#include "fimc-core.h"
+#include "fimc-is.h"
#include "fimc-lite.h"
#include "mipi-csis.h"
case GRP_ID_FIMC:
/* No need to control FIMC subdev through subdev ops */
break;
+ case GRP_ID_FIMC_IS:
+ p->subdevs[IDX_IS_ISP] = sd;
+ break;
default:
- pr_warn("%s: Unknown subdev grp_id: %#x\n",
- __func__, sd->grp_id);
+ break;
}
me = &sd->entity;
if (me->num_pads == 1)
if (!client)
return;
+
v4l2_device_unregister_subdev(sd);
if (!client->dev.of_node) {
goto mod_put;
v4l2_set_subdev_hostdata(sd, si);
- sd->grp_id = GRP_ID_SENSOR;
+ 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;
+
si->subdev = sd;
v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
sd->name, fmd->num_sensors);
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,
struct platform_device *pdev,
int plat_entity)
case IDX_CSIS:
ret = register_csis_entity(fmd, pdev, drvdata);
break;
+ case IDX_IS_ISP:
+ ret = register_fimc_is_entity(fmd, drvdata);
+ break;
default:
ret = -ENODEV;
}
/* If driver of any entity isn't ready try all again later. */
if (!strcmp(node->name, CSIS_OF_NODE_NAME))
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))
plat_entity = IDX_FLITE;
else if (!strcmp(node->name, FIMC_OF_NODE_NAME) &&
v4l2_dev->notify = fimc_sensor_notify;
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);
if (ret < 0) {
v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <media/media-device.h>
#include <media/media-entity.h>
* @num_sensors: actual number of registered sensors
* @camclk: external sensor clock information
* @fimc: array of registered fimc devices
+ * @fimc_is: fimc-is data structure
* @use_isp: set to true when FIMC-IS subsystem is used
* @pmf: handle to the CAMCLK clock control FIMC helper device
* @media_dev: top level media device
struct clk *wbclk[FIMC_MAX_WBCLKS];
struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
struct fimc_dev *fimc[FIMC_MAX_DEVS];
+ struct fimc_is *fimc_is;
bool use_isp;
struct device *pmf;
struct media_device media_dev;
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