aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/sh_mobile_ceu_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:46:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:19:06 -0400
commit08590b9613f7f624fe3a052586eea2dbb3584b38 (patch)
treea893d250a4edf84e93794be59e2b1d859314c972 /drivers/media/video/sh_mobile_ceu_camera.c
parent961801bbb3448a86f0cc93747cecbfae686d81d1 (diff)
V4L/DVB (12529): soc-camera: switch to s_crop v4l2-subdev video operation
Remove set_crop soc-camera device method and switch to s_crop from v4l2-subdev video operations. Also extend non-i2c drivers to also hold a pointer to their v4l2-subdev instance in control device driver-data, i.e., in dev_get_drvdata((struct device *)to_soc_camera_control(icd)) 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.c110
1 files changed, 57 insertions, 53 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 499d1a235fd7..726cf0e4dc23 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -846,12 +846,16 @@ static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
846 * 3. if (2) failed, try to request the maximum image 846 * 3. if (2) failed, try to request the maximum image
847 */ 847 */
848static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, 848static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
849 struct v4l2_rect *rect) 849 struct v4l2_crop *a)
850{ 850{
851 struct v4l2_rect *rect = &a->c;
851 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 852 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
852 struct sh_mobile_ceu_dev *pcdev = ici->priv; 853 struct sh_mobile_ceu_dev *pcdev = ici->priv;
853 struct v4l2_rect cam_rect, target, cam_max; 854 struct v4l2_crop cam_crop;
855 struct v4l2_rect *cam_rect = &cam_crop.c, target, cam_max;
854 struct sh_mobile_ceu_cam *cam = icd->host_priv; 856 struct sh_mobile_ceu_cam *cam = icd->host_priv;
857 struct device *control = to_soc_camera_control(icd);
858 struct v4l2_subdev *sd = dev_get_drvdata(control);
855 unsigned int hscale = pcdev->cflcr & 0xffff; 859 unsigned int hscale = pcdev->cflcr & 0xffff;
856 unsigned int vscale = (pcdev->cflcr >> 16) & 0xffff; 860 unsigned int vscale = (pcdev->cflcr >> 16) & 0xffff;
857 unsigned short width, height; 861 unsigned short width, height;
@@ -859,80 +863,80 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
859 int ret; 863 int ret;
860 864
861 /* Scale back up into client units */ 865 /* Scale back up into client units */
862 cam_rect.left = size_src(rect->left, hscale); 866 cam_rect->left = size_src(rect->left, hscale);
863 cam_rect.width = size_src(rect->width, hscale); 867 cam_rect->width = size_src(rect->width, hscale);
864 cam_rect.top = size_src(rect->top, vscale); 868 cam_rect->top = size_src(rect->top, vscale);
865 cam_rect.height = size_src(rect->height, vscale); 869 cam_rect->height = size_src(rect->height, vscale);
866 870
867 target = cam_rect; 871 target = *cam_rect;
868 872
869 capsr = capture_save_reset(pcdev); 873 capsr = capture_save_reset(pcdev);
870 dev_dbg(&icd->dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); 874 dev_dbg(&icd->dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
871 875
872 /* First attempt - see if the client can deliver a perfect result */ 876 /* First attempt - see if the client can deliver a perfect result */
873 ret = icd->ops->set_crop(icd, &cam_rect); 877 ret = v4l2_subdev_call(sd, video, s_crop, &cam_crop);
874 if (!ret && !memcmp(&target, &cam_rect, sizeof(target))) { 878 if (!ret && !memcmp(&target, &cam_rect, sizeof(target))) {
875 dev_dbg(&icd->dev, "Camera S_CROP successful for %ux%u@%u:%u\n", 879 dev_dbg(&icd->dev, "Camera S_CROP successful for %ux%u@%u:%u\n",
876 cam_rect.width, cam_rect.height, 880 cam_rect->width, cam_rect->height,
877 cam_rect.left, cam_rect.top); 881 cam_rect->left, cam_rect->top);
878 goto ceu_set_rect; 882 goto ceu_set_rect;
879 } 883 }
880 884
881 /* Try to fix cropping, that camera hasn't managed to do */ 885 /* Try to fix cropping, that camera hasn't managed to do */
882 dev_dbg(&icd->dev, "Fix camera S_CROP %d for %ux%u@%u:%u" 886 dev_dbg(&icd->dev, "Fix camera S_CROP %d for %ux%u@%u:%u"
883 " to %ux%u@%u:%u\n", 887 " to %ux%u@%u:%u\n",
884 ret, cam_rect.width, cam_rect.height, 888 ret, cam_rect->width, cam_rect->height,
885 cam_rect.left, cam_rect.top, 889 cam_rect->left, cam_rect->top,
886 target.width, target.height, target.left, target.top); 890 target.width, target.height, target.left, target.top);
887 891
888 /* 892 /*
889 * Popular special case - some cameras can only handle fixed sizes like 893 * Popular special case - some cameras can only handle fixed sizes like
890 * QVGA, VGA,... Take care to avoid infinite loop. 894 * QVGA, VGA,... Take care to avoid infinite loop.
891 */ 895 */
892 width = max(cam_rect.width, 1); 896 width = max(cam_rect->width, 1);
893 height = max(cam_rect.height, 1); 897 height = max(cam_rect->height, 1);
894 cam_max.width = size_src(icd->rect_max.width, hscale); 898 cam_max.width = size_src(icd->rect_max.width, hscale);
895 cam_max.left = size_src(icd->rect_max.left, hscale); 899 cam_max.left = size_src(icd->rect_max.left, hscale);
896 cam_max.height = size_src(icd->rect_max.height, vscale); 900 cam_max.height = size_src(icd->rect_max.height, vscale);
897 cam_max.top = size_src(icd->rect_max.top, vscale); 901 cam_max.top = size_src(icd->rect_max.top, vscale);
898 while (!ret && (is_smaller(&cam_rect, &target) || 902 while (!ret && (is_smaller(cam_rect, &target) ||
899 is_inside(&cam_rect, &target)) && 903 is_inside(cam_rect, &target)) &&
900 cam_max.width >= width && cam_max.height >= height) { 904 cam_max.width >= width && cam_max.height >= height) {
901 905
902 width *= 2; 906 width *= 2;
903 height *= 2; 907 height *= 2;
904 cam_rect.width = width; 908 cam_rect->width = width;
905 cam_rect.height = height; 909 cam_rect->height = height;
906 910
907 /* We do not know what the camera is capable of, play safe */ 911 /* We do not know what the camera is capable of, play safe */
908 if (cam_rect.left > target.left) 912 if (cam_rect->left > target.left)
909 cam_rect.left = cam_max.left; 913 cam_rect->left = cam_max.left;
910 914
911 if (cam_rect.left + cam_rect.width < target.left + target.width) 915 if (cam_rect->left + cam_rect->width < target.left + target.width)
912 cam_rect.width = target.left + target.width - 916 cam_rect->width = target.left + target.width -
913 cam_rect.left; 917 cam_rect->left;
914 918
915 if (cam_rect.top > target.top) 919 if (cam_rect->top > target.top)
916 cam_rect.top = cam_max.top; 920 cam_rect->top = cam_max.top;
917 921
918 if (cam_rect.top + cam_rect.height < target.top + target.height) 922 if (cam_rect->top + cam_rect->height < target.top + target.height)
919 cam_rect.height = target.top + target.height - 923 cam_rect->height = target.top + target.height -
920 cam_rect.top; 924 cam_rect->top;
921 925
922 if (cam_rect.width + cam_rect.left > 926 if (cam_rect->width + cam_rect->left >
923 cam_max.width + cam_max.left) 927 cam_max.width + cam_max.left)
924 cam_rect.left = max(cam_max.width + cam_max.left - 928 cam_rect->left = max(cam_max.width + cam_max.left -
925 cam_rect.width, cam_max.left); 929 cam_rect->width, cam_max.left);
926 930
927 if (cam_rect.height + cam_rect.top > 931 if (cam_rect->height + cam_rect->top >
928 cam_max.height + cam_max.top) 932 cam_max.height + cam_max.top)
929 cam_rect.top = max(cam_max.height + cam_max.top - 933 cam_rect->top = max(cam_max.height + cam_max.top -
930 cam_rect.height, cam_max.top); 934 cam_rect->height, cam_max.top);
931 935
932 ret = icd->ops->set_crop(icd, &cam_rect); 936 ret = v4l2_subdev_call(sd, video, s_crop, &cam_crop);
933 dev_dbg(&icd->dev, "Camera S_CROP %d for %ux%u@%u:%u\n", 937 dev_dbg(&icd->dev, "Camera S_CROP %d for %ux%u@%u:%u\n",
934 ret, cam_rect.width, cam_rect.height, 938 ret, cam_rect->width, cam_rect->height,
935 cam_rect.left, cam_rect.top); 939 cam_rect->left, cam_rect->top);
936 } 940 }
937 941
938 /* 942 /*
@@ -941,30 +945,30 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
941 */ 945 */
942 if ((ret < 0 && (is_smaller(&icd->rect_current, rect) || 946 if ((ret < 0 && (is_smaller(&icd->rect_current, rect) ||
943 is_inside(&icd->rect_current, rect))) || 947 is_inside(&icd->rect_current, rect))) ||
944 is_smaller(&cam_rect, &target) || is_inside(&cam_rect, &target)) { 948 is_smaller(cam_rect, &target) || is_inside(cam_rect, &target)) {
945 /* 949 /*
946 * The camera failed to configure a suitable cropping, 950 * The camera failed to configure a suitable cropping,
947 * we cannot use the current rectangle, set to max 951 * we cannot use the current rectangle, set to max
948 */ 952 */
949 cam_rect = cam_max; 953 *cam_rect = cam_max;
950 ret = icd->ops->set_crop(icd, &cam_rect); 954 ret = v4l2_subdev_call(sd, video, s_crop, &cam_crop);
951 dev_dbg(&icd->dev, "Camera S_CROP %d for max %ux%u@%u:%u\n", 955 dev_dbg(&icd->dev, "Camera S_CROP %d for max %ux%u@%u:%u\n",
952 ret, cam_rect.width, cam_rect.height, 956 ret, cam_rect->width, cam_rect->height,
953 cam_rect.left, cam_rect.top); 957 cam_rect->left, cam_rect->top);
954 if (ret < 0) 958 if (ret < 0 && ret != -ENOIOCTLCMD)
955 /* All failed, hopefully resume current capture */ 959 /* All failed, hopefully resume current capture */
956 goto resume_capture; 960 goto resume_capture;
957 961
958 /* Finally, adjust the target rectangle */ 962 /* Finally, adjust the target rectangle */
959 if (target.width > cam_rect.width) 963 if (target.width > cam_rect->width)
960 target.width = cam_rect.width; 964 target.width = cam_rect->width;
961 if (target.height > cam_rect.height) 965 if (target.height > cam_rect->height)
962 target.height = cam_rect.height; 966 target.height = cam_rect->height;
963 if (target.left + target.width > cam_rect.left + cam_rect.width) 967 if (target.left + target.width > cam_rect->left + cam_rect->width)
964 target.left = cam_rect.left + cam_rect.width - 968 target.left = cam_rect->left + cam_rect->width -
965 target.width; 969 target.width;
966 if (target.top + target.height > cam_rect.top + cam_rect.height) 970 if (target.top + target.height > cam_rect->top + cam_rect->height)
967 target.top = cam_rect.top + cam_rect.height - 971 target.top = cam_rect->top + cam_rect->height -
968 target.height; 972 target.height;
969 } 973 }
970 974
@@ -978,14 +982,14 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
978 */ 982 */
979 dev_dbg(&icd->dev, 983 dev_dbg(&icd->dev,
980 "SH S_CROP from %ux%u@%u:%u to %ux%u@%u:%u, scale to %ux%u@%u:%u\n", 984 "SH S_CROP from %ux%u@%u:%u to %ux%u@%u:%u, scale to %ux%u@%u:%u\n",
981 cam_rect.width, cam_rect.height, cam_rect.left, cam_rect.top, 985 cam_rect->width, cam_rect->height, cam_rect->left, cam_rect->top,
982 target.width, target.height, target.left, target.top, 986 target.width, target.height, target.left, target.top,
983 rect->width, rect->height, rect->left, rect->top); 987 rect->width, rect->height, rect->left, rect->top);
984 988
985 ret = 0; 989 ret = 0;
986 990
987ceu_set_rect: 991ceu_set_rect:
988 cam->camera_rect = cam_rect; 992 cam->camera_rect = *cam_rect;
989 993
990 rect->width = size_dst(target.width, hscale); 994 rect->width = size_dst(target.width, hscale);
991 rect->left = size_dst(target.left, hscale); 995 rect->left = size_dst(target.left, hscale);