aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mx1_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-12-11 09:46:49 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-16 06:27:29 -0500
commit760697beca338599a65484389c7abbe54aedb664 (patch)
tree515735429d2240629a6f048ab1a7fefaf5299e46 /drivers/media/video/mx1_camera.c
parent9a74251d8bee7a25fee89a0be3ccea73e01c1a05 (diff)
V4L/DVB (13659): soc-camera: convert to the new mediabus API
Convert soc-camera core and all soc-camera drivers to the new mediabus API. This also takes soc-camera client drivers one step closer to also be usable with generic v4l2-subdev host drivers. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mx1_camera.c')
-rw-r--r--drivers/media/video/mx1_camera.c90
1 files changed, 73 insertions, 17 deletions
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 4c1a439373c5..2ba14fb5b031 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -37,6 +37,7 @@
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-dev.h> 38#include <media/v4l2-dev.h>
39#include <media/videobuf-dma-contig.h> 39#include <media/videobuf-dma-contig.h>
40#include <media/soc_mediabus.h>
40 41
41#include <asm/dma.h> 42#include <asm/dma.h>
42#include <asm/fiq.h> 43#include <asm/fiq.h>
@@ -94,9 +95,9 @@
94/* buffer for one video frame */ 95/* buffer for one video frame */
95struct mx1_buffer { 96struct mx1_buffer {
96 /* common v4l buffer stuff -- must be first */ 97 /* common v4l buffer stuff -- must be first */
97 struct videobuf_buffer vb; 98 struct videobuf_buffer vb;
98 const struct soc_camera_data_format *fmt; 99 enum v4l2_mbus_pixelcode code;
99 int inwork; 100 int inwork;
100}; 101};
101 102
102/* 103/*
@@ -128,9 +129,13 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
128 unsigned int *size) 129 unsigned int *size)
129{ 130{
130 struct soc_camera_device *icd = vq->priv_data; 131 struct soc_camera_device *icd = vq->priv_data;
132 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
133 icd->current_fmt->host_fmt);
131 134
132 *size = icd->user_width * icd->user_height * 135 if (bytes_per_line < 0)
133 ((icd->current_fmt->depth + 7) >> 3); 136 return bytes_per_line;
137
138 *size = bytes_per_line * icd->user_height;
134 139
135 if (!*count) 140 if (!*count)
136 *count = 32; 141 *count = 32;
@@ -169,6 +174,11 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
169 struct soc_camera_device *icd = vq->priv_data; 174 struct soc_camera_device *icd = vq->priv_data;
170 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 175 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
171 int ret; 176 int ret;
177 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
178 icd->current_fmt->host_fmt);
179
180 if (bytes_per_line < 0)
181 return bytes_per_line;
172 182
173 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 183 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
174 vb, vb->baddr, vb->bsize); 184 vb, vb->baddr, vb->bsize);
@@ -184,18 +194,18 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
184 */ 194 */
185 buf->inwork = 1; 195 buf->inwork = 1;
186 196
187 if (buf->fmt != icd->current_fmt || 197 if (buf->code != icd->current_fmt->code ||
188 vb->width != icd->user_width || 198 vb->width != icd->user_width ||
189 vb->height != icd->user_height || 199 vb->height != icd->user_height ||
190 vb->field != field) { 200 vb->field != field) {
191 buf->fmt = icd->current_fmt; 201 buf->code = icd->current_fmt->code;
192 vb->width = icd->user_width; 202 vb->width = icd->user_width;
193 vb->height = icd->user_height; 203 vb->height = icd->user_height;
194 vb->field = field; 204 vb->field = field;
195 vb->state = VIDEOBUF_NEEDS_INIT; 205 vb->state = VIDEOBUF_NEEDS_INIT;
196 } 206 }
197 207
198 vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); 208 vb->size = bytes_per_line * vb->height;
199 if (0 != vb->baddr && vb->bsize < vb->size) { 209 if (0 != vb->baddr && vb->bsize < vb->size) {
200 ret = -EINVAL; 210 ret = -EINVAL;
201 goto out; 211 goto out;
@@ -497,12 +507,10 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
497 507
498 /* MX1 supports only 8bit buswidth */ 508 /* MX1 supports only 8bit buswidth */
499 common_flags = soc_camera_bus_param_compatible(camera_flags, 509 common_flags = soc_camera_bus_param_compatible(camera_flags,
500 CSI_BUS_FLAGS); 510 CSI_BUS_FLAGS);
501 if (!common_flags) 511 if (!common_flags)
502 return -EINVAL; 512 return -EINVAL;
503 513
504 icd->buswidth = 8;
505
506 /* Make choises, based on platform choice */ 514 /* Make choises, based on platform choice */
507 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 515 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
508 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 516 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
@@ -555,7 +563,8 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
555 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 563 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
556 const struct soc_camera_format_xlate *xlate; 564 const struct soc_camera_format_xlate *xlate;
557 struct v4l2_pix_format *pix = &f->fmt.pix; 565 struct v4l2_pix_format *pix = &f->fmt.pix;
558 int ret; 566 struct v4l2_mbus_framefmt mf;
567 int ret, buswidth;
559 568
560 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 569 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
561 if (!xlate) { 570 if (!xlate) {
@@ -564,12 +573,33 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
564 return -EINVAL; 573 return -EINVAL;
565 } 574 }
566 575
567 ret = v4l2_subdev_call(sd, video, s_fmt, f); 576 buswidth = xlate->host_fmt->bits_per_sample;
568 if (!ret) { 577 if (buswidth > 8) {
569 icd->buswidth = xlate->buswidth; 578 dev_warn(icd->dev.parent,
570 icd->current_fmt = xlate->host_fmt; 579 "bits-per-sample %d for format %x unsupported\n",
580 buswidth, pix->pixelformat);
581 return -EINVAL;
571 } 582 }
572 583
584 mf.width = pix->width;
585 mf.height = pix->height;
586 mf.field = pix->field;
587 mf.colorspace = pix->colorspace;
588 mf.code = xlate->code;
589
590 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
591 if (ret < 0)
592 return ret;
593
594 if (mf.code != xlate->code)
595 return -EINVAL;
596
597 pix->width = mf.width;
598 pix->height = mf.height;
599 pix->field = mf.field;
600 pix->colorspace = mf.colorspace;
601 icd->current_fmt = xlate;
602
573 return ret; 603 return ret;
574} 604}
575 605
@@ -577,10 +607,36 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd,
577 struct v4l2_format *f) 607 struct v4l2_format *f)
578{ 608{
579 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 609 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
610 const struct soc_camera_format_xlate *xlate;
611 struct v4l2_pix_format *pix = &f->fmt.pix;
612 struct v4l2_mbus_framefmt mf;
613 int ret;
580 /* TODO: limit to mx1 hardware capabilities */ 614 /* TODO: limit to mx1 hardware capabilities */
581 615
616 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
617 if (!xlate) {
618 dev_warn(icd->dev.parent, "Format %x not found\n",
619 pix->pixelformat);
620 return -EINVAL;
621 }
622
623 mf.width = pix->width;
624 mf.height = pix->height;
625 mf.field = pix->field;
626 mf.colorspace = pix->colorspace;
627 mf.code = xlate->code;
628
582 /* limit to sensor capabilities */ 629 /* limit to sensor capabilities */
583 return v4l2_subdev_call(sd, video, try_fmt, f); 630 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
631 if (ret < 0)
632 return ret;
633
634 pix->width = mf.width;
635 pix->height = mf.height;
636 pix->field = mf.field;
637 pix->colorspace = mf.colorspace;
638
639 return 0;
584} 640}
585 641
586static int mx1_camera_reqbufs(struct soc_camera_file *icf, 642static int mx1_camera_reqbufs(struct soc_camera_file *icf,