aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/sh_mobile_ceu_camera.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-03-21 07:16:05 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-15 15:13:22 -0400
commitfc13baff743cf9fa49035974471c17378bfe6146 (patch)
tree9bd286e49b1dfb0abec5d12fecd429ce1fd39a0e /drivers/media/video/sh_mobile_ceu_camera.c
parent914f05c8118e17d65c4626ae3ed2edcf79f00031 (diff)
[media] sh_mobile_ceu_camera: Support user-configurable line stride
In image mode, the CEU allows configurable line strides up to 8188 pixels. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> [g.liakhovetski@gmx.de: unify sh_mobile_ceu_set_rect() in data-fetch mode] Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/sh_mobile_ceu_camera.c')
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 79bec15cc4a..2ffeb21dfe3 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -342,19 +342,15 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
342 342
343 ceu_write(pcdev, top1, phys_addr_top); 343 ceu_write(pcdev, top1, phys_addr_top);
344 if (V4L2_FIELD_NONE != pcdev->field) { 344 if (V4L2_FIELD_NONE != pcdev->field) {
345 if (planar) 345 phys_addr_bottom = phys_addr_top + icd->bytesperline;
346 phys_addr_bottom = phys_addr_top + icd->user_width;
347 else
348 phys_addr_bottom = phys_addr_top + icd->bytesperline;
349 ceu_write(pcdev, bottom1, phys_addr_bottom); 346 ceu_write(pcdev, bottom1, phys_addr_bottom);
350 } 347 }
351 348
352 if (planar) { 349 if (planar) {
353 phys_addr_top += icd->user_width * 350 phys_addr_top += icd->bytesperline * icd->user_height;
354 icd->user_height;
355 ceu_write(pcdev, top2, phys_addr_top); 351 ceu_write(pcdev, top2, phys_addr_top);
356 if (V4L2_FIELD_NONE != pcdev->field) { 352 if (V4L2_FIELD_NONE != pcdev->field) {
357 phys_addr_bottom = phys_addr_top + icd->user_width; 353 phys_addr_bottom = phys_addr_top + icd->bytesperline;
358 ceu_write(pcdev, bottom2, phys_addr_bottom); 354 ceu_write(pcdev, bottom2, phys_addr_bottom);
359 } 355 }
360 } 356 }
@@ -681,10 +677,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
681 in_width *= 2; 677 in_width *= 2;
682 left_offset *= 2; 678 left_offset *= 2;
683 } 679 }
684 cdwdr_width = width;
685 } else { 680 } else {
686 int bytes_per_line = soc_mbus_bytes_per_line(width,
687 icd->current_fmt->host_fmt);
688 unsigned int w_factor; 681 unsigned int w_factor;
689 682
690 switch (icd->current_fmt->host_fmt->packing) { 683 switch (icd->current_fmt->host_fmt->packing) {
@@ -697,13 +690,10 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
697 690
698 in_width = cam->width * w_factor; 691 in_width = cam->width * w_factor;
699 left_offset *= w_factor; 692 left_offset *= w_factor;
700
701 if (bytes_per_line < 0)
702 cdwdr_width = width;
703 else
704 cdwdr_width = bytes_per_line;
705 } 693 }
706 694
695 cdwdr_width = icd->bytesperline;
696
707 height = icd->user_height; 697 height = icd->user_height;
708 in_height = cam->height; 698 in_height = cam->height;
709 if (V4L2_FIELD_NONE != pcdev->field) { 699 if (V4L2_FIELD_NONE != pcdev->field) {
@@ -1848,6 +1838,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1848 return 0; 1838 return 0;
1849} 1839}
1850 1840
1841#define CEU_CHDW_MAX 8188U /* Maximum line stride */
1842
1851static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1843static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1852 struct v4l2_format *f) 1844 struct v4l2_format *f)
1853{ 1845{
@@ -1926,10 +1918,20 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1926 pix->width = width; 1918 pix->width = width;
1927 if (mf.height > height) 1919 if (mf.height > height)
1928 pix->height = height; 1920 pix->height = height;
1921
1922 pix->bytesperline = max(pix->bytesperline, pix->width);
1923 pix->bytesperline = min(pix->bytesperline, CEU_CHDW_MAX);
1924 pix->bytesperline &= ~3;
1925 break;
1926
1927 default:
1928 /* Configurable stride isn't supported in pass-through mode. */
1929 pix->bytesperline = 0;
1929 } 1930 }
1930 1931
1931 pix->width &= ~3; 1932 pix->width &= ~3;
1932 pix->height &= ~3; 1933 pix->height &= ~3;
1934 pix->sizeimage = 0;
1933 1935
1934 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n", 1936 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1935 __func__, ret, pix->pixelformat, pix->width, pix->height); 1937 __func__, ret, pix->pixelformat, pix->width, pix->height);
@@ -2148,6 +2150,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2148 pcdev->ici.nr = pdev->id; 2150 pcdev->ici.nr = pdev->id;
2149 pcdev->ici.drv_name = dev_name(&pdev->dev); 2151 pcdev->ici.drv_name = dev_name(&pdev->dev);
2150 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 2152 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
2153 pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE;
2151 2154
2152 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 2155 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2153 if (IS_ERR(pcdev->alloc_ctx)) { 2156 if (IS_ERR(pcdev->alloc_ctx)) {