Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] V4L: sh_mobile_ceu_camera: maximum image size depends on the hardware version

Newer CEU versions, e.g., the one, used on sh7372, support image sizes
larger than 2560x1920. Retrieve maximum sizes from platform properties.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Guennadi Liakhovetski and committed by
Mauro Carvalho Chehab
48e971cd 7705b6d8

+29 -8
+27 -8
drivers/media/video/sh_mobile_ceu_camera.c
··· 112 112 113 113 u32 cflcr; 114 114 115 + /* static max sizes either from platform data or default */ 116 + int max_width; 117 + int max_height; 118 + 115 119 enum v4l2_field field; 116 120 int sequence; 117 121 ··· 1085 1081 if (ret < 0) 1086 1082 return ret; 1087 1083 1088 - while ((mf.width > 2560 || mf.height > 1920) && shift < 4) { 1084 + /* 1085 + * All currently existing CEU implementations support 2560x1920 1086 + * or larger frames. If the sensor is proposing too big a frame, 1087 + * don't bother with possibly supportred by the CEU larger 1088 + * sizes, just try VGA multiples. If needed, this can be 1089 + * adjusted in the future. 1090 + */ 1091 + while ((mf.width > pcdev->max_width || 1092 + mf.height > pcdev->max_height) && shift < 4) { 1089 1093 /* Try 2560x1920, 1280x960, 640x480, 320x240 */ 1090 1094 mf.width = 2560 >> shift; 1091 1095 mf.height = 1920 >> shift; ··· 1389 1377 static int client_s_fmt(struct soc_camera_device *icd, 1390 1378 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1391 1379 { 1380 + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1381 + struct sh_mobile_ceu_dev *pcdev = ici->priv; 1392 1382 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1393 1383 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1394 1384 struct device *dev = icd->parent; ··· 1424 1410 if (ret < 0) 1425 1411 return ret; 1426 1412 1427 - max_width = min(cap.bounds.width, 2560); 1428 - max_height = min(cap.bounds.height, 1920); 1413 + max_width = min(cap.bounds.width, pcdev->max_width); 1414 + max_height = min(cap.bounds.height, pcdev->max_height); 1429 1415 1430 1416 /* Camera set a format, but geometry is not precise, try to improve */ 1431 1417 tmp_w = mf->width; ··· 1565 1551 if (ret < 0) 1566 1552 return ret; 1567 1553 1568 - if (mf.width > 2560 || mf.height > 1920) 1554 + if (mf.width > pcdev->max_width || mf.height > pcdev->max_height) 1569 1555 return -EINVAL; 1570 1556 1571 1557 /* 4. Calculate camera scales */ ··· 1848 1834 static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1849 1835 struct v4l2_format *f) 1850 1836 { 1837 + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1838 + struct sh_mobile_ceu_dev *pcdev = ici->priv; 1851 1839 const struct soc_camera_format_xlate *xlate; 1852 1840 struct v4l2_pix_format *pix = &f->fmt.pix; 1853 1841 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); ··· 1870 1854 /* FIXME: calculate using depth and bus width */ 1871 1855 1872 1856 /* CFSZR requires height and width to be 4-pixel aligned */ 1873 - v4l_bound_align_image(&pix->width, 2, 2560, 2, 1874 - &pix->height, 4, 1920, 2, 0); 1857 + v4l_bound_align_image(&pix->width, 2, pcdev->max_width, 2, 1858 + &pix->height, 4, pcdev->max_height, 2, 0); 1875 1859 1876 1860 width = pix->width; 1877 1861 height = pix->height; ··· 1906 1890 * requested a bigger rectangle, it will not return a 1907 1891 * smaller one. 1908 1892 */ 1909 - mf.width = 2560; 1910 - mf.height = 1920; 1893 + mf.width = pcdev->max_width; 1894 + mf.height = pcdev->max_height; 1911 1895 ret = v4l2_device_call_until_err(sd->v4l2_dev, 1912 1896 soc_camera_grp_id(icd), video, 1913 1897 try_mbus_fmt, &mf); ··· 2097 2081 dev_err(&pdev->dev, "CEU platform data not set.\n"); 2098 2082 goto exit_kfree; 2099 2083 } 2084 + 2085 + pcdev->max_width = pcdev->pdata->max_width ? : 2560; 2086 + pcdev->max_height = pcdev->pdata->max_height ? : 1920; 2100 2087 2101 2088 base = ioremap_nocache(res->start, resource_size(res)); 2102 2089 if (!base) {
+2
include/media/sh_mobile_ceu.h
··· 18 18 19 19 struct sh_mobile_ceu_info { 20 20 unsigned long flags; 21 + int max_width; 22 + int max_height; 21 23 struct sh_mobile_ceu_companion *csi2; 22 24 }; 23 25