aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/cafe_ccic.c87
1 files changed, 74 insertions, 13 deletions
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index be35e6965829..2ffb6df955b3 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -180,6 +180,7 @@ struct cafe_camera
180 /* Current operating parameters */ 180 /* Current operating parameters */
181 u32 sensor_type; /* Currently ov7670 only */ 181 u32 sensor_type; /* Currently ov7670 only */
182 struct v4l2_pix_format pix_format; 182 struct v4l2_pix_format pix_format;
183 enum v4l2_mbus_pixelcode mbus_code;
183 184
184 /* Locks */ 185 /* Locks */
185 struct mutex s_mutex; /* Access to this structure */ 186 struct mutex s_mutex; /* Access to this structure */
@@ -207,6 +208,49 @@ static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
207 return container_of(dev, struct cafe_camera, v4l2_dev); 208 return container_of(dev, struct cafe_camera, v4l2_dev);
208} 209}
209 210
211static struct cafe_format_struct {
212 __u8 *desc;
213 __u32 pixelformat;
214 int bpp; /* Bytes per pixel */
215 enum v4l2_mbus_pixelcode mbus_code;
216} cafe_formats[] = {
217 {
218 .desc = "YUYV 4:2:2",
219 .pixelformat = V4L2_PIX_FMT_YUYV,
220 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
221 .bpp = 2,
222 },
223 {
224 .desc = "RGB 444",
225 .pixelformat = V4L2_PIX_FMT_RGB444,
226 .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
227 .bpp = 2,
228 },
229 {
230 .desc = "RGB 565",
231 .pixelformat = V4L2_PIX_FMT_RGB565,
232 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
233 .bpp = 2,
234 },
235 {
236 .desc = "Raw RGB Bayer",
237 .pixelformat = V4L2_PIX_FMT_SBGGR8,
238 .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,
239 .bpp = 1
240 },
241};
242#define N_CAFE_FMTS ARRAY_SIZE(cafe_formats)
243
244static struct cafe_format_struct *cafe_find_format(u32 pixelformat)
245{
246 unsigned i;
247
248 for (i = 0; i < N_CAFE_FMTS; i++)
249 if (cafe_formats[i].pixelformat == pixelformat)
250 return cafe_formats + i;
251 /* Not found? Then return the first format. */
252 return cafe_formats;
253}
210 254
211/* 255/*
212 * Start over with DMA buffers - dev_lock needed. 256 * Start over with DMA buffers - dev_lock needed.
@@ -812,15 +856,15 @@ static int cafe_cam_set_flip(struct cafe_camera *cam)
812 856
813static int cafe_cam_configure(struct cafe_camera *cam) 857static int cafe_cam_configure(struct cafe_camera *cam)
814{ 858{
815 struct v4l2_format fmt; 859 struct v4l2_mbus_framefmt mbus_fmt;
816 int ret; 860 int ret;
817 861
818 if (cam->state != S_IDLE) 862 if (cam->state != S_IDLE)
819 return -EINVAL; 863 return -EINVAL;
820 fmt.fmt.pix = cam->pix_format; 864 v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
821 ret = sensor_call(cam, core, init, 0); 865 ret = sensor_call(cam, core, init, 0);
822 if (ret == 0) 866 if (ret == 0)
823 ret = sensor_call(cam, video, s_fmt, &fmt); 867 ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
824 /* 868 /*
825 * OV7670 does weird things if flip is set *before* format... 869 * OV7670 does weird things if flip is set *before* format...
826 */ 870 */
@@ -1481,7 +1525,7 @@ static int cafe_vidioc_querycap(struct file *file, void *priv,
1481/* 1525/*
1482 * The default format we use until somebody says otherwise. 1526 * The default format we use until somebody says otherwise.
1483 */ 1527 */
1484static struct v4l2_pix_format cafe_def_pix_format = { 1528static const struct v4l2_pix_format cafe_def_pix_format = {
1485 .width = VGA_WIDTH, 1529 .width = VGA_WIDTH,
1486 .height = VGA_HEIGHT, 1530 .height = VGA_HEIGHT,
1487 .pixelformat = V4L2_PIX_FMT_YUYV, 1531 .pixelformat = V4L2_PIX_FMT_YUYV,
@@ -1490,28 +1534,38 @@ static struct v4l2_pix_format cafe_def_pix_format = {
1490 .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, 1534 .sizeimage = VGA_WIDTH*VGA_HEIGHT*2,
1491}; 1535};
1492 1536
1537static const enum v4l2_mbus_pixelcode cafe_def_mbus_code =
1538 V4L2_MBUS_FMT_YUYV8_2X8;
1539
1493static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp, 1540static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
1494 void *priv, struct v4l2_fmtdesc *fmt) 1541 void *priv, struct v4l2_fmtdesc *fmt)
1495{ 1542{
1496 struct cafe_camera *cam = priv; 1543 if (fmt->index >= N_CAFE_FMTS)
1497 int ret; 1544 return -EINVAL;
1498 1545 strlcpy(fmt->description, cafe_formats[fmt->index].desc,
1499 mutex_lock(&cam->s_mutex); 1546 sizeof(fmt->description));
1500 ret = sensor_call(cam, video, enum_fmt, fmt); 1547 fmt->pixelformat = cafe_formats[fmt->index].pixelformat;
1501 mutex_unlock(&cam->s_mutex); 1548 return 0;
1502 return ret;
1503} 1549}
1504 1550
1505
1506static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, 1551static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
1507 struct v4l2_format *fmt) 1552 struct v4l2_format *fmt)
1508{ 1553{
1509 struct cafe_camera *cam = priv; 1554 struct cafe_camera *cam = priv;
1555 struct cafe_format_struct *f;
1556 struct v4l2_pix_format *pix = &fmt->fmt.pix;
1557 struct v4l2_mbus_framefmt mbus_fmt;
1510 int ret; 1558 int ret;
1511 1559
1560 f = cafe_find_format(pix->pixelformat);
1561 pix->pixelformat = f->pixelformat;
1562 v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code);
1512 mutex_lock(&cam->s_mutex); 1563 mutex_lock(&cam->s_mutex);
1513 ret = sensor_call(cam, video, try_fmt, fmt); 1564 ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
1514 mutex_unlock(&cam->s_mutex); 1565 mutex_unlock(&cam->s_mutex);
1566 v4l2_fill_pix_format(pix, &mbus_fmt);
1567 pix->bytesperline = pix->width * f->bpp;
1568 pix->sizeimage = pix->height * pix->bytesperline;
1515 return ret; 1569 return ret;
1516} 1570}
1517 1571
@@ -1519,6 +1573,7 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
1519 struct v4l2_format *fmt) 1573 struct v4l2_format *fmt)
1520{ 1574{
1521 struct cafe_camera *cam = priv; 1575 struct cafe_camera *cam = priv;
1576 struct cafe_format_struct *f;
1522 int ret; 1577 int ret;
1523 1578
1524 /* 1579 /*
@@ -1527,6 +1582,9 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
1527 */ 1582 */
1528 if (cam->state != S_IDLE || cam->n_sbufs > 0) 1583 if (cam->state != S_IDLE || cam->n_sbufs > 0)
1529 return -EBUSY; 1584 return -EBUSY;
1585
1586 f = cafe_find_format(fmt->fmt.pix.pixelformat);
1587
1530 /* 1588 /*
1531 * See if the formatting works in principle. 1589 * See if the formatting works in principle.
1532 */ 1590 */
@@ -1539,6 +1597,8 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
1539 */ 1597 */
1540 mutex_lock(&cam->s_mutex); 1598 mutex_lock(&cam->s_mutex);
1541 cam->pix_format = fmt->fmt.pix; 1599 cam->pix_format = fmt->fmt.pix;
1600 cam->mbus_code = f->mbus_code;
1601
1542 /* 1602 /*
1543 * Make sure we have appropriate DMA buffers. 1603 * Make sure we have appropriate DMA buffers.
1544 */ 1604 */
@@ -1915,6 +1975,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1915 init_waitqueue_head(&cam->iowait); 1975 init_waitqueue_head(&cam->iowait);
1916 cam->pdev = pdev; 1976 cam->pdev = pdev;
1917 cam->pix_format = cafe_def_pix_format; 1977 cam->pix_format = cafe_def_pix_format;
1978 cam->mbus_code = cafe_def_mbus_code;
1918 INIT_LIST_HEAD(&cam->dev_list); 1979 INIT_LIST_HEAD(&cam->dev_list);
1919 INIT_LIST_HEAD(&cam->sb_avail); 1980 INIT_LIST_HEAD(&cam->sb_avail);
1920 INIT_LIST_HEAD(&cam->sb_full); 1981 INIT_LIST_HEAD(&cam->sb_full);