summaryrefslogtreecommitdiff
path: root/isp/omap3isp.c
diff options
context:
space:
mode:
Diffstat (limited to 'isp/omap3isp.c')
-rw-r--r--isp/omap3isp.c183
1 files changed, 91 insertions, 92 deletions
diff --git a/isp/omap3isp.c b/isp/omap3isp.c
index 6abcac5..8a5acc8 100644
--- a/isp/omap3isp.c
+++ b/isp/omap3isp.c
@@ -68,26 +68,6 @@ static int setup_link(struct omap3_isp_device *isp, struct media_entity *source,
return ret;
}
-static struct media_entity *entity_output_node(struct media_entity *entity)
-{
- struct media_entity *node;
- unsigned int i;
-
- for (i = 0; i < entity->num_links; ++i) {
- node = entity->links[i].sink->entity;
- if (media_entity_type(node) == MEDIA_ENT_T_DEVNODE)
- break;
- }
-
- if (i == entity->num_links) {
- printf("error: unable to locate %s output video node.\n",
- entity->info.name);
- return NULL;
- }
-
- return node;
-}
-
static __u32 mbus_to_pix(enum v4l2_mbus_pixelcode code)
{
switch (code) {
@@ -121,10 +101,20 @@ static void omap3_isp_pipeline_destroy(struct omap3_isp_pipeline *pipe)
{
struct omap3_isp_entity *entity;
struct omap3_isp_entity *next;
+ struct omap3_isp_video *video;
list_for_each_entry_safe(entity, next, &pipe->entities, list) {
list_remove(&entity->list);
- free(entity);
+ switch (entity->type) {
+ case OMAP3_ISP_ENTITY_VIDEO:
+ video = to_omap3_isp_video(entity);
+ free(video);
+ break;
+
+ case OMAP3_ISP_ENTITY_ENTITY:
+ free(entity);
+ break;
+ }
}
}
@@ -133,6 +123,7 @@ static int omap3_isp_pipeline_build(struct omap3_isp_device *isp,
{
struct omap3_isp_entity *source = NULL;
struct omap3_isp_entity *sink;
+ struct omap3_isp_video *video;
struct media_entity *entity;
unsigned int i;
va_list ap;
@@ -149,13 +140,25 @@ static int omap3_isp_pipeline_build(struct omap3_isp_device *isp,
goto done;
}
- sink = malloc(sizeof *entity);
- if (sink == NULL) {
- ret = -ENOMEM;
- goto done;
+ if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) {
+ video = malloc(sizeof *video);
+ if (video == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ memset(video, 0, sizeof *video);
+ sink = &video->entity;
+ } else {
+ sink = malloc(sizeof *entity);
+ if (sink == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ memset(sink, 0, sizeof *sink);
}
- memset(sink, 0, sizeof *sink);
sink->entity = entity;
if (source != NULL) {
@@ -187,6 +190,8 @@ static int omap3_isp_pipeline_build(struct omap3_isp_device *isp,
goto done;
}
+ pipe->output = to_omap3_isp_video(source);
+
va_end(ap);
ret = 0;
@@ -438,11 +443,6 @@ struct omap3_isp_device *omap3_isp_open(const char *devname,
isp->sensor = entity;
- isp->viewfinder.output.scaler = OMAP3_ISP_SCALER_ISP;
- isp->viewfinder.output.node = entity_output_node(isp->resizer);
- if (isp->viewfinder.output.node == NULL)
- goto error;
-
/* Retrieve the sensor default format. */
ret = v4l2_subdev_get_format(isp->sensor, &isp->sensor_format, 0,
V4L2_SUBDEV_FORMAT_TRY);
@@ -498,9 +498,11 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
return ret;
}
+ isp->viewfinder.output->scaler = OMAP3_ISP_SCALER_ISP;
+
/* Try the format. */
ret = omap3_isp_pipeline_try_format(isp, &isp->viewfinder, ofmt,
- isp->viewfinder.output.scaler);
+ isp->viewfinder.output->scaler);
if (ret < 0)
return ret;
@@ -510,10 +512,10 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
return ret;
/* Open the V4L2 device. */
- isp->viewfinder.output.video = v4l2_open(isp->viewfinder.output.node->devname);
- if (isp->viewfinder.output.video == NULL) {
+ isp->viewfinder.output->video = v4l2_open(isp->viewfinder.output->entity.entity->devname);
+ if (isp->viewfinder.output->video == NULL) {
printf("error: unable to open video capture device %s\n",
- isp->viewfinder.output.node->devname);
+ isp->viewfinder.output->entity.entity->devname);
return -ENXIO;
}
@@ -523,11 +525,11 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
format.width = ofmt->width;
format.height = ofmt->height;
- ret = v4l2_set_format(isp->viewfinder.output.video, &format);
+ ret = v4l2_set_format(isp->viewfinder.output->video, &format);
if (ret < 0)
return ret;
- isp->viewfinder.output.format = *ofmt;
+ isp->viewfinder.output->format = *ofmt;
return 0;
}
@@ -538,14 +540,14 @@ int omap3_isp_viewfinder_set_pool(struct omap3_isp_device *isp,
int ret;
/* Allocate video buffers. */
- ret = v4l2_alloc_buffers(isp->viewfinder.output.video, pool, V4L2_MEMORY_USERPTR);
+ ret = v4l2_alloc_buffers(isp->viewfinder.output->video, pool, V4L2_MEMORY_USERPTR);
if (ret < 0) {
printf("error: unable to allocate buffers for viewfinder.\n");
return ret;
}
- isp->viewfinder.output.dequeued = 0;
- isp->viewfinder.output.queued = 0;
+ isp->viewfinder.output->dequeued = 0;
+ isp->viewfinder.output->queued = 0;
return 0;
}
@@ -555,19 +557,19 @@ int omap3_isp_viewfinder_set_scaler(struct omap3_isp_device *isp,
struct v4l2_mbus_framefmt format;
int ret;
- if (isp->viewfinder.output.scaler == scaler)
+ if (isp->viewfinder.output->scaler == scaler)
return 0;
- isp->viewfinder.output.scaler = scaler;
+ isp->viewfinder.output->scaler = scaler;
/* If omap3_isp_viewfinder_setup() hasn't been called yet return now. */
- if (isp->viewfinder.output.format.width == 0 ||
- isp->viewfinder.output.format.height == 0)
+ if (isp->viewfinder.output->format.width == 0 ||
+ isp->viewfinder.output->format.height == 0)
return 0;
- format = isp->viewfinder.output.format;
+ format = isp->viewfinder.output->format;
ret = omap3_isp_pipeline_try_format(isp, &isp->viewfinder, &format,
- isp->viewfinder.output.scaler);
+ isp->viewfinder.output->scaler);
if (ret < 0)
return ret;
@@ -581,18 +583,18 @@ static void omap3_isp_viewfinder_event(void *priv)
int ret;
/* Dequeue the buffer */
- ret = v4l2_dequeue_buffer(isp->viewfinder.output.video, &buffer);
+ ret = v4l2_dequeue_buffer(isp->viewfinder.output->video, &buffer);
if (ret < 0) {
printf("error: unable to dequeue buffer: %s (%d)\n",
strerror(-ret), ret);
return;
}
- isp->viewfinder.output.dequeued |= 1 << buffer.index;
- isp->viewfinder.output.queued--;
+ isp->viewfinder.output->dequeued |= 1 << buffer.index;
+ isp->viewfinder.output->queued--;
- if (isp->viewfinder.output.queued == 0)
- isp->ops->unwatch_fd(isp->viewfinder.output.video->fd);
+ if (isp->viewfinder.output->queued == 0)
+ isp->ops->unwatch_fd(isp->viewfinder.output->video->fd);
isp->ops->viewfinder_ready(isp, &buffer);
}
@@ -604,36 +606,36 @@ int omap3_isp_viewfinder_start(struct omap3_isp_device *isp)
int ret;
/* Queue all buffers for video capture. */
- for (i = 0; i < isp->viewfinder.output.video->nbufs; ++i) {
- if (isp->viewfinder.output.dequeued & (1 << i))
+ for (i = 0; i < isp->viewfinder.output->video->nbufs; ++i) {
+ if (isp->viewfinder.output->dequeued & (1 << i))
continue;
buffer.index = i;
- ret = v4l2_queue_buffer(isp->viewfinder.output.video, &buffer);
+ ret = v4l2_queue_buffer(isp->viewfinder.output->video, &buffer);
if (ret < 0) {
printf("error: unable to queue buffer %u (%d)\n", i, ret);
return -errno;
}
- isp->viewfinder.output.queued++;
+ isp->viewfinder.output->queued++;
}
if (isp->ops->prepare_streamon)
isp->ops->prepare_streamon(isp);
/* Watch the viewfinder file descriptor. */
- isp->ops->watch_fd(isp->viewfinder.output.video->fd,
+ isp->ops->watch_fd(isp->viewfinder.output->video->fd,
OMAP3_ISP_EVENT_READ, omap3_isp_viewfinder_event,
isp);
- ret = v4l2_stream_on(isp->viewfinder.output.video);
+ ret = v4l2_stream_on(isp->viewfinder.output->video);
if (ret < 0) {
printf("error: streamon failed for viewfinder (%d)\n", ret);
return ret;
}
- isp->viewfinder.output.running = true;
+ isp->viewfinder.output->running = true;
return 0;
}
@@ -642,34 +644,34 @@ int omap3_isp_viewfinder_stop(struct omap3_isp_device *isp)
{
int ret;
- isp->ops->unwatch_fd(isp->viewfinder.output.video->fd);
+ isp->ops->unwatch_fd(isp->viewfinder.output->video->fd);
- ret = v4l2_stream_off(isp->viewfinder.output.video);
+ ret = v4l2_stream_off(isp->viewfinder.output->video);
if (ret < 0) {
printf("error: streamoff failed for viewfinder\n");
return ret;
}
- isp->viewfinder.output.queued = 0;
- isp->viewfinder.output.running = false;
+ isp->viewfinder.output->queued = 0;
+ isp->viewfinder.output->running = false;
return 0;
}
int omap3_isp_viewfinder_put_buffer(struct omap3_isp_device *isp,
struct v4l2_video_buffer *buffer)
{
- isp->viewfinder.output.dequeued &= ~(1 << buffer->index);
+ isp->viewfinder.output->dequeued &= ~(1 << buffer->index);
- if (!isp->viewfinder.output.running)
+ if (!isp->viewfinder.output->running)
return 0;
- if (isp->viewfinder.output.queued == 0)
- isp->ops->watch_fd(isp->viewfinder.output.video->fd,
+ if (isp->viewfinder.output->queued == 0)
+ isp->ops->watch_fd(isp->viewfinder.output->video->fd,
OMAP3_ISP_EVENT_READ,
omap3_isp_viewfinder_event, isp);
- isp->viewfinder.output.queued++;
- return v4l2_queue_buffer(isp->viewfinder.output.video, buffer);
+ isp->viewfinder.output->queued++;
+ return v4l2_queue_buffer(isp->viewfinder.output->video, buffer);
}
/* -----------------------------------------------------------------------------
@@ -716,10 +718,7 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
return ret;
}
- isp->snapshot.output.scaler = OMAP3_ISP_SCALER_ISP;
- isp->snapshot.output.node = entity_output_node(entity);
- if (isp->snapshot.output.node == NULL)
- return -ENOENT;
+ isp->snapshot.output->scaler = OMAP3_ISP_SCALER_ISP;
/* Try the format. */
ret = omap3_isp_pipeline_try_format(isp, &isp->snapshot, ofmt,
@@ -727,13 +726,13 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
if (ret < 0)
return ret;
- isp->snapshot.output.format = *ofmt;
+ isp->snapshot.output->format = *ofmt;
/* Open the V4L2 device. */
- isp->snapshot.output.video = v4l2_open(isp->snapshot.output.node->devname);
- if (isp->snapshot.output.video == NULL) {
+ isp->snapshot.output->video = v4l2_open(isp->snapshot.output->entity.entity->devname);
+ if (isp->snapshot.output->video == NULL) {
printf("error: unable to open snapshot capture device %s\n",
- isp->snapshot.output.node->devname);
+ isp->snapshot.output->entity.entity->devname);
return -ENODEV;
}
@@ -743,18 +742,18 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
format.width = ofmt->width;
format.height = ofmt->height;
- ret = v4l2_set_format(isp->snapshot.output.video, &format);
+ ret = v4l2_set_format(isp->snapshot.output->video, &format);
if (ret < 0)
return ret;
/* Pre-allocate capture buffers. */
- isp->snapshot.output.pool = v4l2_buffers_pool_new(2);
- if (isp->snapshot.output.pool == NULL) {
+ isp->snapshot.output->pool = v4l2_buffers_pool_new(2);
+ if (isp->snapshot.output->pool == NULL) {
printf("error: unable to allocate buffers pool for snapshot.\n");
return -ENOMEM;
}
- ret = v4l2_alloc_buffers(isp->snapshot.output.video, isp->snapshot.output.pool,
+ ret = v4l2_alloc_buffers(isp->snapshot.output->video, isp->snapshot.output->pool,
V4L2_MEMORY_MMAP);
if (ret < 0) {
printf("error: unable to allocate buffers for snapshot.\n");
@@ -762,10 +761,10 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
}
/* Queue all buffers. */
- for (i = 0; i < isp->snapshot.output.video->nbufs; ++i) {
+ for (i = 0; i < isp->snapshot.output->video->nbufs; ++i) {
buffer.index = i;
- ret = v4l2_queue_buffer(isp->snapshot.output.video, &buffer);
+ ret = v4l2_queue_buffer(isp->snapshot.output->video, &buffer);
if (ret < 0) {
printf("error: unable to queue buffer %u\n", i);
return -errno;
@@ -783,21 +782,21 @@ static void omap3_isp_snapshot_event(void *priv)
int ret;
/* Dequeue a buffer, stop the stream and fire the snapshot event. */
- ret = v4l2_dequeue_buffer(isp->snapshot.output.video, &buffer);
+ ret = v4l2_dequeue_buffer(isp->snapshot.output->video, &buffer);
if (ret < 0) {
printf("error: unable to dequeue snapshot buffer.\n");
return;
}
- isp->ops->unwatch_fd(isp->snapshot.output.video->fd);
+ isp->ops->unwatch_fd(isp->snapshot.output->video->fd);
- ret = v4l2_stream_off(isp->snapshot.output.video);
+ ret = v4l2_stream_off(isp->snapshot.output->video);
if (ret < 0) {
printf("error: streamoff failed for snapshot\n");
return;
}
- isp->snapshot.output.running = false;
+ isp->snapshot.output->running = false;
isp->ops->snapshot_ready(isp, &buffer);
@@ -813,10 +812,10 @@ static void omap3_isp_snapshot_event(void *priv)
}
/* Queue all buffers for the next snapshot. */
- for (i = 0; i < isp->snapshot.output.video->nbufs; ++i) {
+ for (i = 0; i < isp->snapshot.output->video->nbufs; ++i) {
buffer.index = i;
- ret = v4l2_queue_buffer(isp->snapshot.output.video, &buffer);
+ ret = v4l2_queue_buffer(isp->snapshot.output->video, &buffer);
if (ret < 0) {
printf("error: unable to queue buffer %u\n", i);
return;
@@ -846,16 +845,16 @@ int omap3_isp_snapshot_capture(struct omap3_isp_device *isp)
isp->ops->prepare_streamon(isp);
/* Watch the snapshot file descriptor. */
- isp->ops->watch_fd(isp->snapshot.output.video->fd, OMAP3_ISP_EVENT_READ,
- omap3_isp_snapshot_event, isp);
+ isp->ops->watch_fd(isp->snapshot.output->video->fd,
+ OMAP3_ISP_EVENT_READ, omap3_isp_snapshot_event, isp);
- ret = v4l2_stream_on(isp->snapshot.output.video);
+ ret = v4l2_stream_on(isp->snapshot.output->video);
if (ret < 0) {
printf("error: streamon failed for snapshot\n");
return ret;
}
- isp->snapshot.output.running = true;
+ isp->snapshot.output->running = true;
return 0;
}