[go: nahoru, domu]

126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart/*
226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * vsp1_entity.c  --  R-Car VSP1 Base Entity
326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart *
48a1edc55c1ec1ff3624c25b4ac6c1ce776d872b8Laurent Pinchart * Copyright (C) 2013-2014 Renesas Electronics Corporation
526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart *
626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart *
826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * This program is free software; you can redistribute it and/or modify
926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * it under the terms of the GNU General Public License as published by
1026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * the Free Software Foundation; either version 2 of the License, or
1126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * (at your option) any later version.
1226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart */
1326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
1426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart#include <linux/device.h>
1526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart#include <linux/gfp.h>
1626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
1726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart#include <media/media-entity.h>
18a626e64e0bee4fb26848dbed92223dde488f3d93Laurent Pinchart#include <media/v4l2-ctrls.h>
1926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart#include <media/v4l2-subdev.h>
2026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
2126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart#include "vsp1.h"
2226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart#include "vsp1_entity.h"
231499be67a545fb6f41acb5614b8e4732147cec50Laurent Pinchart#include "vsp1_video.h"
2426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
25960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchartbool vsp1_entity_is_streaming(struct vsp1_entity *entity)
26960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart{
27960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	bool streaming;
28960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
29960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	mutex_lock(&entity->lock);
30960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	streaming = entity->streaming;
31960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	mutex_unlock(&entity->lock);
32960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
33960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	return streaming;
34960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart}
35960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
36960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchartint vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming)
37960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart{
38960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	int ret;
39960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
40960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	mutex_lock(&entity->lock);
41960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	entity->streaming = streaming;
42960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	mutex_unlock(&entity->lock);
43960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
44960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	if (!streaming)
45960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart		return 0;
46960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
47960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	if (!entity->subdev.ctrl_handler)
48960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart		return 0;
49960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
50960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	ret = v4l2_ctrl_handler_setup(entity->subdev.ctrl_handler);
51960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	if (ret < 0) {
52960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart		mutex_lock(&entity->lock);
53960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart		entity->streaming = false;
54960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart		mutex_unlock(&entity->lock);
55960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	}
56960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
57960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	return ret;
58960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart}
59960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
6026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart/* -----------------------------------------------------------------------------
6126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * V4L2 Subdevice Operations
6226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart */
6326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
6426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartstruct v4l2_mbus_framefmt *
6526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartvsp1_entity_get_pad_format(struct vsp1_entity *entity,
6626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			   struct v4l2_subdev_fh *fh,
6726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			   unsigned int pad, u32 which)
6826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart{
6926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	switch (which) {
7026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	case V4L2_SUBDEV_FORMAT_TRY:
7126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return v4l2_subdev_get_try_format(fh, pad);
7226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	case V4L2_SUBDEV_FORMAT_ACTIVE:
7326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return &entity->formats[pad];
7426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	default:
7526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return NULL;
7626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	}
7726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart}
7826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
7926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart/*
8026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * vsp1_entity_init_formats - Initialize formats on all pads
8126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * @subdev: V4L2 subdevice
8226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * @fh: V4L2 subdev file handle
8326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart *
8426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * Initialize all pad formats with default values. If fh is not NULL, try
8526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * formats are initialized on the file handle. Otherwise active formats are
8626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * initialized on the device.
8726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart */
8826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartvoid vsp1_entity_init_formats(struct v4l2_subdev *subdev,
8926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			    struct v4l2_subdev_fh *fh)
9026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart{
9126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	struct v4l2_subdev_format format;
9226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	unsigned int pad;
9326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
9426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) {
9526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		memset(&format, 0, sizeof(format));
9626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
9726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		format.pad = pad;
9826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		format.which = fh ? V4L2_SUBDEV_FORMAT_TRY
9926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			     : V4L2_SUBDEV_FORMAT_ACTIVE;
10026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
10126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		v4l2_subdev_call(subdev, pad, set_fmt, fh, &format);
10226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	}
10326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart}
10426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
10526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartstatic int vsp1_entity_open(struct v4l2_subdev *subdev,
10626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			    struct v4l2_subdev_fh *fh)
10726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart{
10826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	vsp1_entity_init_formats(subdev, fh);
10926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
11026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	return 0;
11126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart}
11226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
11326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartconst struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops = {
11426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	.open = vsp1_entity_open,
11526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart};
11626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
11726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart/* -----------------------------------------------------------------------------
11826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * Media Operations
11926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart */
12026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
12126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartstatic int vsp1_entity_link_setup(struct media_entity *entity,
12226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart				  const struct media_pad *local,
12326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart				  const struct media_pad *remote, u32 flags)
12426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart{
12526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	struct vsp1_entity *source;
12626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
12726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	if (!(local->flags & MEDIA_PAD_FL_SOURCE))
12826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return 0;
12926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
13026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	source = container_of(local->entity, struct vsp1_entity, subdev.entity);
13126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
13226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	if (!source->route)
13326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return 0;
13426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
13526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	if (flags & MEDIA_LNK_FL_ENABLED) {
13626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		if (source->sink)
13726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			return -EBUSY;
13826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		source->sink = remote->entity;
139d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart		source->sink_pad = remote->index;
14026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	} else {
14126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		source->sink = NULL;
142d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart		source->sink_pad = 0;
14326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	}
14426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
14526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	return 0;
14626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart}
14726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
14826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartconst struct media_entity_operations vsp1_media_ops = {
14926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	.link_setup = vsp1_entity_link_setup,
15026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	.link_validate = v4l2_subdev_link_validate,
15126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart};
15226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
15326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart/* -----------------------------------------------------------------------------
15426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart * Initialization
15526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart */
15626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
157d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchartstatic const struct vsp1_route vsp1_routes[] = {
158629bb6d4b38fe62d36ab52ad22c3ab726f6ce6e8Laurent Pinchart	{ VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
159629bb6d4b38fe62d36ab52ad22c3ab726f6ce6e8Laurent Pinchart	  { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
160629bb6d4b38fe62d36ab52ad22c3ab726f6ce6e8Laurent Pinchart	    VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), } },
161d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_HSI, 0, VI6_DPR_HSI_ROUTE, { VI6_DPR_NODE_HSI, } },
162d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_HST, 0, VI6_DPR_HST_ROUTE, { VI6_DPR_NODE_HST, } },
163d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, } },
164d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_LUT, 0, VI6_DPR_LUT_ROUTE, { VI6_DPR_NODE_LUT, } },
165d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_RPF, 0, VI6_DPR_RPF_ROUTE(0), { VI6_DPR_NODE_RPF(0), } },
166d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_RPF, 1, VI6_DPR_RPF_ROUTE(1), { VI6_DPR_NODE_RPF(1), } },
167d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_RPF, 2, VI6_DPR_RPF_ROUTE(2), { VI6_DPR_NODE_RPF(2), } },
168d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_RPF, 3, VI6_DPR_RPF_ROUTE(3), { VI6_DPR_NODE_RPF(3), } },
169d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_RPF, 4, VI6_DPR_RPF_ROUTE(4), { VI6_DPR_NODE_RPF(4), } },
170d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_SRU, 0, VI6_DPR_SRU_ROUTE, { VI6_DPR_NODE_SRU, } },
171d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_UDS, 0, VI6_DPR_UDS_ROUTE(0), { VI6_DPR_NODE_UDS(0), } },
172d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_UDS, 1, VI6_DPR_UDS_ROUTE(1), { VI6_DPR_NODE_UDS(1), } },
173d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_UDS, 2, VI6_DPR_UDS_ROUTE(2), { VI6_DPR_NODE_UDS(2), } },
174d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_WPF, 0, 0, { VI6_DPR_NODE_WPF(0), } },
175d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_WPF, 1, 0, { VI6_DPR_NODE_WPF(1), } },
176d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_WPF, 2, 0, { VI6_DPR_NODE_WPF(2), } },
177d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	{ VSP1_ENTITY_WPF, 3, 0, { VI6_DPR_NODE_WPF(3), } },
178d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart};
179d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart
18026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartint vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
18126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		     unsigned int num_pads)
18226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart{
18326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	unsigned int i;
18426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
185d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	for (i = 0; i < ARRAY_SIZE(vsp1_routes); ++i) {
186d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart		if (vsp1_routes[i].type == entity->type &&
187d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart		    vsp1_routes[i].index == entity->index) {
188d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart			entity->route = &vsp1_routes[i];
18926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart			break;
19026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		}
19126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	}
19226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
193d9b45ed3d8b75e8cf38c8cd1563c29217eecba27Laurent Pinchart	if (i == ARRAY_SIZE(vsp1_routes))
19426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return -EINVAL;
19526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
196960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	mutex_init(&entity->lock);
197960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
19826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	entity->vsp1 = vsp1;
19926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	entity->source_pad = num_pads - 1;
20026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
20126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	/* Allocate formats and pads. */
20226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	entity->formats = devm_kzalloc(vsp1->dev,
20326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart				       num_pads * sizeof(*entity->formats),
20426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart				       GFP_KERNEL);
20526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	if (entity->formats == NULL)
20626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return -ENOMEM;
20726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
20826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads),
20926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart				    GFP_KERNEL);
21026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	if (entity->pads == NULL)
21126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		return -ENOMEM;
21226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
21326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	/* Initialize pads. */
21426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	for (i = 0; i < num_pads - 1; ++i)
21526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart		entity->pads[i].flags = MEDIA_PAD_FL_SINK;
21626e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
21726e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE;
21826e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
21926e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	/* Initialize the media entity. */
22026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	return media_entity_init(&entity->subdev.entity, num_pads,
22126e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart				 entity->pads, 0);
22226e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart}
22326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart
22426e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchartvoid vsp1_entity_destroy(struct vsp1_entity *entity)
22526e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart{
2261499be67a545fb6f41acb5614b8e4732147cec50Laurent Pinchart	if (entity->video)
2271499be67a545fb6f41acb5614b8e4732147cec50Laurent Pinchart		vsp1_video_cleanup(entity->video);
228a626e64e0bee4fb26848dbed92223dde488f3d93Laurent Pinchart	if (entity->subdev.ctrl_handler)
229a626e64e0bee4fb26848dbed92223dde488f3d93Laurent Pinchart		v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
23026e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart	media_entity_cleanup(&entity->subdev.entity);
231960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart
232960de2cff49a4e5f45e6a60175f4298cc34dc526Laurent Pinchart	mutex_destroy(&entity->lock);
23326e0ca22c3b85b04f693dd0422f13a61846ccfa9Laurent Pinchart}
234