diff options
author | Sandor Yu <R01008@freescale.com> | 2014-04-11 01:37:54 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-17 22:19:11 -0400 |
commit | 1f991ca3123275a7e47bee3badc7ed991ead3cb2 (patch) | |
tree | e718412efd2c2fecd8a1921a9b3836a7c0c72517 | |
parent | f8fd69100cc9a83fc4bc4b9e4c7bc1d37cc5b61a (diff) |
ENGR00307014-03 v4l2 capture: support for vadc
-Add v4l2 capture ioctl VIDIOC_S_INPUT, VIDIOC_G_INPUT,VIDIOC_ENUMINPUT,
VIDIOC_S_STD,VIDIOC_G_STD support.
-Add NTSC, PAL format define.
-Add parameter cam_input_fmt to save camera sensor format.
Signed-off-by: Sandor Yu <R01008@freescale.com>
-rw-r--r-- | drivers/media/platform/mxc/capture/csi_v4l2_capture.c | 316 |
1 files changed, 298 insertions, 18 deletions
diff --git a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c index fe8594363a7a..f56faef7734b 100644 --- a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c | |||
@@ -50,6 +50,7 @@ static void csi_v4l2_master_detach(struct v4l2_int_device *slave); | |||
50 | static u8 camera_power(cam_data *cam, bool cameraOn); | 50 | static u8 camera_power(cam_data *cam, bool cameraOn); |
51 | struct v4l2_crop crop_current; | 51 | struct v4l2_crop crop_current; |
52 | struct v4l2_window win_current; | 52 | struct v4l2_window win_current; |
53 | static struct v4l2_format cam_input_fmt; | ||
53 | 54 | ||
54 | /*! Information about this driver. */ | 55 | /*! Information about this driver. */ |
55 | static struct v4l2_int_master csi_v4l2_master = { | 56 | static struct v4l2_int_master csi_v4l2_master = { |
@@ -97,6 +98,96 @@ static struct v4l2_queryctrl pxp_controls[] = { | |||
97 | }, | 98 | }, |
98 | }; | 99 | }; |
99 | 100 | ||
101 | /*! List of TV input video formats supported. The video formats is corresponding | ||
102 | * to the v4l2_id in video_fmt_t. | ||
103 | * Currently, only PAL and NTSC is supported. Needs to be expanded in the | ||
104 | * future. | ||
105 | */ | ||
106 | typedef enum _video_fmt_idx { | ||
107 | TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */ | ||
108 | TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */ | ||
109 | TV_NOT_LOCKED, /*!< Not locked on a signal. */ | ||
110 | } video_fmt_idx; | ||
111 | |||
112 | /*! Number of video standards supported (including 'not locked' signal). */ | ||
113 | #define TV_STD_MAX (TV_NOT_LOCKED + 1) | ||
114 | |||
115 | /*! Video format structure. */ | ||
116 | typedef struct _video_fmt_t { | ||
117 | int v4l2_id; /*!< Video for linux ID. */ | ||
118 | char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */ | ||
119 | u16 raw_width; /*!< Raw width. */ | ||
120 | u16 raw_height; /*!< Raw height. */ | ||
121 | u16 active_width; /*!< Active width. */ | ||
122 | u16 active_height; /*!< Active height. */ | ||
123 | u16 active_top; /*!< Active top. */ | ||
124 | u16 active_left; /*!< Active left. */ | ||
125 | } video_fmt_t; | ||
126 | |||
127 | /*! | ||
128 | * Description of video formats supported. | ||
129 | * | ||
130 | * PAL: raw=720x625, active=720x576. | ||
131 | * NTSC: raw=720x525, active=720x480. | ||
132 | */ | ||
133 | static video_fmt_t video_fmts[] = { | ||
134 | { /*! NTSC */ | ||
135 | .v4l2_id = V4L2_STD_NTSC, | ||
136 | .name = "NTSC", | ||
137 | .raw_width = 720, /* SENS_FRM_WIDTH */ | ||
138 | .raw_height = 525, /* SENS_FRM_HEIGHT */ | ||
139 | .active_width = 720, /* ACT_FRM_WIDTH */ | ||
140 | .active_height = 480, /* ACT_FRM_HEIGHT */ | ||
141 | .active_top = 13, | ||
142 | .active_left = 0, | ||
143 | }, | ||
144 | { /*! (B, G, H, I, N) PAL */ | ||
145 | .v4l2_id = V4L2_STD_PAL, | ||
146 | .name = "PAL", | ||
147 | .raw_width = 720, | ||
148 | .raw_height = 625, | ||
149 | .active_width = 720, | ||
150 | .active_height = 576, | ||
151 | .active_top = 0, | ||
152 | .active_left = 0, | ||
153 | }, | ||
154 | { /*! Unlocked standard */ | ||
155 | .v4l2_id = V4L2_STD_ALL, | ||
156 | .name = "Autodetect", | ||
157 | .raw_width = 720, | ||
158 | .raw_height = 625, | ||
159 | .active_width = 720, | ||
160 | .active_height = 576, | ||
161 | .active_top = 0, | ||
162 | .active_left = 0, | ||
163 | }, | ||
164 | }; | ||
165 | |||
166 | #define CSI_V4L2_CAPTURE_NUM_INPUTS 2 | ||
167 | static struct v4l2_input csi_capture_inputs[CSI_V4L2_CAPTURE_NUM_INPUTS] = { | ||
168 | { | ||
169 | .index = 0, | ||
170 | .name = "Camera", | ||
171 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
172 | .audioset = 0, | ||
173 | .tuner = 0, | ||
174 | .std = V4L2_STD_UNKNOWN, | ||
175 | .status = 0, | ||
176 | }, | ||
177 | { | ||
178 | .index = 1, | ||
179 | .name = "Vadc", | ||
180 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
181 | .audioset = 0, | ||
182 | .tuner = 0, | ||
183 | .std = V4L2_STD_UNKNOWN, | ||
184 | .status = 0, | ||
185 | }, | ||
186 | }; | ||
187 | |||
188 | /*!* Standard index of TV. */ | ||
189 | static video_fmt_idx video_index = TV_NOT_LOCKED; | ||
190 | |||
100 | /* Callback function triggered after PxP receives an EOF interrupt */ | 191 | /* Callback function triggered after PxP receives an EOF interrupt */ |
101 | static void pxp_dma_done(void *arg) | 192 | static void pxp_dma_done(void *arg) |
102 | { | 193 | { |
@@ -141,6 +232,23 @@ static int pxp_chan_init(cam_data *cam) | |||
141 | return 0; | 232 | return 0; |
142 | } | 233 | } |
143 | 234 | ||
235 | static int v4l2_fmt_2_pxp_fmt(int fmt) | ||
236 | { | ||
237 | int ret; | ||
238 | switch (fmt) { | ||
239 | case V4L2_PIX_FMT_YUV420: | ||
240 | ret = PXP_PIX_FMT_YUV420P2; | ||
241 | break; | ||
242 | case V4L2_PIX_FMT_RGB565: | ||
243 | case V4L2_PIX_FMT_YUYV: | ||
244 | case V4L2_PIX_FMT_UYVY: | ||
245 | case V4L2_PIX_FMT_YUV444: | ||
246 | default: | ||
247 | ret = fmt; | ||
248 | break; | ||
249 | } | ||
250 | return ret; | ||
251 | } | ||
144 | /* | 252 | /* |
145 | * Function to call PxP DMA driver and send our new V4L2 buffer | 253 | * Function to call PxP DMA driver and send our new V4L2 buffer |
146 | * through the PxP. | 254 | * through the PxP. |
@@ -200,7 +308,7 @@ static int pxp_process_update(cam_data *cam) | |||
200 | /* | 308 | /* |
201 | * Configure PxP for processing of new v4l2 buf | 309 | * Configure PxP for processing of new v4l2 buf |
202 | */ | 310 | */ |
203 | pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_UYVY; | 311 | pxp_conf->s0_param.pixel_fmt = v4l2_fmt_2_pxp_fmt(cam_input_fmt.fmt.pix.pixelformat); |
204 | pxp_conf->s0_param.color_key = -1; | 312 | pxp_conf->s0_param.color_key = -1; |
205 | pxp_conf->s0_param.color_key_enable = false; | 313 | pxp_conf->s0_param.color_key_enable = false; |
206 | pxp_conf->s0_param.width = cam->v2f.fmt.pix.width; | 314 | pxp_conf->s0_param.width = cam->v2f.fmt.pix.width; |
@@ -243,7 +351,8 @@ static int pxp_process_update(cam_data *cam) | |||
243 | proc_data->drect.left, proc_data->drect.top, | 351 | proc_data->drect.left, proc_data->drect.top, |
244 | proc_data->drect.width, proc_data->drect.height); | 352 | proc_data->drect.width, proc_data->drect.height); |
245 | 353 | ||
246 | pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565; | 354 | /* Out buffer */ |
355 | pxp_conf->out_param.pixel_fmt = v4l2_fmt_2_pxp_fmt(cam->v2f.fmt.pix.pixelformat); | ||
247 | pxp_conf->out_param.width = proc_data->drect.width; | 356 | pxp_conf->out_param.width = proc_data->drect.width; |
248 | pxp_conf->out_param.height = proc_data->drect.height; | 357 | pxp_conf->out_param.height = proc_data->drect.height; |
249 | 358 | ||
@@ -558,7 +667,9 @@ static inline int valid_mode(u32 palette) | |||
558 | { | 667 | { |
559 | return (palette == V4L2_PIX_FMT_RGB565) || | 668 | return (palette == V4L2_PIX_FMT_RGB565) || |
560 | (palette == V4L2_PIX_FMT_YUYV) || | 669 | (palette == V4L2_PIX_FMT_YUYV) || |
561 | (palette == V4L2_PIX_FMT_UYVY) || (palette == V4L2_PIX_FMT_YUV420); | 670 | (palette == V4L2_PIX_FMT_UYVY) || |
671 | (palette == V4L2_PIX_FMT_YUV444) || | ||
672 | (palette == V4L2_PIX_FMT_YUV420); | ||
562 | } | 673 | } |
563 | 674 | ||
564 | /*! | 675 | /*! |
@@ -631,6 +742,7 @@ static int csi_streamon(cam_data *cam) | |||
631 | if (__raw_readl(CSI_CSISR) & BIT_SOF_INT) { | 742 | if (__raw_readl(CSI_CSISR) & BIT_SOF_INT) { |
632 | val = __raw_readl(CSI_CSICR3); | 743 | val = __raw_readl(CSI_CSICR3); |
633 | __raw_writel(val | BIT_DMA_REFLASH_RFF, CSI_CSICR3); | 744 | __raw_writel(val | BIT_DMA_REFLASH_RFF, CSI_CSICR3); |
745 | /* Wait DMA reflash done */ | ||
634 | for (timeout2 = 1000000; timeout2 > 0; timeout2--) { | 746 | for (timeout2 = 1000000; timeout2 > 0; timeout2--) { |
635 | if (__raw_readl(CSI_CSICR3) & | 747 | if (__raw_readl(CSI_CSICR3) & |
636 | BIT_DMA_REFLASH_RFF) | 748 | BIT_DMA_REFLASH_RFF) |
@@ -682,6 +794,13 @@ static int csi_streamoff(cam_data *cam) | |||
682 | /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */ | 794 | /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */ |
683 | __raw_writel(0, CSI_CSIDMASA_FB1); | 795 | __raw_writel(0, CSI_CSIDMASA_FB1); |
684 | __raw_writel(0, CSI_CSIDMASA_FB2); | 796 | __raw_writel(0, CSI_CSIDMASA_FB2); |
797 | |||
798 | if (strcmp(csi_capture_inputs[cam->current_input].name, | ||
799 | "Vadc") == 0) { | ||
800 | csi_buf_stride_set(0); | ||
801 | csi_deinterlace_enable(false); | ||
802 | csi_tvdec_enable(false); | ||
803 | } | ||
685 | csi_enable(0); | 804 | csi_enable(0); |
686 | 805 | ||
687 | csi_free_frames(cam); | 806 | csi_free_frames(cam); |
@@ -792,7 +911,17 @@ static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f) | |||
792 | return -EINVAL; | 911 | return -EINVAL; |
793 | } | 912 | } |
794 | 913 | ||
795 | /* Handle case where size requested is larger than cuurent | 914 | /* |
915 | * Force the capture window resolution to be crop bounds | ||
916 | * for Vadc input mode. | ||
917 | */ | ||
918 | if (strcmp(csi_capture_inputs[cam->current_input].name, | ||
919 | "Vadc") == 0) { | ||
920 | f->fmt.pix.width = cam->crop_current.width; | ||
921 | f->fmt.pix.height = cam->crop_current.height; | ||
922 | } | ||
923 | |||
924 | /* Handle case where size requested is larger than current | ||
796 | * camera setting. */ | 925 | * camera setting. */ |
797 | if ((f->fmt.pix.width > cam->crop_bounds.width) | 926 | if ((f->fmt.pix.width > cam->crop_bounds.width) |
798 | || (f->fmt.pix.height > cam->crop_bounds.height)) { | 927 | || (f->fmt.pix.height > cam->crop_bounds.height)) { |
@@ -828,24 +957,24 @@ static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f) | |||
828 | "resize to %d.\n", *height); | 957 | "resize to %d.\n", *height); |
829 | } | 958 | } |
830 | 959 | ||
831 | switch (f->fmt.pix.pixelformat) { | 960 | cam_input_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
832 | case V4L2_PIX_FMT_RGB565: | 961 | vidioc_int_g_fmt_cap(cam->sensor, &cam_input_fmt); |
833 | size = f->fmt.pix.width * f->fmt.pix.height * 2; | 962 | |
834 | csi_init_format(V4L2_PIX_FMT_UYVY); | 963 | switch (cam_input_fmt.fmt.pix.pixelformat) { |
835 | csi_set_16bit_imagpara(f->fmt.pix.width, | 964 | case V4L2_PIX_FMT_YUV444: |
965 | size = f->fmt.pix.width * f->fmt.pix.height * 4; | ||
966 | csi_set_32bit_imagpara(f->fmt.pix.width, | ||
836 | f->fmt.pix.height); | 967 | f->fmt.pix.height); |
837 | bytesperline = f->fmt.pix.width * 2; | 968 | bytesperline = f->fmt.pix.width * 4; |
838 | break; | 969 | break; |
839 | case V4L2_PIX_FMT_UYVY: | 970 | case V4L2_PIX_FMT_UYVY: |
840 | size = f->fmt.pix.width * f->fmt.pix.height * 2; | 971 | size = f->fmt.pix.width * f->fmt.pix.height * 2; |
841 | csi_init_format(f->fmt.pix.pixelformat); | ||
842 | csi_set_16bit_imagpara(f->fmt.pix.width, | 972 | csi_set_16bit_imagpara(f->fmt.pix.width, |
843 | f->fmt.pix.height); | 973 | f->fmt.pix.height); |
844 | bytesperline = f->fmt.pix.width * 2; | 974 | bytesperline = f->fmt.pix.width * 2; |
845 | break; | 975 | break; |
846 | case V4L2_PIX_FMT_YUYV: | 976 | case V4L2_PIX_FMT_YUYV: |
847 | size = f->fmt.pix.width * f->fmt.pix.height * 2; | 977 | size = f->fmt.pix.width * f->fmt.pix.height * 2; |
848 | csi_init_format(f->fmt.pix.pixelformat); | ||
849 | csi_set_16bit_imagpara(f->fmt.pix.width, | 978 | csi_set_16bit_imagpara(f->fmt.pix.width, |
850 | f->fmt.pix.height); | 979 | f->fmt.pix.height); |
851 | bytesperline = f->fmt.pix.width * 2; | 980 | bytesperline = f->fmt.pix.width * 2; |
@@ -1008,6 +1137,104 @@ static int pxp_get_cstate(cam_data *cam, struct v4l2_control *vc) | |||
1008 | return 0; | 1137 | return 0; |
1009 | } | 1138 | } |
1010 | 1139 | ||
1140 | /*! | ||
1141 | * V4L2 - csi_v4l_s_std function | ||
1142 | * | ||
1143 | * Sets the TV standard to be used. | ||
1144 | * | ||
1145 | * @param cam structure cam_data * | ||
1146 | * @param parm structure v4l2_std_id * | ||
1147 | * | ||
1148 | * @return status 0 success, -EINVAL failed | ||
1149 | */ | ||
1150 | static int csi_v4l_s_std(cam_data *cam, v4l2_std_id e) | ||
1151 | { | ||
1152 | pr_debug("In csi_v4l2_s_std %Lx\n", e); | ||
1153 | |||
1154 | if (e == V4L2_STD_PAL) { | ||
1155 | pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL); | ||
1156 | cam->standard.id = V4L2_STD_PAL; | ||
1157 | video_index = TV_PAL; | ||
1158 | } else if (e == V4L2_STD_NTSC) { | ||
1159 | pr_debug(" Setting standard to NTSC %Lx\n", | ||
1160 | V4L2_STD_NTSC); | ||
1161 | /* Get rid of the white dot line in NTSC signal input */ | ||
1162 | cam->standard.id = V4L2_STD_NTSC; | ||
1163 | video_index = TV_NTSC; | ||
1164 | } else { | ||
1165 | cam->standard.id = V4L2_STD_ALL; | ||
1166 | video_index = TV_NOT_LOCKED; | ||
1167 | pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n", | ||
1168 | e, V4L2_STD_PAL, V4L2_STD_NTSC); | ||
1169 | } | ||
1170 | |||
1171 | cam->standard.index = video_index; | ||
1172 | strcpy(cam->standard.name, video_fmts[video_index].name); | ||
1173 | |||
1174 | /* Enable csi PAL/NTSC deinterlace mode */ | ||
1175 | csi_buf_stride_set(video_fmts[video_index].active_width); | ||
1176 | csi_deinterlace_mode(cam->standard.id); | ||
1177 | csi_deinterlace_enable(true); | ||
1178 | |||
1179 | /* crop will overwrite */ | ||
1180 | cam->crop_bounds.width = video_fmts[video_index].raw_width; | ||
1181 | cam->crop_bounds.height = video_fmts[video_index].raw_height; | ||
1182 | cam->crop_current.width = video_fmts[video_index].active_width; | ||
1183 | cam->crop_current.height = video_fmts[video_index].active_height; | ||
1184 | cam->crop_current.top = video_fmts[video_index].active_top; | ||
1185 | cam->crop_current.left = video_fmts[video_index].active_left; | ||
1186 | |||
1187 | return 0; | ||
1188 | } | ||
1189 | |||
1190 | /*! | ||
1191 | * V4L2 - csi_v4l_g_std function | ||
1192 | * | ||
1193 | * Gets the TV standard from the TV input device. | ||
1194 | * | ||
1195 | * @param cam structure cam_data * | ||
1196 | * | ||
1197 | * @param e structure v4l2_std_id * | ||
1198 | * | ||
1199 | * @return status 0 success, -EINVAL failed | ||
1200 | */ | ||
1201 | static int csi_v4l_g_std(cam_data *cam, v4l2_std_id *e) | ||
1202 | { | ||
1203 | struct v4l2_format tv_fmt; | ||
1204 | |||
1205 | pr_debug("In csi_v4l2_g_std\n"); | ||
1206 | |||
1207 | if (cam->device_type == 1) { | ||
1208 | /* Use this function to get what the TV-In device detects the | ||
1209 | * format to be. pixelformat is used to return the std value | ||
1210 | * since the interface has no vidioc_g_std.*/ | ||
1211 | tv_fmt.type = V4L2_BUF_TYPE_PRIVATE; | ||
1212 | vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt); | ||
1213 | |||
1214 | /* If the TV-in automatically detects the standard, then if it | ||
1215 | * changes, the settings need to change. */ | ||
1216 | if (cam->standard_autodetect) { | ||
1217 | if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) { | ||
1218 | pr_debug("csi_v4l2_g_std: " | ||
1219 | "Changing standard\n"); | ||
1220 | csi_v4l_s_std(cam, tv_fmt.fmt.pix.pixelformat); | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1224 | *e = tv_fmt.fmt.pix.pixelformat; | ||
1225 | } | ||
1226 | |||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | static void csi_input_select(int input_select) | ||
1231 | { | ||
1232 | if (strcmp(csi_capture_inputs[input_select].name, "Vadc") == 0) | ||
1233 | /* Enable csi tvdec */ | ||
1234 | csi_tvdec_enable(true); | ||
1235 | else | ||
1236 | csi_tvdec_enable(false); | ||
1237 | } | ||
1011 | 1238 | ||
1012 | /*! | 1239 | /*! |
1013 | * Dequeue one V4L capture buffer | 1240 | * Dequeue one V4L capture buffer |
@@ -1076,8 +1303,9 @@ static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf) | |||
1076 | * If want to do preview on LCD, use PxP CSC to convert from UYVY | 1303 | * If want to do preview on LCD, use PxP CSC to convert from UYVY |
1077 | * to RGB565; but for encoding, usually we don't use RGB format. | 1304 | * to RGB565; but for encoding, usually we don't use RGB format. |
1078 | */ | 1305 | */ |
1079 | if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { | 1306 | if (cam->v2f.fmt.pix.pixelformat != cam_input_fmt.fmt.pix.pixelformat) { |
1080 | sg_dma_address(&cam->sg[0]) = buf->m.offset; | 1307 | sg_dma_address(&cam->sg[0]) = buf->m.offset; |
1308 | /* last frame buffer as pxp output buffer */ | ||
1081 | sg_dma_address(&cam->sg[1]) = | 1309 | sg_dma_address(&cam->sg[1]) = |
1082 | cam->frame[req_buf_number].paddress; | 1310 | cam->frame[req_buf_number].paddress; |
1083 | retval = pxp_process_update(cam); | 1311 | retval = pxp_process_update(cam); |
@@ -1086,11 +1314,14 @@ static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf) | |||
1086 | return retval; | 1314 | return retval; |
1087 | } | 1315 | } |
1088 | pxp_complete_update(cam); | 1316 | pxp_complete_update(cam); |
1317 | /* Copy data from pxp output buffer to original buffer | ||
1318 | * Need optimization */ | ||
1089 | if (cam->frame[buf->index].vaddress) | 1319 | if (cam->frame[buf->index].vaddress) |
1090 | memcpy(cam->frame[buf->index].vaddress, | 1320 | memcpy(cam->frame[buf->index].vaddress, |
1091 | cam->frame[req_buf_number].vaddress, | 1321 | cam->frame[req_buf_number].vaddress, |
1092 | cam->v2f.fmt.pix.sizeimage); | 1322 | cam->v2f.fmt.pix.sizeimage); |
1093 | } | 1323 | } |
1324 | |||
1094 | up(&cam->busy_lock); | 1325 | up(&cam->busy_lock); |
1095 | 1326 | ||
1096 | return retval; | 1327 | return retval; |
@@ -1413,6 +1644,7 @@ static long csi_v4l_do_ioctl(struct file *file, | |||
1413 | struct v4l2_crop *crop = arg; | 1644 | struct v4l2_crop *crop = arg; |
1414 | struct v4l2_rect *b = &cam->crop_bounds; | 1645 | struct v4l2_rect *b = &cam->crop_bounds; |
1415 | 1646 | ||
1647 | pr_debug(" case VIDIOC_S_CROP\n"); | ||
1416 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1648 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1417 | retval = -EINVAL; | 1649 | retval = -EINVAL; |
1418 | break; | 1650 | break; |
@@ -1444,6 +1676,7 @@ static long csi_v4l_do_ioctl(struct file *file, | |||
1444 | case VIDIOC_G_CROP: | 1676 | case VIDIOC_G_CROP: |
1445 | { | 1677 | { |
1446 | struct v4l2_crop *crop = arg; | 1678 | struct v4l2_crop *crop = arg; |
1679 | pr_debug(" case VIDIOC_G_CROP\n"); | ||
1447 | 1680 | ||
1448 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1681 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1449 | retval = -EINVAL; | 1682 | retval = -EINVAL; |
@@ -1653,15 +1886,62 @@ static long csi_v4l_do_ioctl(struct file *file, | |||
1653 | retval = -EINVAL; | 1886 | retval = -EINVAL; |
1654 | break; | 1887 | break; |
1655 | } | 1888 | } |
1656 | case VIDIOC_G_STD: | 1889 | |
1890 | case VIDIOC_G_STD: { | ||
1891 | v4l2_std_id *e = arg; | ||
1892 | pr_debug(" case VIDIOC_G_STD\n"); | ||
1893 | if (cam->sensor) { | ||
1894 | retval = csi_v4l_g_std(cam, e); | ||
1895 | } else { | ||
1896 | pr_err("ERROR: v4l2 capture: slave not found!\n"); | ||
1897 | retval = -ENODEV; | ||
1898 | } | ||
1899 | break; | ||
1900 | } | ||
1901 | |||
1902 | case VIDIOC_S_STD: { | ||
1903 | v4l2_std_id *e = arg; | ||
1904 | pr_debug(" case VIDIOC_S_STD\n"); | ||
1905 | retval = csi_v4l_s_std(cam, *e); | ||
1906 | |||
1907 | break; | ||
1908 | } | ||
1909 | |||
1910 | case VIDIOC_ENUMINPUT: { | ||
1911 | struct v4l2_input *input = arg; | ||
1912 | pr_debug(" case VIDIOC_ENUMINPUT\n"); | ||
1913 | if (input->index >= CSI_V4L2_CAPTURE_NUM_INPUTS) { | ||
1914 | retval = -EINVAL; | ||
1915 | break; | ||
1916 | } | ||
1917 | *input = csi_capture_inputs[input->index]; | ||
1918 | break; | ||
1919 | } | ||
1920 | |||
1921 | case VIDIOC_G_INPUT: { | ||
1922 | int *index = arg; | ||
1923 | pr_debug(" case VIDIOC_G_INPUT\n"); | ||
1924 | *index = cam->current_input; | ||
1925 | break; | ||
1926 | } | ||
1927 | |||
1928 | case VIDIOC_S_INPUT: { | ||
1929 | int *index = arg; | ||
1930 | pr_debug(" case VIDIOC_S_INPUT\n"); | ||
1931 | if (*index >= CSI_V4L2_CAPTURE_NUM_INPUTS) { | ||
1932 | retval = -EINVAL; | ||
1933 | break; | ||
1934 | } | ||
1935 | |||
1936 | cam->current_input = *index; | ||
1937 | |||
1938 | csi_input_select(cam->current_input); | ||
1939 | break; | ||
1940 | } | ||
1657 | case VIDIOC_G_OUTPUT: | 1941 | case VIDIOC_G_OUTPUT: |
1658 | case VIDIOC_S_OUTPUT: | 1942 | case VIDIOC_S_OUTPUT: |
1659 | case VIDIOC_ENUMSTD: | 1943 | case VIDIOC_ENUMSTD: |
1660 | case VIDIOC_S_STD: | ||
1661 | case VIDIOC_TRY_FMT: | 1944 | case VIDIOC_TRY_FMT: |
1662 | case VIDIOC_ENUMINPUT: | ||
1663 | case VIDIOC_G_INPUT: | ||
1664 | case VIDIOC_S_INPUT: | ||
1665 | case VIDIOC_G_TUNER: | 1945 | case VIDIOC_G_TUNER: |
1666 | case VIDIOC_S_TUNER: | 1946 | case VIDIOC_S_TUNER: |
1667 | case VIDIOC_G_FREQUENCY: | 1947 | case VIDIOC_G_FREQUENCY: |