aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandor Yu <R01008@freescale.com>2014-04-11 01:37:54 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-17 22:19:11 -0400
commit1f991ca3123275a7e47bee3badc7ed991ead3cb2 (patch)
treee718412efd2c2fecd8a1921a9b3836a7c0c72517
parentf8fd69100cc9a83fc4bc4b9e4c7bc1d37cc5b61a (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.c316
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);
50static u8 camera_power(cam_data *cam, bool cameraOn); 50static u8 camera_power(cam_data *cam, bool cameraOn);
51struct v4l2_crop crop_current; 51struct v4l2_crop crop_current;
52struct v4l2_window win_current; 52struct v4l2_window win_current;
53static struct v4l2_format cam_input_fmt;
53 54
54/*! Information about this driver. */ 55/*! Information about this driver. */
55static struct v4l2_int_master csi_v4l2_master = { 56static 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 */
106typedef 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. */
116typedef 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 */
133static 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
167static 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. */
189static 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 */
101static void pxp_dma_done(void *arg) 192static 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
235static 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 */
1150static 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 */
1201static 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
1230static 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: