aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mx3_camera.c
diff options
context:
space:
mode:
authorAlberto Panizzo <maramaopercheseimorto@gmail.com>2011-01-17 04:52:10 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:14 -0400
commita48be1d626ceb05b58a980a962214431af8041e8 (patch)
treeba83dcc99d9884dfbc4f731aeed61f7985f00728 /drivers/media/video/mx3_camera.c
parent44facdc8c43a8b5172d6cbe995845c9889561aa0 (diff)
[media] V4L: mx3_camera: fix capture issues for non 8-bit per pixel formats
If the camera was set to output formats like RGB565 YUYV or SBGGR10, the resulting image was scrambled due to erroneous interpretations of horizontal parameter's units. This patch in fourcc_to_ipu_pix, eliminate also the pixel formats mappings that, first are not used within mainline code and second, standing at the datasheets, they will not work properly: The IPU internal bus support only the following data formatting (44.1.1.3 Data Flows and Formats): 1 YUV 4:4:4 or RGB-8 bits per color component 2 YUV 4:4:4 or RGB-10 bits per color component 3 Generic data (from sensor to the system memory only) And format conversions are done: - from memory: unpacking from other formats to IPU supported ones - to memory: packing in the inverse order. So, assigning a packing/unpacking strategy to the IPU for those formats will produce a packing to memory and not the inverse. Signed-off-by: Alberto Panizzo <maramaopercheseimorto@gmail.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mx3_camera.c')
-rw-r--r--drivers/media/video/mx3_camera.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 1cfff4132a0b..c8c6c03a6a62 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -324,14 +324,10 @@ static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
324{ 324{
325 /* Add more formats as need arises and test possibilities appear... */ 325 /* Add more formats as need arises and test possibilities appear... */
326 switch (fourcc) { 326 switch (fourcc) {
327 case V4L2_PIX_FMT_RGB565:
328 return IPU_PIX_FMT_RGB565;
329 case V4L2_PIX_FMT_RGB24: 327 case V4L2_PIX_FMT_RGB24:
330 return IPU_PIX_FMT_RGB24; 328 return IPU_PIX_FMT_RGB24;
331 case V4L2_PIX_FMT_RGB332: 329 case V4L2_PIX_FMT_UYVY:
332 return IPU_PIX_FMT_RGB332; 330 case V4L2_PIX_FMT_RGB565:
333 case V4L2_PIX_FMT_YUV422P:
334 return IPU_PIX_FMT_YVU422P;
335 default: 331 default:
336 return IPU_PIX_FMT_GENERIC; 332 return IPU_PIX_FMT_GENERIC;
337 } 333 }
@@ -359,9 +355,31 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
359 355
360 /* This is the configuration of one sg-element */ 356 /* This is the configuration of one sg-element */
361 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); 357 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc);
362 video->out_width = icd->user_width; 358
363 video->out_height = icd->user_height; 359 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
364 video->out_stride = icd->user_width; 360 /*
361 * If the IPU DMA channel is configured to transport
362 * generic 8-bit data, we have to set up correctly the
363 * geometry parameters upon the current pixel format.
364 * So, since the DMA horizontal parameters are expressed
365 * in bytes not pixels, convert these in the right unit.
366 */
367 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
368 icd->current_fmt->host_fmt);
369 BUG_ON(bytes_per_line <= 0);
370
371 video->out_width = bytes_per_line;
372 video->out_height = icd->user_height;
373 video->out_stride = bytes_per_line;
374 } else {
375 /*
376 * For IPU known formats the pixel unit will be managed
377 * successfully by the IPU code
378 */
379 video->out_width = icd->user_width;
380 video->out_height = icd->user_height;
381 video->out_stride = icd->user_width;
382 }
365 383
366#ifdef DEBUG 384#ifdef DEBUG
367 /* helps to see what DMA actually has written */ 385 /* helps to see what DMA actually has written */
@@ -734,18 +752,36 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
734 if (xlate) { 752 if (xlate) {
735 xlate->host_fmt = fmt; 753 xlate->host_fmt = fmt;
736 xlate->code = code; 754 xlate->code = code;
755 dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
756 (fmt->fourcc >> (0*8)) & 0xFF,
757 (fmt->fourcc >> (1*8)) & 0xFF,
758 (fmt->fourcc >> (2*8)) & 0xFF,
759 (fmt->fourcc >> (3*8)) & 0xFF);
737 xlate++; 760 xlate++;
738 dev_dbg(dev, "Providing format %x in pass-through mode\n",
739 xlate->host_fmt->fourcc);
740 } 761 }
741 762
742 return formats; 763 return formats;
743} 764}
744 765
745static void configure_geometry(struct mx3_camera_dev *mx3_cam, 766static void configure_geometry(struct mx3_camera_dev *mx3_cam,
746 unsigned int width, unsigned int height) 767 unsigned int width, unsigned int height,
768 enum v4l2_mbus_pixelcode code)
747{ 769{
748 u32 ctrl, width_field, height_field; 770 u32 ctrl, width_field, height_field;
771 const struct soc_mbus_pixelfmt *fmt;
772
773 fmt = soc_mbus_get_fmtdesc(code);
774 BUG_ON(!fmt);
775
776 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
777 /*
778 * As the CSI will be configured to output BAYER, here
779 * the width parameter count the number of samples to
780 * capture to complete the whole image width.
781 */
782 width *= soc_mbus_samples_per_pixel(fmt);
783 BUG_ON(width < 0);
784 }
749 785
750 /* Setup frame size - this cannot be changed on-the-fly... */ 786 /* Setup frame size - this cannot be changed on-the-fly... */
751 width_field = width - 1; 787 width_field = width - 1;
@@ -854,7 +890,7 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
854 return ret; 890 return ret;
855 } 891 }
856 892
857 configure_geometry(mx3_cam, mf.width, mf.height); 893 configure_geometry(mx3_cam, mf.width, mf.height, mf.code);
858 } 894 }
859 895
860 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 896 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
@@ -897,7 +933,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
897 * mxc_v4l2_s_fmt() 933 * mxc_v4l2_s_fmt()
898 */ 934 */
899 935
900 configure_geometry(mx3_cam, pix->width, pix->height); 936 configure_geometry(mx3_cam, pix->width, pix->height, xlate->code);
901 937
902 mf.width = pix->width; 938 mf.width = pix->width;
903 mf.height = pix->height; 939 mf.height = pix->height;