Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 138167
b: refs/heads/master
c: df2ed07
h: refs/heads/master
i:
  138165: d075d8b
  138163: 4f0d6f3
  138159: 1ea6ecc
v: v3
  • Loading branch information
Guennadi Liakhovetski authored and Mauro Carvalho Chehab committed Mar 30, 2009
1 parent a96d349 commit a2ed06f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 09e231b35173313cd92e27532e5028f2042dcee4
refs/heads/master: df2ed07025fc83f3b36470cf06d1816a5e07c90b
100 changes: 68 additions & 32 deletions trunk/drivers/media/video/soc_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <media/videobuf-core.h>
#include <media/soc_camera.h>

/* Default to VGA resolution */
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 480

static LIST_HEAD(hosts);
static LIST_HEAD(devices);
static DEFINE_MUTEX(list_lock);
Expand Down Expand Up @@ -256,6 +260,44 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
vfree(icd->user_formats);
}

/* Called with .vb_lock held */
static int soc_camera_set_fmt(struct soc_camera_file *icf,
struct v4l2_format *f)
{
struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct v4l2_pix_format *pix = &f->fmt.pix;
int ret;

/* We always call try_fmt() before set_fmt() or set_crop() */
ret = ici->ops->try_fmt(icd, f);
if (ret < 0)
return ret;

ret = ici->ops->set_fmt(icd, f);
if (ret < 0) {
return ret;
} else if (!icd->current_fmt ||
icd->current_fmt->fourcc != pix->pixelformat) {
dev_err(&ici->dev,
"Host driver hasn't set up current format correctly!\n");
return -EINVAL;
}

icd->width = pix->width;
icd->height = pix->height;
icf->vb_vidq.field = pix->field;
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
f->type);

dev_dbg(&icd->dev, "set width: %d height: %d\n",
icd->width, icd->height);

/* set physical bus parameters */
return ici->ops->set_bus_param(icd, pix->pixelformat);
}

static int soc_camera_open(struct file *file)
{
struct video_device *vdev;
Expand Down Expand Up @@ -297,6 +339,15 @@ static int soc_camera_open(struct file *file)

/* Now we really have to activate the camera */
if (icd->use_count == 1) {
struct v4l2_format f = {
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.fmt.pix = {
.width = DEFAULT_WIDTH,
.height = DEFAULT_HEIGHT,
.field = V4L2_FIELD_ANY,
},
};

ret = soc_camera_init_user_formats(icd);
if (ret < 0)
goto eiufmt;
Expand All @@ -305,6 +356,14 @@ static int soc_camera_open(struct file *file)
dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
goto eiciadd;
}

f.fmt.pix.pixelformat = icd->current_fmt->fourcc;
f.fmt.pix.colorspace = icd->current_fmt->colorspace;

/* Try to configure with default parameters */
ret = soc_camera_set_fmt(icf, &f);
if (ret < 0)
goto esfmt;
}

mutex_unlock(&icd->video_lock);
Expand All @@ -316,7 +375,12 @@ static int soc_camera_open(struct file *file)

return 0;

/* First two errors are entered with the .video_lock held */
/*
* First three errors are entered with the .video_lock held
* and use_count == 1
*/
esfmt:
ici->ops->remove(icd);
eiciadd:
soc_camera_free_user_formats(icd);
eiufmt:
Expand Down Expand Up @@ -415,16 +479,10 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
{
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct v4l2_pix_format *pix = &f->fmt.pix;
int ret;

WARN_ON(priv != file->private_data);

ret = soc_camera_try_fmt_vid_cap(file, priv, f);
if (ret < 0)
return ret;

mutex_lock(&icf->vb_vidq.vb_lock);

if (videobuf_queue_is_busy(&icf->vb_vidq)) {
Expand All @@ -433,29 +491,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
goto unlock;
}

ret = ici->ops->set_fmt(icd, f);
if (ret < 0) {
goto unlock;
} else if (!icd->current_fmt ||
icd->current_fmt->fourcc != pix->pixelformat) {
dev_err(&ici->dev,
"Host driver hasn't set up current format correctly!\n");
ret = -EINVAL;
goto unlock;
}

icd->width = f->fmt.pix.width;
icd->height = f->fmt.pix.height;
icf->vb_vidq.field = pix->field;
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
f->type);

dev_dbg(&icd->dev, "set width: %d height: %d\n",
icd->width, icd->height);

/* set physical bus parameters */
ret = ici->ops->set_bus_param(icd, pix->pixelformat);
ret = soc_camera_set_fmt(icf, f);

unlock:
mutex_unlock(&icf->vb_vidq.vb_lock);
Expand Down Expand Up @@ -642,8 +678,8 @@ static int soc_camera_cropcap(struct file *file, void *fh,
a->bounds.height = icd->height_max;
a->defrect.left = icd->x_min;
a->defrect.top = icd->y_min;
a->defrect.width = 640;
a->defrect.height = 480;
a->defrect.width = DEFAULT_WIDTH;
a->defrect.height = DEFAULT_HEIGHT;
a->pixelaspect.numerator = 1;
a->pixelaspect.denominator = 1;

Expand Down

0 comments on commit a2ed06f

Please sign in to comment.