Commit 09e231b3 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

V4L/DVB (11024): soc-camera: separate S_FMT and S_CROP operations

As host and camera drivers become more complex, differences between S_FMT and
S_CROP functionality grow, this patch separates them.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 1cd3c0fa
...@@ -284,8 +284,8 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) ...@@ -284,8 +284,8 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
return soc_camera_apply_sensor_flags(icl, flags); return soc_camera_apply_sensor_flags(icl, flags);
} }
static int mt9m001_set_fmt(struct soc_camera_device *icd, static int mt9m001_set_crop(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_rect *rect)
{ {
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
int ret; int ret;
...@@ -324,6 +324,20 @@ static int mt9m001_set_fmt(struct soc_camera_device *icd, ...@@ -324,6 +324,20 @@ static int mt9m001_set_fmt(struct soc_camera_device *icd,
return ret; return ret;
} }
static int mt9m001_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct v4l2_rect rect = {
.left = icd->x_current,
.top = icd->y_current,
.width = f->fmt.pix.width,
.height = f->fmt.pix.height,
};
/* No support for scaling so far, just crop. TODO: use skipping */
return mt9m001_set_crop(icd, &rect);
}
static int mt9m001_try_fmt(struct soc_camera_device *icd, static int mt9m001_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f) struct v4l2_format *f)
{ {
...@@ -449,6 +463,7 @@ static struct soc_camera_ops mt9m001_ops = { ...@@ -449,6 +463,7 @@ static struct soc_camera_ops mt9m001_ops = {
.release = mt9m001_release, .release = mt9m001_release,
.start_capture = mt9m001_start_capture, .start_capture = mt9m001_start_capture,
.stop_capture = mt9m001_stop_capture, .stop_capture = mt9m001_stop_capture,
.set_crop = mt9m001_set_crop,
.set_fmt = mt9m001_set_fmt, .set_fmt = mt9m001_set_fmt,
.try_fmt = mt9m001_try_fmt, .try_fmt = mt9m001_try_fmt,
.set_bus_param = mt9m001_set_bus_param, .set_bus_param = mt9m001_set_bus_param,
......
...@@ -152,7 +152,7 @@ struct mt9m111 { ...@@ -152,7 +152,7 @@ struct mt9m111 {
struct soc_camera_device icd; struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
enum mt9m111_context context; enum mt9m111_context context;
unsigned int left, top, width, height; struct v4l2_rect rect;
u32 pixfmt; u32 pixfmt;
unsigned char autoexposure; unsigned char autoexposure;
unsigned char datawidth; unsigned char datawidth;
...@@ -249,12 +249,13 @@ static int mt9m111_set_context(struct soc_camera_device *icd, ...@@ -249,12 +249,13 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
return reg_write(CONTEXT_CONTROL, valA); return reg_write(CONTEXT_CONTROL, valA);
} }
static int mt9m111_setup_rect(struct soc_camera_device *icd) static int mt9m111_setup_rect(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{ {
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret, is_raw_format; int ret, is_raw_format;
int width = mt9m111->width; int width = rect->width;
int height = mt9m111->height; int height = rect->height;
if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
|| (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
...@@ -262,9 +263,9 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd) ...@@ -262,9 +263,9 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd)
else else
is_raw_format = 0; is_raw_format = 0;
ret = reg_write(COLUMN_START, mt9m111->left); ret = reg_write(COLUMN_START, rect->left);
if (!ret) if (!ret)
ret = reg_write(ROW_START, mt9m111->top); ret = reg_write(ROW_START, rect->top);
if (is_raw_format) { if (is_raw_format) {
if (!ret) if (!ret)
...@@ -436,6 +437,22 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) ...@@ -436,6 +437,22 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
return 0; return 0;
} }
static int mt9m111_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret;
dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
__func__, rect->left, rect->top, rect->width,
rect->height);
ret = mt9m111_setup_rect(icd, rect);
if (!ret)
mt9m111->rect = *rect;
return ret;
}
static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
{ {
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
...@@ -486,23 +503,27 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) ...@@ -486,23 +503,27 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
} }
static int mt9m111_set_fmt(struct soc_camera_device *icd, static int mt9m111_set_fmt(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_format *f)
{ {
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_rect rect = {
.left = mt9m111->rect.left,
.top = mt9m111->rect.top,
.width = pix->width,
.height = pix->height,
};
int ret; int ret;
mt9m111->left = rect->left;
mt9m111->top = rect->top;
mt9m111->width = rect->width;
mt9m111->height = rect->height;
dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
__func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, __func__, pix->pixelformat, rect.left, rect.top, rect.width,
mt9m111->height); rect.height);
ret = mt9m111_setup_rect(icd); ret = mt9m111_setup_rect(icd, &rect);
if (!ret)
ret = mt9m111_set_pixfmt(icd, pix->pixelformat);
if (!ret) if (!ret)
ret = mt9m111_set_pixfmt(icd, pixfmt); mt9m111->rect = rect;
return ret; return ret;
} }
...@@ -633,6 +654,7 @@ static struct soc_camera_ops mt9m111_ops = { ...@@ -633,6 +654,7 @@ static struct soc_camera_ops mt9m111_ops = {
.release = mt9m111_release, .release = mt9m111_release,
.start_capture = mt9m111_start_capture, .start_capture = mt9m111_start_capture,
.stop_capture = mt9m111_stop_capture, .stop_capture = mt9m111_stop_capture,
.set_crop = mt9m111_set_crop,
.set_fmt = mt9m111_set_fmt, .set_fmt = mt9m111_set_fmt,
.try_fmt = mt9m111_try_fmt, .try_fmt = mt9m111_try_fmt,
.query_bus_param = mt9m111_query_bus_param, .query_bus_param = mt9m111_query_bus_param,
...@@ -817,7 +839,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd) ...@@ -817,7 +839,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd)
mt9m111_set_context(icd, mt9m111->context); mt9m111_set_context(icd, mt9m111->context);
mt9m111_set_pixfmt(icd, mt9m111->pixfmt); mt9m111_set_pixfmt(icd, mt9m111->pixfmt);
mt9m111_setup_rect(icd); mt9m111_setup_rect(icd, &mt9m111->rect);
mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
mt9m111_set_global_gain(icd, icd->gain); mt9m111_set_global_gain(icd, icd->gain);
......
...@@ -213,36 +213,14 @@ static void recalculate_limits(struct soc_camera_device *icd, ...@@ -213,36 +213,14 @@ static void recalculate_limits(struct soc_camera_device *icd,
icd->height_max = MT9T031_MAX_HEIGHT / yskip; icd->height_max = MT9T031_MAX_HEIGHT / yskip;
} }
static int mt9t031_set_fmt(struct soc_camera_device *icd, static int mt9t031_set_params(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_rect *rect, u16 xskip, u16 yskip)
{ {
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
int ret; int ret;
u16 xbin, ybin, width, height, left, top;
const u16 hblank = MT9T031_HORIZONTAL_BLANK, const u16 hblank = MT9T031_HORIZONTAL_BLANK,
vblank = MT9T031_VERTICAL_BLANK; vblank = MT9T031_VERTICAL_BLANK;
u16 xbin, xskip, ybin, yskip, width, height, left, top;
if (pixfmt) {
/*
* try_fmt has put rectangle within limits.
* S_FMT - use binning and skipping for scaling, recalculate
* limits, used for cropping
*/
/* Is this more optimal than just a division? */
for (xskip = 8; xskip > 1; xskip--)
if (rect->width * xskip <= MT9T031_MAX_WIDTH)
break;
for (yskip = 8; yskip > 1; yskip--)
if (rect->height * yskip <= MT9T031_MAX_HEIGHT)
break;
recalculate_limits(icd, xskip, yskip);
} else {
/* CROP - no change in scaling, or in limits */
xskip = mt9t031->xskip;
yskip = mt9t031->yskip;
}
/* Make sure we don't exceed sensor limits */ /* Make sure we don't exceed sensor limits */
if (rect->left + rect->width > icd->width_max) if (rect->left + rect->width > icd->width_max)
...@@ -289,7 +267,7 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd, ...@@ -289,7 +267,7 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
if (ret >= 0) if (ret >= 0)
ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank); ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
if (pixfmt) { if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
/* Binning, skipping */ /* Binning, skipping */
if (ret >= 0) if (ret >= 0)
ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE, ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
...@@ -325,15 +303,58 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd, ...@@ -325,15 +303,58 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
} }
} }
if (!ret && pixfmt) { /* Re-enable register update, commit all changes */
if (ret >= 0)
ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
return ret < 0 ? ret : 0;
}
static int mt9t031_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
/* CROP - no change in scaling, or in limits */
return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
}
static int mt9t031_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
int ret;
u16 xskip, yskip;
struct v4l2_rect rect = {
.left = icd->x_current,
.top = icd->y_current,
.width = f->fmt.pix.width,
.height = f->fmt.pix.height,
};
/*
* try_fmt has put rectangle within limits.
* S_FMT - use binning and skipping for scaling, recalculate
* limits, used for cropping
*/
/* Is this more optimal than just a division? */
for (xskip = 8; xskip > 1; xskip--)
if (rect.width * xskip <= MT9T031_MAX_WIDTH)
break;
for (yskip = 8; yskip > 1; yskip--)
if (rect.height * yskip <= MT9T031_MAX_HEIGHT)
break;
recalculate_limits(icd, xskip, yskip);
ret = mt9t031_set_params(icd, &rect, xskip, yskip);
if (!ret) {
mt9t031->xskip = xskip; mt9t031->xskip = xskip;
mt9t031->yskip = yskip; mt9t031->yskip = yskip;
} }
/* Re-enable register update, commit all changes */ return ret;
reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
return ret < 0 ? ret : 0;
} }
static int mt9t031_try_fmt(struct soc_camera_device *icd, static int mt9t031_try_fmt(struct soc_camera_device *icd,
...@@ -470,6 +491,7 @@ static struct soc_camera_ops mt9t031_ops = { ...@@ -470,6 +491,7 @@ static struct soc_camera_ops mt9t031_ops = {
.release = mt9t031_release, .release = mt9t031_release,
.start_capture = mt9t031_start_capture, .start_capture = mt9t031_start_capture,
.stop_capture = mt9t031_stop_capture, .stop_capture = mt9t031_stop_capture,
.set_crop = mt9t031_set_crop,
.set_fmt = mt9t031_set_fmt, .set_fmt = mt9t031_set_fmt,
.try_fmt = mt9t031_try_fmt, .try_fmt = mt9t031_try_fmt,
.set_bus_param = mt9t031_set_bus_param, .set_bus_param = mt9t031_set_bus_param,
......
...@@ -340,32 +340,11 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) ...@@ -340,32 +340,11 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
width_flag; width_flag;
} }
static int mt9v022_set_fmt(struct soc_camera_device *icd, static int mt9v022_set_crop(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_rect *rect)
{ {
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
int ret; int ret;
/* The caller provides a supported format, as verified per call to
* icd->try_fmt(), datawidth is from our supported format list */
switch (pixfmt) {
case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y16:
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
return -EINVAL;
break;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SBGGR16:
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
return -EINVAL;
break;
case 0:
/* No format change, only geometry */
break;
default:
return -EINVAL;
}
/* Like in example app. Contradicts the datasheet though */ /* Like in example app. Contradicts the datasheet though */
ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
if (ret >= 0) { if (ret >= 0) {
...@@ -403,6 +382,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd, ...@@ -403,6 +382,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
return 0; return 0;
} }
static int mt9v022_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_rect rect = {
.left = icd->x_current,
.top = icd->y_current,
.width = pix->width,
.height = pix->height,
};
/* The caller provides a supported format, as verified per call to
* icd->try_fmt(), datawidth is from our supported format list */
switch (pix->pixelformat) {
case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y16:
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
return -EINVAL;
break;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SBGGR16:
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
return -EINVAL;
break;
case 0:
/* No format change, only geometry */
break;
default:
return -EINVAL;
}
/* No support for scaling on this camera, just crop. */
return mt9v022_set_crop(icd, &rect);
}
static int mt9v022_try_fmt(struct soc_camera_device *icd, static int mt9v022_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f) struct v4l2_format *f)
{ {
...@@ -544,6 +559,7 @@ static struct soc_camera_ops mt9v022_ops = { ...@@ -544,6 +559,7 @@ static struct soc_camera_ops mt9v022_ops = {
.release = mt9v022_release, .release = mt9v022_release,
.start_capture = mt9v022_start_capture, .start_capture = mt9v022_start_capture,
.stop_capture = mt9v022_stop_capture, .stop_capture = mt9v022_stop_capture,
.set_crop = mt9v022_set_crop,
.set_fmt = mt9v022_set_fmt, .set_fmt = mt9v022_set_fmt,
.try_fmt = mt9v022_try_fmt, .try_fmt = mt9v022_try_fmt,
.set_bus_param = mt9v022_set_bus_param, .set_bus_param = mt9v022_set_bus_param,
......
...@@ -544,16 +544,14 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd) ...@@ -544,16 +544,14 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
} }
static bool channel_change_requested(struct soc_camera_device *icd, static bool channel_change_requested(struct soc_camera_device *icd,
const struct soc_camera_format_xlate *xlate, struct v4l2_rect *rect)
__u32 pixfmt, struct v4l2_rect *rect)
{ {
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv; struct mx3_camera_dev *mx3_cam = ici->priv;
struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
/* So far only one configuration is supported */ /* Do buffers have to be re-allocated or channel re-configured? */
return pixfmt || (ichan && rect->width * rect->height > return ichan && rect->width * rect->height > icd->width * icd->height;
icd->width * icd->height);
} }
static int test_platform_param(struct mx3_camera_dev *mx3_cam, static int test_platform_param(struct mx3_camera_dev *mx3_cam,
...@@ -733,61 +731,10 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, ...@@ -733,61 +731,10 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
return formats; return formats;
} }
static int mx3_camera_set_fmt(struct soc_camera_device *icd, static void configure_geometry(struct mx3_camera_dev *mx3_cam,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_rect *rect)
{ {
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
const struct soc_camera_format_xlate *xlate;
u32 ctrl, width_field, height_field; u32 ctrl, width_field, height_field;
int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (pixfmt && !xlate) {
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
/*
* We now know pixel formats and can decide upon DMA-channel(s)
* So far only direct camera-to-memory is supported
*/
if (channel_change_requested(icd, xlate, pixfmt, rect)) {
dma_cap_mask_t mask;
struct dma_chan *chan;
struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
/* We have to use IDMAC_IC_7 for Bayer / generic data */
struct dma_chan_request rq = {.mx3_cam = mx3_cam,
.id = IDMAC_IC_7};
if (*ichan) {
struct videobuf_buffer *vb, *_vb;
dma_release_channel(&(*ichan)->dma_chan);
*ichan = NULL;
mx3_cam->active = NULL;
list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
list_del_init(&vb->queue);
vb->state = VIDEOBUF_ERROR;
wake_up(&vb->done);
}
}
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_PRIVATE, mask);
chan = dma_request_channel(mask, chan_filter, &rq);
if (!chan)
return -EBUSY;
*ichan = to_idmac_chan(chan);
(*ichan)->client = mx3_cam;
}
/*
* Might have to perform a complete interface initialisation like in
* ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
* mxc_v4l2_s_fmt()
*/
/* Setup frame size - this cannot be changed on-the-fly... */ /* Setup frame size - this cannot be changed on-the-fly... */
width_field = rect->width - 1; width_field = rect->width - 1;
...@@ -808,9 +755,98 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, ...@@ -808,9 +755,98 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
* No need to free resources here if we fail, we'll see if we need to * No need to free resources here if we fail, we'll see if we need to
* do this next time we are called * do this next time we are called
*/ */
}
static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
{
dma_cap_mask_t mask;
struct dma_chan *chan;
struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
/* We have to use IDMAC_IC_7 for Bayer / generic data */
struct dma_chan_request rq = {.mx3_cam = mx3_cam,
.id = IDMAC_IC_7};
if (*ichan) {
struct videobuf_buffer *vb, *_vb;
dma_release_channel(&(*ichan)->dma_chan);
*ichan = NULL;
mx3_cam->active = NULL;
list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
list_del_init(&vb->queue);
vb->state = VIDEOBUF_ERROR;
wake_up(&vb->done);
}
}
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_PRIVATE, mask);
chan = dma_request_channel(mask, chan_filter, &rq);
if (!chan)
return -EBUSY;
*ichan = to_idmac_chan(chan);
(*ichan)->client = mx3_cam;
return 0;
}
static int mx3_camera_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
/*
* We now know pixel formats and can decide upon DMA-channel(s)
* So far only direct camera-to-memory is supported
*/
if (channel_change_requested(icd, rect)) {
int ret = acquire_dma_channel(mx3_cam);
if (ret < 0)
return ret;
}
configure_geometry(mx3_cam, rect);
return icd->ops->set_crop(icd, rect);
}
static int mx3_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_rect rect = {
.left = icd->x_current,
.top = icd->y_current,
.width = pix->width,
.height = pix->height,
};
int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate) {
dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
return -EINVAL;
}
ret = acquire_dma_channel(mx3_cam);
if (ret < 0)
return ret;
/*
* Might have to perform a complete interface initialisation like in
* ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
* mxc_v4l2_s_fmt()
*/
configure_geometry(mx3_cam, &rect);
ret = icd->ops->set_fmt(icd, pixfmt ? xlate->cam_fmt->fourcc : 0, rect); ret = icd->ops->set_fmt(icd, f);
if (pixfmt && !ret) { if (!ret) {
icd->buswidth = xlate->buswidth; icd->buswidth = xlate->buswidth;
icd->current_fmt = xlate->host_fmt; icd->current_fmt = xlate->host_fmt;
} }
...@@ -1031,6 +1067,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = { ...@@ -1031,6 +1067,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
.suspend = mx3_camera_suspend, .suspend = mx3_camera_suspend,
.resume = mx3_camera_resume, .resume = mx3_camera_resume,
#endif #endif
.set_crop = mx3_camera_set_crop,
.set_fmt = mx3_camera_set_fmt, .set_fmt = mx3_camera_set_fmt,
.try_fmt = mx3_camera_try_fmt, .try_fmt = mx3_camera_try_fmt,
.get_formats = mx3_camera_get_formats, .get_formats = mx3_camera_get_formats,
......
...@@ -781,11 +781,9 @@ ov772x_select_win(u32 width, u32 height) ...@@ -781,11 +781,9 @@ ov772x_select_win(u32 width, u32 height)
return win; return win;
} }
static int ov772x_set_fmt(struct soc_camera_device *icd, static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
__u32 pixfmt, u32 pixfmt)
struct v4l2_rect *rect)
{ {
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
int ret = -EINVAL; int ret = -EINVAL;
u8 val; u8 val;
int i; int i;
...@@ -806,7 +804,7 @@ static int ov772x_set_fmt(struct soc_camera_device *icd, ...@@ -806,7 +804,7 @@ static int ov772x_set_fmt(struct soc_camera_device *icd,
/* /*
* select win * select win
*/ */
priv->win = ov772x_select_win(rect->width, rect->height); priv->win = ov772x_select_win(width, height);
/* /*
* reset hardware * reset hardware
...@@ -870,6 +868,28 @@ static int ov772x_set_fmt(struct soc_camera_device *icd, ...@@ -870,6 +868,28 @@ static int ov772x_set_fmt(struct soc_camera_device *icd,
return ret; return ret;
} }
static int ov772x_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
if (!priv->fmt)
return -EINVAL;
return ov772x_set_params(priv, rect->width, rect->height,
priv->fmt->fourcc);
}
static int ov772x_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
struct v4l2_pix_format *pix = &f->fmt.pix;
return ov772x_set_params(priv, pix->width, pix->height,
pix->pixelformat);
}
static int ov772x_try_fmt(struct soc_camera_device *icd, static int ov772x_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f) struct v4l2_format *f)
{ {
...@@ -959,6 +979,7 @@ static struct soc_camera_ops ov772x_ops = { ...@@ -959,6 +979,7 @@ static struct soc_camera_ops ov772x_ops = {
.release = ov772x_release, .release = ov772x_release,
.start_capture = ov772x_start_capture, .start_capture = ov772x_start_capture,
.stop_capture = ov772x_stop_capture, .stop_capture = ov772x_stop_capture,
.set_crop = ov772x_set_crop,
.set_fmt = ov772x_set_fmt, .set_fmt = ov772x_set_fmt,
.try_fmt = ov772x_try_fmt, .try_fmt = ov772x_try_fmt,
.set_bus_param = ov772x_set_bus_param, .set_bus_param = ov772x_set_bus_param,
......
...@@ -1150,8 +1150,43 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, ...@@ -1150,8 +1150,43 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
return formats; return formats;
} }
static int pxa_camera_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
struct soc_camera_sense sense = {
.master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4,
};
int ret;
/* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
icd->sense = &sense;
ret = icd->ops->set_crop(icd, rect);
icd->sense = NULL;
if (ret < 0) {
dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
rect->width, rect->height, rect->left, rect->top);
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) {
dev_err(&ici->dev,
"pixel clock %lu set by the camera too high!",
sense.pixel_clock);
return -EIO;
}
recalculate_fifo_timeout(pcdev, sense.pixel_clock);
}
return ret;
}
static int pxa_camera_set_fmt(struct soc_camera_device *icd, static int pxa_camera_set_fmt(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_format *f)
{ {
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv; struct pxa_camera_dev *pcdev = ici->priv;
...@@ -1161,35 +1196,30 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, ...@@ -1161,35 +1196,30 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
.master_clock = pcdev->mclk, .master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4, .pixel_clock_max = pcdev->ciclk / 4,
}; };
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_format cam_f = *f;
int ret; int ret;
if (pixfmt) { xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) {
if (!xlate) { dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
dev_warn(&ici->dev, "Format %x not found\n", pixfmt); return -EINVAL;
return -EINVAL;
}
cam_fmt = xlate->cam_fmt;
} }
cam_fmt = xlate->cam_fmt;
/* If PCLK is used to latch data from the sensor, check sense */ /* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
icd->sense = &sense; icd->sense = &sense;
switch (pixfmt) { cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
case 0: /* Only geometry change */ ret = icd->ops->set_fmt(icd, &cam_f);
ret = icd->ops->set_fmt(icd, pixfmt, rect);
break;
default:
ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect);
}
icd->sense = NULL; icd->sense = NULL;
if (ret < 0) { if (ret < 0) {
dev_warn(&ici->dev, "Failed to configure for format %x\n", dev_warn(&ici->dev, "Failed to configure for format %x\n",
pixfmt); pix->pixelformat);
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) { if (sense.pixel_clock > sense.pixel_clock_max) {
dev_err(&ici->dev, dev_err(&ici->dev,
...@@ -1200,7 +1230,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, ...@@ -1200,7 +1230,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
recalculate_fifo_timeout(pcdev, sense.pixel_clock); recalculate_fifo_timeout(pcdev, sense.pixel_clock);
} }
if (pixfmt && !ret) { if (!ret) {
icd->buswidth = xlate->buswidth; icd->buswidth = xlate->buswidth;
icd->current_fmt = xlate->host_fmt; icd->current_fmt = xlate->host_fmt;
} }
...@@ -1364,6 +1394,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { ...@@ -1364,6 +1394,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.remove = pxa_camera_remove_device, .remove = pxa_camera_remove_device,
.suspend = pxa_camera_suspend, .suspend = pxa_camera_suspend,
.resume = pxa_camera_resume, .resume = pxa_camera_resume,
.set_crop = pxa_camera_set_crop,
.get_formats = pxa_camera_get_formats, .get_formats = pxa_camera_get_formats,
.set_fmt = pxa_camera_set_fmt, .set_fmt = pxa_camera_set_fmt,
.try_fmt = pxa_camera_try_fmt, .try_fmt = pxa_camera_try_fmt,
......
...@@ -638,24 +638,30 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, ...@@ -638,24 +638,30 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
return formats; return formats;
} }
static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
return icd->ops->set_crop(icd, rect);
}
static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_format *f)
{ {
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv; struct sh_mobile_ceu_dev *pcdev = ici->priv;
__u32 pixfmt = f->fmt.pix.pixelformat;
const struct soc_camera_format_xlate *xlate; const struct soc_camera_format_xlate *xlate;
struct v4l2_format cam_f = *f;
int ret; int ret;
if (!pixfmt)
return icd->ops->set_fmt(icd, pixfmt, rect);
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) { if (!xlate) {
dev_warn(&ici->dev, "Format %x not found\n", pixfmt); dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL; return -EINVAL;
} }
ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
ret = icd->ops->set_fmt(icd, &cam_f);
if (!ret) { if (!ret) {
icd->buswidth = xlate->buswidth; icd->buswidth = xlate->buswidth;
...@@ -787,6 +793,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { ...@@ -787,6 +793,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
.add = sh_mobile_ceu_add_device, .add = sh_mobile_ceu_add_device,
.remove = sh_mobile_ceu_remove_device, .remove = sh_mobile_ceu_remove_device,
.get_formats = sh_mobile_ceu_get_formats, .get_formats = sh_mobile_ceu_get_formats,
.set_crop = sh_mobile_ceu_set_crop,
.set_fmt = sh_mobile_ceu_set_fmt, .set_fmt = sh_mobile_ceu_set_fmt,
.try_fmt = sh_mobile_ceu_try_fmt, .try_fmt = sh_mobile_ceu_try_fmt,
.reqbufs = sh_mobile_ceu_reqbufs, .reqbufs = sh_mobile_ceu_reqbufs,
......
...@@ -417,9 +417,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -417,9 +417,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
struct soc_camera_device *icd = icf->icd; struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_pix_format *pix = &f->fmt.pix;
__u32 pixfmt = pix->pixelformat;
int ret; int ret;
struct v4l2_rect rect;
WARN_ON(priv != file->private_data); WARN_ON(priv != file->private_data);
...@@ -435,23 +433,19 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -435,23 +433,19 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
goto unlock; goto unlock;
} }
rect.left = icd->x_current; ret = ici->ops->set_fmt(icd, f);
rect.top = icd->y_current;
rect.width = pix->width;
rect.height = pix->height;
ret = ici->ops->set_fmt(icd, pix->pixelformat, &rect);
if (ret < 0) { if (ret < 0) {
goto unlock; goto unlock;
} else if (!icd->current_fmt || } else if (!icd->current_fmt ||
icd->current_fmt->fourcc != pixfmt) { icd->current_fmt->fourcc != pix->pixelformat) {
dev_err(&ici->dev, dev_err(&ici->dev,
"Host driver hasn't set up current format correctly!\n"); "Host driver hasn't set up current format correctly!\n");
ret = -EINVAL; ret = -EINVAL;
goto unlock; goto unlock;
} }
icd->width = rect.width; icd->width = f->fmt.pix.width;
icd->height = rect.height; icd->height = f->fmt.pix.height;
icf->vb_vidq.field = pix->field; icf->vb_vidq.field = pix->field;
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
...@@ -461,7 +455,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -461,7 +455,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
icd->width, icd->height); icd->width, icd->height);
/* set physical bus parameters */ /* set physical bus parameters */
ret = ici->ops->set_bus_param(icd, pixfmt); ret = ici->ops->set_bus_param(icd, pix->pixelformat);
unlock: unlock:
mutex_unlock(&icf->vb_vidq.vb_lock); mutex_unlock(&icf->vb_vidq.vb_lock);
...@@ -685,7 +679,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, ...@@ -685,7 +679,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
/* Cropping is allowed during a running capture, guard consistency */ /* Cropping is allowed during a running capture, guard consistency */
mutex_lock(&icf->vb_vidq.vb_lock); mutex_lock(&icf->vb_vidq.vb_lock);
ret = ici->ops->set_fmt(icd, 0, &a->c); ret = ici->ops->set_crop(icd, &a->c);
if (!ret) { if (!ret) {
icd->width = a->c.width; icd->width = a->c.width;
icd->height = a->c.height; icd->height = a->c.height;
...@@ -918,6 +912,7 @@ int soc_camera_host_register(struct soc_camera_host *ici) ...@@ -918,6 +912,7 @@ int soc_camera_host_register(struct soc_camera_host *ici)
if (!ici || !ici->ops || if (!ici || !ici->ops ||
!ici->ops->try_fmt || !ici->ops->try_fmt ||
!ici->ops->set_fmt || !ici->ops->set_fmt ||
!ici->ops->set_crop ||
!ici->ops->set_bus_param || !ici->ops->set_bus_param ||
!ici->ops->querycap || !ici->ops->querycap ||
!ici->ops->init_videobuf || !ici->ops->init_videobuf ||
...@@ -998,6 +993,7 @@ int soc_camera_device_register(struct soc_camera_device *icd) ...@@ -998,6 +993,7 @@ int soc_camera_device_register(struct soc_camera_device *icd)
!icd->ops->release || !icd->ops->release ||
!icd->ops->start_capture || !icd->ops->start_capture ||
!icd->ops->stop_capture || !icd->ops->stop_capture ||
!icd->ops->set_crop ||
!icd->ops->set_fmt || !icd->ops->set_fmt ||
!icd->ops->try_fmt || !icd->ops->try_fmt ||
!icd->ops->query_bus_param || !icd->ops->query_bus_param ||
......
...@@ -79,8 +79,14 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd) ...@@ -79,8 +79,14 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
return p->bus_param; return p->bus_param;
} }
static int soc_camera_platform_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
return 0;
}
static int soc_camera_platform_set_fmt(struct soc_camera_device *icd, static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) struct v4l2_format *f)
{ {
return 0; return 0;
} }
...@@ -125,6 +131,7 @@ static struct soc_camera_ops soc_camera_platform_ops = { ...@@ -125,6 +131,7 @@ static struct soc_camera_ops soc_camera_platform_ops = {
.release = soc_camera_platform_release, .release = soc_camera_platform_release,
.start_capture = soc_camera_platform_start_capture, .start_capture = soc_camera_platform_start_capture,
.stop_capture = soc_camera_platform_stop_capture, .stop_capture = soc_camera_platform_stop_capture,
.set_crop = soc_camera_platform_set_crop,
.set_fmt = soc_camera_platform_set_fmt, .set_fmt = soc_camera_platform_set_fmt,
.try_fmt = soc_camera_platform_try_fmt, .try_fmt = soc_camera_platform_try_fmt,
.set_bus_param = soc_camera_platform_set_bus_param, .set_bus_param = soc_camera_platform_set_bus_param,
......
...@@ -641,25 +641,12 @@ static int tw9910_set_register(struct soc_camera_device *icd, ...@@ -641,25 +641,12 @@ static int tw9910_set_register(struct soc_camera_device *icd,
} }
#endif #endif
static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt, static int tw9910_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect) struct v4l2_rect *rect)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
int ret = -EINVAL; int ret = -EINVAL;
u8 val; u8 val;
int i;
/*
* check color format
*/
for (i = 0 ; i < ARRAY_SIZE(tw9910_color_fmt) ; i++) {
if (pixfmt == tw9910_color_fmt[i].fourcc) {
ret = 0;
break;
}
}
if (ret < 0)
goto tw9910_set_fmt_error;
/* /*
* select suitable norm * select suitable norm
...@@ -746,8 +733,33 @@ static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt, ...@@ -746,8 +733,33 @@ static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt,
return ret; return ret;
} }
static int tw9910_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_rect rect = {
.left = icd->x_current,
.top = icd->y_current,
.width = pix->width,
.height = pix->height,
};
int i;
/*
* check color format
*/
for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++)
if (pix->pixelformat == tw9910_color_fmt[i].fourcc)
break;
if (i == ARRAY_SIZE(tw9910_color_fmt))
return -EINVAL;
return tw9910_set_crop(icd, &rect);
}
static int tw9910_try_fmt(struct soc_camera_device *icd, static int tw9910_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_pix_format *pix = &f->fmt.pix;
const struct tw9910_scale_ctrl *scale; const struct tw9910_scale_ctrl *scale;
...@@ -835,6 +847,7 @@ static struct soc_camera_ops tw9910_ops = { ...@@ -835,6 +847,7 @@ static struct soc_camera_ops tw9910_ops = {
.release = tw9910_release, .release = tw9910_release,
.start_capture = tw9910_start_capture, .start_capture = tw9910_start_capture,
.stop_capture = tw9910_stop_capture, .stop_capture = tw9910_stop_capture,
.set_crop = tw9910_set_crop,
.set_fmt = tw9910_set_fmt, .set_fmt = tw9910_set_fmt,
.try_fmt = tw9910_try_fmt, .try_fmt = tw9910_try_fmt,
.set_bus_param = tw9910_set_bus_param, .set_bus_param = tw9910_set_bus_param,
......
...@@ -74,7 +74,8 @@ struct soc_camera_host_ops { ...@@ -74,7 +74,8 @@ struct soc_camera_host_ops {
int (*resume)(struct soc_camera_device *); int (*resume)(struct soc_camera_device *);
int (*get_formats)(struct soc_camera_device *, int, int (*get_formats)(struct soc_camera_device *, int,
struct soc_camera_format_xlate *); struct soc_camera_format_xlate *);
int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *); int (*set_crop)(struct soc_camera_device *, struct v4l2_rect *);
int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
void (*init_videobuf)(struct videobuf_queue *, void (*init_videobuf)(struct videobuf_queue *,
struct soc_camera_device *); struct soc_camera_device *);
...@@ -159,7 +160,8 @@ struct soc_camera_ops { ...@@ -159,7 +160,8 @@ struct soc_camera_ops {
int (*release)(struct soc_camera_device *); int (*release)(struct soc_camera_device *);
int (*start_capture)(struct soc_camera_device *); int (*start_capture)(struct soc_camera_device *);
int (*stop_capture)(struct soc_camera_device *); int (*stop_capture)(struct soc_camera_device *);
int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *); int (*set_crop)(struct soc_camera_device *, struct v4l2_rect *);
int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
unsigned long (*query_bus_param)(struct soc_camera_device *); unsigned long (*query_bus_param)(struct soc_camera_device *);
int (*set_bus_param)(struct soc_camera_device *, unsigned long); int (*set_bus_param)(struct soc_camera_device *, unsigned long);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment