diff options
Diffstat (limited to 'drivers/media/usb/cx231xx/cx231xx-video.c')
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-video.c | 601 |
1 files changed, 163 insertions, 438 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 06376d904c9f..cd221474e1b9 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
38 | #include <media/v4l2-event.h> | ||
38 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
39 | #include <media/msp3400.h> | 40 | #include <media/msp3400.h> |
40 | #include <media/tuner.h> | 41 | #include <media/tuner.h> |
@@ -100,125 +101,6 @@ static struct cx231xx_fmt format[] = { | |||
100 | }, | 101 | }, |
101 | }; | 102 | }; |
102 | 103 | ||
103 | /* supported controls */ | ||
104 | /* Common to all boards */ | ||
105 | |||
106 | /* ------------------------------------------------------------------- */ | ||
107 | |||
108 | static const struct v4l2_queryctrl no_ctl = { | ||
109 | .name = "42", | ||
110 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
111 | }; | ||
112 | |||
113 | static struct cx231xx_ctrl cx231xx_ctls[] = { | ||
114 | /* --- video --- */ | ||
115 | { | ||
116 | .v = { | ||
117 | .id = V4L2_CID_BRIGHTNESS, | ||
118 | .name = "Brightness", | ||
119 | .minimum = 0x00, | ||
120 | .maximum = 0xff, | ||
121 | .step = 1, | ||
122 | .default_value = 0x7f, | ||
123 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
124 | }, | ||
125 | .off = 128, | ||
126 | .reg = LUMA_CTRL, | ||
127 | .mask = 0x00ff, | ||
128 | .shift = 0, | ||
129 | }, { | ||
130 | .v = { | ||
131 | .id = V4L2_CID_CONTRAST, | ||
132 | .name = "Contrast", | ||
133 | .minimum = 0, | ||
134 | .maximum = 0xff, | ||
135 | .step = 1, | ||
136 | .default_value = 0x3f, | ||
137 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
138 | }, | ||
139 | .off = 0, | ||
140 | .reg = LUMA_CTRL, | ||
141 | .mask = 0xff00, | ||
142 | .shift = 8, | ||
143 | }, { | ||
144 | .v = { | ||
145 | .id = V4L2_CID_HUE, | ||
146 | .name = "Hue", | ||
147 | .minimum = 0, | ||
148 | .maximum = 0xff, | ||
149 | .step = 1, | ||
150 | .default_value = 0x7f, | ||
151 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
152 | }, | ||
153 | .off = 128, | ||
154 | .reg = CHROMA_CTRL, | ||
155 | .mask = 0xff0000, | ||
156 | .shift = 16, | ||
157 | }, { | ||
158 | /* strictly, this only describes only U saturation. | ||
159 | * V saturation is handled specially through code. | ||
160 | */ | ||
161 | .v = { | ||
162 | .id = V4L2_CID_SATURATION, | ||
163 | .name = "Saturation", | ||
164 | .minimum = 0, | ||
165 | .maximum = 0xff, | ||
166 | .step = 1, | ||
167 | .default_value = 0x7f, | ||
168 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
169 | }, | ||
170 | .off = 0, | ||
171 | .reg = CHROMA_CTRL, | ||
172 | .mask = 0x00ff, | ||
173 | .shift = 0, | ||
174 | }, { | ||
175 | /* --- audio --- */ | ||
176 | .v = { | ||
177 | .id = V4L2_CID_AUDIO_MUTE, | ||
178 | .name = "Mute", | ||
179 | .minimum = 0, | ||
180 | .maximum = 1, | ||
181 | .default_value = 1, | ||
182 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
183 | }, | ||
184 | .reg = PATH1_CTL1, | ||
185 | .mask = (0x1f << 24), | ||
186 | .shift = 24, | ||
187 | }, { | ||
188 | .v = { | ||
189 | .id = V4L2_CID_AUDIO_VOLUME, | ||
190 | .name = "Volume", | ||
191 | .minimum = 0, | ||
192 | .maximum = 0x3f, | ||
193 | .step = 1, | ||
194 | .default_value = 0x3f, | ||
195 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
196 | }, | ||
197 | .reg = PATH1_VOL_CTL, | ||
198 | .mask = 0xff, | ||
199 | .shift = 0, | ||
200 | } | ||
201 | }; | ||
202 | static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls); | ||
203 | |||
204 | static const u32 cx231xx_user_ctrls[] = { | ||
205 | V4L2_CID_USER_CLASS, | ||
206 | V4L2_CID_BRIGHTNESS, | ||
207 | V4L2_CID_CONTRAST, | ||
208 | V4L2_CID_SATURATION, | ||
209 | V4L2_CID_HUE, | ||
210 | V4L2_CID_AUDIO_VOLUME, | ||
211 | #if 0 | ||
212 | V4L2_CID_AUDIO_BALANCE, | ||
213 | #endif | ||
214 | V4L2_CID_AUDIO_MUTE, | ||
215 | 0 | ||
216 | }; | ||
217 | |||
218 | static const u32 *ctrl_classes[] = { | ||
219 | cx231xx_user_ctrls, | ||
220 | NULL | ||
221 | }; | ||
222 | 104 | ||
223 | /* ------------------------------------------------------------------ | 105 | /* ------------------------------------------------------------------ |
224 | Video buffer and parser functions | 106 | Video buffer and parser functions |
@@ -1005,6 +887,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1005 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 887 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
1006 | 888 | ||
1007 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 889 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
890 | f->fmt.pix.priv = 0; | ||
1008 | 891 | ||
1009 | return 0; | 892 | return 0; |
1010 | } | 893 | } |
@@ -1045,10 +928,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
1045 | f->fmt.pix.width = width; | 928 | f->fmt.pix.width = width; |
1046 | f->fmt.pix.height = height; | 929 | f->fmt.pix.height = height; |
1047 | f->fmt.pix.pixelformat = fmt->fourcc; | 930 | f->fmt.pix.pixelformat = fmt->fourcc; |
1048 | f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; | 931 | f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3; |
1049 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; | 932 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; |
1050 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 933 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
1051 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 934 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
935 | f->fmt.pix.priv = 0; | ||
1052 | 936 | ||
1053 | return 0; | 937 | return 0; |
1054 | } | 938 | } |
@@ -1103,39 +987,39 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) | |||
1103 | return 0; | 987 | return 0; |
1104 | } | 988 | } |
1105 | 989 | ||
1106 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | 990 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) |
1107 | { | 991 | { |
1108 | struct cx231xx_fh *fh = priv; | 992 | struct cx231xx_fh *fh = priv; |
1109 | struct cx231xx *dev = fh->dev; | 993 | struct cx231xx *dev = fh->dev; |
1110 | struct v4l2_mbus_framefmt mbus_fmt; | 994 | struct v4l2_mbus_framefmt mbus_fmt; |
1111 | struct v4l2_format f; | ||
1112 | int rc; | 995 | int rc; |
1113 | 996 | ||
1114 | rc = check_dev(dev); | 997 | rc = check_dev(dev); |
1115 | if (rc < 0) | 998 | if (rc < 0) |
1116 | return rc; | 999 | return rc; |
1117 | 1000 | ||
1118 | cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm); | 1001 | if (dev->norm == norm) |
1002 | return 0; | ||
1119 | 1003 | ||
1120 | dev->norm = *norm; | 1004 | if (videobuf_queue_is_busy(&fh->vb_vidq)) |
1005 | return -EBUSY; | ||
1006 | |||
1007 | dev->norm = norm; | ||
1121 | 1008 | ||
1122 | /* Adjusts width/height, if needed */ | 1009 | /* Adjusts width/height, if needed */ |
1123 | f.fmt.pix.width = dev->width; | 1010 | dev->width = 720; |
1124 | f.fmt.pix.height = dev->height; | 1011 | dev->height = (dev->norm & V4L2_STD_625_50) ? 576 : 480; |
1125 | vidioc_try_fmt_vid_cap(file, priv, &f); | ||
1126 | 1012 | ||
1127 | call_all(dev, core, s_std, dev->norm); | 1013 | call_all(dev, core, s_std, dev->norm); |
1128 | 1014 | ||
1129 | /* We need to reset basic properties in the decoder related to | 1015 | /* We need to reset basic properties in the decoder related to |
1130 | resolution (since a standard change effects things like the number | 1016 | resolution (since a standard change effects things like the number |
1131 | of lines in VACT, etc) */ | 1017 | of lines in VACT, etc) */ |
1132 | v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED); | 1018 | memset(&mbus_fmt, 0, sizeof(mbus_fmt)); |
1019 | mbus_fmt.code = V4L2_MBUS_FMT_FIXED; | ||
1020 | mbus_fmt.width = dev->width; | ||
1021 | mbus_fmt.height = dev->height; | ||
1133 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); | 1022 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); |
1134 | v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt); | ||
1135 | |||
1136 | /* set new image size */ | ||
1137 | dev->width = f.fmt.pix.width; | ||
1138 | dev->height = f.fmt.pix.height; | ||
1139 | 1023 | ||
1140 | /* do mode control overrides */ | 1024 | /* do mode control overrides */ |
1141 | cx231xx_do_mode_ctrl_overrides(dev); | 1025 | cx231xx_do_mode_ctrl_overrides(dev); |
@@ -1152,7 +1036,7 @@ static const char *iname[] = { | |||
1152 | [CX231XX_VMUX_DEBUG] = "for debug only", | 1036 | [CX231XX_VMUX_DEBUG] = "for debug only", |
1153 | }; | 1037 | }; |
1154 | 1038 | ||
1155 | static int vidioc_enum_input(struct file *file, void *priv, | 1039 | int cx231xx_enum_input(struct file *file, void *priv, |
1156 | struct v4l2_input *i) | 1040 | struct v4l2_input *i) |
1157 | { | 1041 | { |
1158 | struct cx231xx_fh *fh = priv; | 1042 | struct cx231xx_fh *fh = priv; |
@@ -1192,7 +1076,7 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
1192 | return 0; | 1076 | return 0; |
1193 | } | 1077 | } |
1194 | 1078 | ||
1195 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | 1079 | int cx231xx_g_input(struct file *file, void *priv, unsigned int *i) |
1196 | { | 1080 | { |
1197 | struct cx231xx_fh *fh = priv; | 1081 | struct cx231xx_fh *fh = priv; |
1198 | struct cx231xx *dev = fh->dev; | 1082 | struct cx231xx *dev = fh->dev; |
@@ -1202,7 +1086,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | |||
1202 | return 0; | 1086 | return 0; |
1203 | } | 1087 | } |
1204 | 1088 | ||
1205 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | 1089 | int cx231xx_s_input(struct file *file, void *priv, unsigned int i) |
1206 | { | 1090 | { |
1207 | struct cx231xx_fh *fh = priv; | 1091 | struct cx231xx_fh *fh = priv; |
1208 | struct cx231xx *dev = fh->dev; | 1092 | struct cx231xx *dev = fh->dev; |
@@ -1231,117 +1115,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1231 | return 0; | 1115 | return 0; |
1232 | } | 1116 | } |
1233 | 1117 | ||
1234 | static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | 1118 | int cx231xx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) |
1235 | { | ||
1236 | struct cx231xx_fh *fh = priv; | ||
1237 | struct cx231xx *dev = fh->dev; | ||
1238 | |||
1239 | switch (a->index) { | ||
1240 | case CX231XX_AMUX_VIDEO: | ||
1241 | strcpy(a->name, "Television"); | ||
1242 | break; | ||
1243 | case CX231XX_AMUX_LINE_IN: | ||
1244 | strcpy(a->name, "Line In"); | ||
1245 | break; | ||
1246 | default: | ||
1247 | return -EINVAL; | ||
1248 | } | ||
1249 | |||
1250 | a->index = dev->ctl_ainput; | ||
1251 | a->capability = V4L2_AUDCAP_STEREO; | ||
1252 | |||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) | ||
1257 | { | ||
1258 | struct cx231xx_fh *fh = priv; | ||
1259 | struct cx231xx *dev = fh->dev; | ||
1260 | int status = 0; | ||
1261 | |||
1262 | /* Doesn't allow manual routing */ | ||
1263 | if (a->index != dev->ctl_ainput) | ||
1264 | return -EINVAL; | ||
1265 | |||
1266 | dev->ctl_ainput = INPUT(a->index)->amux; | ||
1267 | status = cx231xx_set_audio_input(dev, dev->ctl_ainput); | ||
1268 | |||
1269 | return status; | ||
1270 | } | ||
1271 | |||
1272 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
1273 | struct v4l2_queryctrl *qc) | ||
1274 | { | ||
1275 | struct cx231xx_fh *fh = priv; | ||
1276 | struct cx231xx *dev = fh->dev; | ||
1277 | int id = qc->id; | ||
1278 | int i; | ||
1279 | int rc; | ||
1280 | |||
1281 | rc = check_dev(dev); | ||
1282 | if (rc < 0) | ||
1283 | return rc; | ||
1284 | |||
1285 | qc->id = v4l2_ctrl_next(ctrl_classes, qc->id); | ||
1286 | if (unlikely(qc->id == 0)) | ||
1287 | return -EINVAL; | ||
1288 | |||
1289 | memset(qc, 0, sizeof(*qc)); | ||
1290 | |||
1291 | qc->id = id; | ||
1292 | |||
1293 | if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1) | ||
1294 | return -EINVAL; | ||
1295 | |||
1296 | for (i = 0; i < CX231XX_CTLS; i++) | ||
1297 | if (cx231xx_ctls[i].v.id == qc->id) | ||
1298 | break; | ||
1299 | |||
1300 | if (i == CX231XX_CTLS) { | ||
1301 | *qc = no_ctl; | ||
1302 | return 0; | ||
1303 | } | ||
1304 | *qc = cx231xx_ctls[i].v; | ||
1305 | |||
1306 | call_all(dev, core, queryctrl, qc); | ||
1307 | |||
1308 | if (qc->type) | ||
1309 | return 0; | ||
1310 | else | ||
1311 | return -EINVAL; | ||
1312 | } | ||
1313 | |||
1314 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
1315 | struct v4l2_control *ctrl) | ||
1316 | { | ||
1317 | struct cx231xx_fh *fh = priv; | ||
1318 | struct cx231xx *dev = fh->dev; | ||
1319 | int rc; | ||
1320 | |||
1321 | rc = check_dev(dev); | ||
1322 | if (rc < 0) | ||
1323 | return rc; | ||
1324 | |||
1325 | call_all(dev, core, g_ctrl, ctrl); | ||
1326 | return rc; | ||
1327 | } | ||
1328 | |||
1329 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1330 | struct v4l2_control *ctrl) | ||
1331 | { | ||
1332 | struct cx231xx_fh *fh = priv; | ||
1333 | struct cx231xx *dev = fh->dev; | ||
1334 | int rc; | ||
1335 | |||
1336 | rc = check_dev(dev); | ||
1337 | if (rc < 0) | ||
1338 | return rc; | ||
1339 | |||
1340 | call_all(dev, core, s_ctrl, ctrl); | ||
1341 | return rc; | ||
1342 | } | ||
1343 | |||
1344 | static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | ||
1345 | { | 1119 | { |
1346 | struct cx231xx_fh *fh = priv; | 1120 | struct cx231xx_fh *fh = priv; |
1347 | struct cx231xx *dev = fh->dev; | 1121 | struct cx231xx *dev = fh->dev; |
@@ -1360,11 +1134,12 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
1360 | t->capability = V4L2_TUNER_CAP_NORM; | 1134 | t->capability = V4L2_TUNER_CAP_NORM; |
1361 | t->rangehigh = 0xffffffffUL; | 1135 | t->rangehigh = 0xffffffffUL; |
1362 | t->signal = 0xffff; /* LOCKED */ | 1136 | t->signal = 0xffff; /* LOCKED */ |
1137 | call_all(dev, tuner, g_tuner, t); | ||
1363 | 1138 | ||
1364 | return 0; | 1139 | return 0; |
1365 | } | 1140 | } |
1366 | 1141 | ||
1367 | static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | 1142 | int cx231xx_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) |
1368 | { | 1143 | { |
1369 | struct cx231xx_fh *fh = priv; | 1144 | struct cx231xx_fh *fh = priv; |
1370 | struct cx231xx *dev = fh->dev; | 1145 | struct cx231xx *dev = fh->dev; |
@@ -1382,25 +1157,26 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
1382 | return 0; | 1157 | return 0; |
1383 | } | 1158 | } |
1384 | 1159 | ||
1385 | static int vidioc_g_frequency(struct file *file, void *priv, | 1160 | int cx231xx_g_frequency(struct file *file, void *priv, |
1386 | struct v4l2_frequency *f) | 1161 | struct v4l2_frequency *f) |
1387 | { | 1162 | { |
1388 | struct cx231xx_fh *fh = priv; | 1163 | struct cx231xx_fh *fh = priv; |
1389 | struct cx231xx *dev = fh->dev; | 1164 | struct cx231xx *dev = fh->dev; |
1390 | 1165 | ||
1391 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1166 | if (f->tuner) |
1392 | f->frequency = dev->ctl_freq; | 1167 | return -EINVAL; |
1393 | 1168 | ||
1394 | call_all(dev, tuner, g_frequency, f); | 1169 | f->frequency = dev->ctl_freq; |
1395 | 1170 | ||
1396 | return 0; | 1171 | return 0; |
1397 | } | 1172 | } |
1398 | 1173 | ||
1399 | static int vidioc_s_frequency(struct file *file, void *priv, | 1174 | int cx231xx_s_frequency(struct file *file, void *priv, |
1400 | struct v4l2_frequency *f) | 1175 | const struct v4l2_frequency *f) |
1401 | { | 1176 | { |
1402 | struct cx231xx_fh *fh = priv; | 1177 | struct cx231xx_fh *fh = priv; |
1403 | struct cx231xx *dev = fh->dev; | 1178 | struct cx231xx *dev = fh->dev; |
1179 | struct v4l2_frequency new_freq = *f; | ||
1404 | int rc; | 1180 | int rc; |
1405 | u32 if_frequency = 5400000; | 1181 | u32 if_frequency = 5400000; |
1406 | 1182 | ||
@@ -1415,16 +1191,12 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1415 | if (0 != f->tuner) | 1191 | if (0 != f->tuner) |
1416 | return -EINVAL; | 1192 | return -EINVAL; |
1417 | 1193 | ||
1418 | if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) | ||
1419 | return -EINVAL; | ||
1420 | if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) | ||
1421 | return -EINVAL; | ||
1422 | |||
1423 | /* set pre channel change settings in DIF first */ | 1194 | /* set pre channel change settings in DIF first */ |
1424 | rc = cx231xx_tuner_pre_channel_change(dev); | 1195 | rc = cx231xx_tuner_pre_channel_change(dev); |
1425 | 1196 | ||
1426 | dev->ctl_freq = f->frequency; | ||
1427 | call_all(dev, tuner, s_frequency, f); | 1197 | call_all(dev, tuner, s_frequency, f); |
1198 | call_all(dev, tuner, g_frequency, &new_freq); | ||
1199 | dev->ctl_freq = new_freq.frequency; | ||
1428 | 1200 | ||
1429 | /* set post channel change settings in DIF first */ | 1201 | /* set post channel change settings in DIF first */ |
1430 | rc = cx231xx_tuner_post_channel_change(dev); | 1202 | rc = cx231xx_tuner_post_channel_change(dev); |
@@ -1456,6 +1228,19 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1456 | return rc; | 1228 | return rc; |
1457 | } | 1229 | } |
1458 | 1230 | ||
1231 | int cx231xx_g_chip_ident(struct file *file, void *fh, | ||
1232 | struct v4l2_dbg_chip_ident *chip) | ||
1233 | { | ||
1234 | chip->ident = V4L2_IDENT_NONE; | ||
1235 | chip->revision = 0; | ||
1236 | if (chip->match.type == V4L2_CHIP_MATCH_HOST) { | ||
1237 | if (v4l2_chip_match_host(&chip->match)) | ||
1238 | chip->ident = V4L2_IDENT_CX23100; | ||
1239 | return 0; | ||
1240 | } | ||
1241 | return -EINVAL; | ||
1242 | } | ||
1243 | |||
1459 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1244 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1460 | 1245 | ||
1461 | /* | 1246 | /* |
@@ -1471,7 +1256,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1471 | if type == i2caddr, then <chip> is the 7-bit I2C address | 1256 | if type == i2caddr, then <chip> is the 7-bit I2C address |
1472 | */ | 1257 | */ |
1473 | 1258 | ||
1474 | static int vidioc_g_register(struct file *file, void *priv, | 1259 | int cx231xx_g_register(struct file *file, void *priv, |
1475 | struct v4l2_dbg_register *reg) | 1260 | struct v4l2_dbg_register *reg) |
1476 | { | 1261 | { |
1477 | struct cx231xx_fh *fh = priv; | 1262 | struct cx231xx_fh *fh = priv; |
@@ -1618,8 +1403,8 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1618 | return ret; | 1403 | return ret; |
1619 | } | 1404 | } |
1620 | 1405 | ||
1621 | static int vidioc_s_register(struct file *file, void *priv, | 1406 | int cx231xx_s_register(struct file *file, void *priv, |
1622 | struct v4l2_dbg_register *reg) | 1407 | const struct v4l2_dbg_register *reg) |
1623 | { | 1408 | { |
1624 | struct cx231xx_fh *fh = priv; | 1409 | struct cx231xx_fh *fh = priv; |
1625 | struct cx231xx *dev = fh->dev; | 1410 | struct cx231xx *dev = fh->dev; |
@@ -1837,9 +1622,6 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1837 | if (rc < 0) | 1622 | if (rc < 0) |
1838 | return rc; | 1623 | return rc; |
1839 | 1624 | ||
1840 | if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
1841 | (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) | ||
1842 | return -EINVAL; | ||
1843 | if (type != fh->type) | 1625 | if (type != fh->type) |
1844 | return -EINVAL; | 1626 | return -EINVAL; |
1845 | 1627 | ||
@@ -1851,9 +1633,10 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1851 | return 0; | 1633 | return 0; |
1852 | } | 1634 | } |
1853 | 1635 | ||
1854 | static int vidioc_querycap(struct file *file, void *priv, | 1636 | int cx231xx_querycap(struct file *file, void *priv, |
1855 | struct v4l2_capability *cap) | 1637 | struct v4l2_capability *cap) |
1856 | { | 1638 | { |
1639 | struct video_device *vdev = video_devdata(file); | ||
1857 | struct cx231xx_fh *fh = priv; | 1640 | struct cx231xx_fh *fh = priv; |
1858 | struct cx231xx *dev = fh->dev; | 1641 | struct cx231xx *dev = fh->dev; |
1859 | 1642 | ||
@@ -1861,17 +1644,22 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1861 | strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); | 1644 | strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); |
1862 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); | 1645 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); |
1863 | 1646 | ||
1864 | cap->capabilities = V4L2_CAP_VBI_CAPTURE | | 1647 | if (vdev->vfl_type == VFL_TYPE_RADIO) |
1865 | #if 0 | 1648 | cap->device_caps = V4L2_CAP_RADIO; |
1866 | V4L2_CAP_SLICED_VBI_CAPTURE | | 1649 | else { |
1867 | #endif | 1650 | cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; |
1868 | V4L2_CAP_VIDEO_CAPTURE | | 1651 | if (vdev->vfl_type == VFL_TYPE_VBI) |
1869 | V4L2_CAP_AUDIO | | 1652 | cap->device_caps |= V4L2_CAP_VBI_CAPTURE; |
1870 | V4L2_CAP_READWRITE | | 1653 | else |
1871 | V4L2_CAP_STREAMING; | 1654 | cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; |
1872 | 1655 | } | |
1873 | if (dev->tuner_type != TUNER_ABSENT) | 1656 | if (dev->tuner_type != TUNER_ABSENT) |
1874 | cap->capabilities |= V4L2_CAP_TUNER; | 1657 | cap->device_caps |= V4L2_CAP_TUNER; |
1658 | cap->capabilities = cap->device_caps | V4L2_CAP_READWRITE | | ||
1659 | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | | ||
1660 | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; | ||
1661 | if (dev->radio_dev) | ||
1662 | cap->capabilities |= V4L2_CAP_RADIO; | ||
1875 | 1663 | ||
1876 | return 0; | 1664 | return 0; |
1877 | } | 1665 | } |
@@ -1888,47 +1676,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
1888 | return 0; | 1676 | return 0; |
1889 | } | 1677 | } |
1890 | 1678 | ||
1891 | /* Sliced VBI ioctls */ | ||
1892 | static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, | ||
1893 | struct v4l2_format *f) | ||
1894 | { | ||
1895 | struct cx231xx_fh *fh = priv; | ||
1896 | struct cx231xx *dev = fh->dev; | ||
1897 | int rc; | ||
1898 | |||
1899 | rc = check_dev(dev); | ||
1900 | if (rc < 0) | ||
1901 | return rc; | ||
1902 | |||
1903 | f->fmt.sliced.service_set = 0; | ||
1904 | |||
1905 | call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); | ||
1906 | |||
1907 | if (f->fmt.sliced.service_set == 0) | ||
1908 | rc = -EINVAL; | ||
1909 | |||
1910 | return rc; | ||
1911 | } | ||
1912 | |||
1913 | static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, | ||
1914 | struct v4l2_format *f) | ||
1915 | { | ||
1916 | struct cx231xx_fh *fh = priv; | ||
1917 | struct cx231xx *dev = fh->dev; | ||
1918 | int rc; | ||
1919 | |||
1920 | rc = check_dev(dev); | ||
1921 | if (rc < 0) | ||
1922 | return rc; | ||
1923 | |||
1924 | call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); | ||
1925 | |||
1926 | if (f->fmt.sliced.service_set == 0) | ||
1927 | return -EINVAL; | ||
1928 | |||
1929 | return 0; | ||
1930 | } | ||
1931 | |||
1932 | /* RAW VBI ioctls */ | 1679 | /* RAW VBI ioctls */ |
1933 | 1680 | ||
1934 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | 1681 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, |
@@ -1936,6 +1683,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | |||
1936 | { | 1683 | { |
1937 | struct cx231xx_fh *fh = priv; | 1684 | struct cx231xx_fh *fh = priv; |
1938 | struct cx231xx *dev = fh->dev; | 1685 | struct cx231xx *dev = fh->dev; |
1686 | |||
1939 | f->fmt.vbi.sampling_rate = 6750000 * 4; | 1687 | f->fmt.vbi.sampling_rate = 6750000 * 4; |
1940 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; | 1688 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; |
1941 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1689 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
@@ -1947,6 +1695,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | |||
1947 | f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? | 1695 | f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? |
1948 | PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263; | 1696 | PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263; |
1949 | f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; | 1697 | f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; |
1698 | memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); | ||
1950 | 1699 | ||
1951 | return 0; | 1700 | return 0; |
1952 | 1701 | ||
@@ -1958,12 +1707,6 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, | |||
1958 | struct cx231xx_fh *fh = priv; | 1707 | struct cx231xx_fh *fh = priv; |
1959 | struct cx231xx *dev = fh->dev; | 1708 | struct cx231xx *dev = fh->dev; |
1960 | 1709 | ||
1961 | if (dev->vbi_stream_on && !fh->stream_on) { | ||
1962 | cx231xx_errdev("%s device in use by another fh\n", __func__); | ||
1963 | return -EBUSY; | ||
1964 | } | ||
1965 | |||
1966 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1967 | f->fmt.vbi.sampling_rate = 6750000 * 4; | 1710 | f->fmt.vbi.sampling_rate = 6750000 * 4; |
1968 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; | 1711 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; |
1969 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1712 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
@@ -1976,11 +1719,25 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, | |||
1976 | f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? | 1719 | f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? |
1977 | PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263; | 1720 | PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263; |
1978 | f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; | 1721 | f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; |
1722 | memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); | ||
1979 | 1723 | ||
1980 | return 0; | 1724 | return 0; |
1981 | 1725 | ||
1982 | } | 1726 | } |
1983 | 1727 | ||
1728 | static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, | ||
1729 | struct v4l2_format *f) | ||
1730 | { | ||
1731 | struct cx231xx_fh *fh = priv; | ||
1732 | struct cx231xx *dev = fh->dev; | ||
1733 | |||
1734 | if (dev->vbi_stream_on && !fh->stream_on) { | ||
1735 | cx231xx_errdev("%s device in use by another fh\n", __func__); | ||
1736 | return -EBUSY; | ||
1737 | } | ||
1738 | return vidioc_try_fmt_vbi_cap(file, priv, f); | ||
1739 | } | ||
1740 | |||
1984 | static int vidioc_reqbufs(struct file *file, void *priv, | 1741 | static int vidioc_reqbufs(struct file *file, void *priv, |
1985 | struct v4l2_requestbuffers *rb) | 1742 | struct v4l2_requestbuffers *rb) |
1986 | { | 1743 | { |
@@ -2038,58 +1795,24 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
2038 | /* RADIO ESPECIFIC IOCTLS */ | 1795 | /* RADIO ESPECIFIC IOCTLS */ |
2039 | /* ----------------------------------------------------------- */ | 1796 | /* ----------------------------------------------------------- */ |
2040 | 1797 | ||
2041 | static int radio_querycap(struct file *file, void *priv, | ||
2042 | struct v4l2_capability *cap) | ||
2043 | { | ||
2044 | struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; | ||
2045 | |||
2046 | strlcpy(cap->driver, "cx231xx", sizeof(cap->driver)); | ||
2047 | strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); | ||
2048 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); | ||
2049 | |||
2050 | cap->capabilities = V4L2_CAP_TUNER; | ||
2051 | return 0; | ||
2052 | } | ||
2053 | |||
2054 | static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | 1798 | static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) |
2055 | { | 1799 | { |
2056 | struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; | 1800 | struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; |
2057 | 1801 | ||
2058 | if (unlikely(t->index > 0)) | 1802 | if (t->index) |
2059 | return -EINVAL; | 1803 | return -EINVAL; |
2060 | 1804 | ||
2061 | strcpy(t->name, "Radio"); | 1805 | strcpy(t->name, "Radio"); |
2062 | t->type = V4L2_TUNER_RADIO; | ||
2063 | |||
2064 | call_all(dev, tuner, s_tuner, t); | ||
2065 | |||
2066 | return 0; | ||
2067 | } | ||
2068 | 1806 | ||
2069 | static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i) | 1807 | call_all(dev, tuner, g_tuner, t); |
2070 | { | ||
2071 | if (i->index != 0) | ||
2072 | return -EINVAL; | ||
2073 | strcpy(i->name, "Radio"); | ||
2074 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
2075 | 1808 | ||
2076 | return 0; | 1809 | return 0; |
2077 | } | 1810 | } |
2078 | 1811 | static int radio_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) | |
2079 | static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | ||
2080 | { | ||
2081 | if (unlikely(a->index)) | ||
2082 | return -EINVAL; | ||
2083 | |||
2084 | strcpy(a->name, "Radio"); | ||
2085 | return 0; | ||
2086 | } | ||
2087 | |||
2088 | static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | ||
2089 | { | 1812 | { |
2090 | struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; | 1813 | struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; |
2091 | 1814 | ||
2092 | if (0 != t->index) | 1815 | if (t->index) |
2093 | return -EINVAL; | 1816 | return -EINVAL; |
2094 | 1817 | ||
2095 | call_all(dev, tuner, s_tuner, t); | 1818 | call_all(dev, tuner, s_tuner, t); |
@@ -2097,36 +1820,6 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
2097 | return 0; | 1820 | return 0; |
2098 | } | 1821 | } |
2099 | 1822 | ||
2100 | static int radio_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) | ||
2101 | { | ||
2102 | return 0; | ||
2103 | } | ||
2104 | |||
2105 | static int radio_s_input(struct file *file, void *fh, unsigned int i) | ||
2106 | { | ||
2107 | return 0; | ||
2108 | } | ||
2109 | |||
2110 | static int radio_queryctrl(struct file *file, void *priv, | ||
2111 | struct v4l2_queryctrl *c) | ||
2112 | { | ||
2113 | int i; | ||
2114 | |||
2115 | if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1) | ||
2116 | return -EINVAL; | ||
2117 | if (c->id == V4L2_CID_AUDIO_MUTE) { | ||
2118 | for (i = 0; i < CX231XX_CTLS; i++) { | ||
2119 | if (cx231xx_ctls[i].v.id == c->id) | ||
2120 | break; | ||
2121 | } | ||
2122 | if (i == CX231XX_CTLS) | ||
2123 | return -EINVAL; | ||
2124 | *c = cx231xx_ctls[i].v; | ||
2125 | } else | ||
2126 | *c = no_ctl; | ||
2127 | return 0; | ||
2128 | } | ||
2129 | |||
2130 | /* | 1823 | /* |
2131 | * cx231xx_v4l2_open() | 1824 | * cx231xx_v4l2_open() |
2132 | * inits the device and starts isoc transfer | 1825 | * inits the device and starts isoc transfer |
@@ -2174,14 +1867,11 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
2174 | return -ERESTARTSYS; | 1867 | return -ERESTARTSYS; |
2175 | } | 1868 | } |
2176 | fh->dev = dev; | 1869 | fh->dev = dev; |
2177 | fh->radio = radio; | ||
2178 | fh->type = fh_type; | 1870 | fh->type = fh_type; |
2179 | filp->private_data = fh; | 1871 | filp->private_data = fh; |
1872 | v4l2_fh_init(&fh->fh, vdev); | ||
2180 | 1873 | ||
2181 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 1874 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
2182 | dev->width = norm_maxw(dev); | ||
2183 | dev->height = norm_maxh(dev); | ||
2184 | |||
2185 | /* Power up in Analog TV mode */ | 1875 | /* Power up in Analog TV mode */ |
2186 | if (dev->board.external_av) | 1876 | if (dev->board.external_av) |
2187 | cx231xx_set_power_mode(dev, | 1877 | cx231xx_set_power_mode(dev, |
@@ -2204,7 +1894,7 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
2204 | dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; | 1894 | dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; |
2205 | 1895 | ||
2206 | } | 1896 | } |
2207 | if (fh->radio) { | 1897 | if (radio) { |
2208 | cx231xx_videodbg("video_open: setting radio device\n"); | 1898 | cx231xx_videodbg("video_open: setting radio device\n"); |
2209 | 1899 | ||
2210 | /* cx231xx_start_radio(dev); */ | 1900 | /* cx231xx_start_radio(dev); */ |
@@ -2232,6 +1922,7 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
2232 | fh, &dev->lock); | 1922 | fh, &dev->lock); |
2233 | } | 1923 | } |
2234 | mutex_unlock(&dev->lock); | 1924 | mutex_unlock(&dev->lock); |
1925 | v4l2_fh_add(&fh->fh); | ||
2235 | 1926 | ||
2236 | return errCode; | 1927 | return errCode; |
2237 | } | 1928 | } |
@@ -2275,6 +1966,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) | |||
2275 | video_device_release(dev->vdev); | 1966 | video_device_release(dev->vdev); |
2276 | dev->vdev = NULL; | 1967 | dev->vdev = NULL; |
2277 | } | 1968 | } |
1969 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | ||
1970 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); | ||
2278 | } | 1971 | } |
2279 | 1972 | ||
2280 | /* | 1973 | /* |
@@ -2324,12 +2017,15 @@ static int cx231xx_close(struct file *filp) | |||
2324 | else | 2017 | else |
2325 | cx231xx_set_alt_setting(dev, INDEX_HANC, 0); | 2018 | cx231xx_set_alt_setting(dev, INDEX_HANC, 0); |
2326 | 2019 | ||
2020 | v4l2_fh_del(&fh->fh); | ||
2021 | v4l2_fh_exit(&fh->fh); | ||
2327 | kfree(fh); | 2022 | kfree(fh); |
2328 | dev->users--; | 2023 | dev->users--; |
2329 | wake_up_interruptible_nr(&dev->open, 1); | 2024 | wake_up_interruptible_nr(&dev->open, 1); |
2330 | return 0; | 2025 | return 0; |
2331 | } | 2026 | } |
2332 | 2027 | ||
2028 | v4l2_fh_del(&fh->fh); | ||
2333 | dev->users--; | 2029 | dev->users--; |
2334 | if (!dev->users) { | 2030 | if (!dev->users) { |
2335 | videobuf_stop(&fh->vb_vidq); | 2031 | videobuf_stop(&fh->vb_vidq); |
@@ -2356,6 +2052,7 @@ static int cx231xx_close(struct file *filp) | |||
2356 | /* set alternate 0 */ | 2052 | /* set alternate 0 */ |
2357 | cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); | 2053 | cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); |
2358 | } | 2054 | } |
2055 | v4l2_fh_exit(&fh->fh); | ||
2359 | kfree(fh); | 2056 | kfree(fh); |
2360 | wake_up_interruptible_nr(&dev->open, 1); | 2057 | wake_up_interruptible_nr(&dev->open, 1); |
2361 | return 0; | 2058 | return 0; |
@@ -2412,29 +2109,37 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
2412 | */ | 2109 | */ |
2413 | static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait) | 2110 | static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait) |
2414 | { | 2111 | { |
2112 | unsigned long req_events = poll_requested_events(wait); | ||
2415 | struct cx231xx_fh *fh = filp->private_data; | 2113 | struct cx231xx_fh *fh = filp->private_data; |
2416 | struct cx231xx *dev = fh->dev; | 2114 | struct cx231xx *dev = fh->dev; |
2115 | unsigned res = 0; | ||
2417 | int rc; | 2116 | int rc; |
2418 | 2117 | ||
2419 | rc = check_dev(dev); | 2118 | rc = check_dev(dev); |
2420 | if (rc < 0) | 2119 | if (rc < 0) |
2421 | return rc; | 2120 | return POLLERR; |
2422 | 2121 | ||
2423 | rc = res_get(fh); | 2122 | rc = res_get(fh); |
2424 | 2123 | ||
2425 | if (unlikely(rc < 0)) | 2124 | if (unlikely(rc < 0)) |
2426 | return POLLERR; | 2125 | return POLLERR; |
2427 | 2126 | ||
2127 | if (v4l2_event_pending(&fh->fh)) | ||
2128 | res |= POLLPRI; | ||
2129 | else | ||
2130 | poll_wait(filp, &fh->fh.wait, wait); | ||
2131 | |||
2132 | if (!(req_events & (POLLIN | POLLRDNORM))) | ||
2133 | return res; | ||
2134 | |||
2428 | if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || | 2135 | if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || |
2429 | (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) { | 2136 | (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) { |
2430 | unsigned int res; | ||
2431 | |||
2432 | mutex_lock(&dev->lock); | 2137 | mutex_lock(&dev->lock); |
2433 | res = videobuf_poll_stream(filp, &fh->vb_vidq, wait); | 2138 | res |= videobuf_poll_stream(filp, &fh->vb_vidq, wait); |
2434 | mutex_unlock(&dev->lock); | 2139 | mutex_unlock(&dev->lock); |
2435 | return res; | 2140 | return res; |
2436 | } | 2141 | } |
2437 | return POLLERR; | 2142 | return res | POLLERR; |
2438 | } | 2143 | } |
2439 | 2144 | ||
2440 | /* | 2145 | /* |
@@ -2479,41 +2184,37 @@ static const struct v4l2_file_operations cx231xx_v4l_fops = { | |||
2479 | }; | 2184 | }; |
2480 | 2185 | ||
2481 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 2186 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
2482 | .vidioc_querycap = vidioc_querycap, | 2187 | .vidioc_querycap = cx231xx_querycap, |
2483 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | 2188 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
2484 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | 2189 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
2485 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | 2190 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, |
2486 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | 2191 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, |
2487 | .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, | 2192 | .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, |
2488 | .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, | 2193 | .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, |
2489 | .vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, | 2194 | .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, |
2490 | .vidioc_g_audio = vidioc_g_audio, | ||
2491 | .vidioc_s_audio = vidioc_s_audio, | ||
2492 | .vidioc_cropcap = vidioc_cropcap, | 2195 | .vidioc_cropcap = vidioc_cropcap, |
2493 | .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, | ||
2494 | .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, | ||
2495 | .vidioc_reqbufs = vidioc_reqbufs, | 2196 | .vidioc_reqbufs = vidioc_reqbufs, |
2496 | .vidioc_querybuf = vidioc_querybuf, | 2197 | .vidioc_querybuf = vidioc_querybuf, |
2497 | .vidioc_qbuf = vidioc_qbuf, | 2198 | .vidioc_qbuf = vidioc_qbuf, |
2498 | .vidioc_dqbuf = vidioc_dqbuf, | 2199 | .vidioc_dqbuf = vidioc_dqbuf, |
2499 | .vidioc_s_std = vidioc_s_std, | 2200 | .vidioc_s_std = vidioc_s_std, |
2500 | .vidioc_g_std = vidioc_g_std, | 2201 | .vidioc_g_std = vidioc_g_std, |
2501 | .vidioc_enum_input = vidioc_enum_input, | 2202 | .vidioc_enum_input = cx231xx_enum_input, |
2502 | .vidioc_g_input = vidioc_g_input, | 2203 | .vidioc_g_input = cx231xx_g_input, |
2503 | .vidioc_s_input = vidioc_s_input, | 2204 | .vidioc_s_input = cx231xx_s_input, |
2504 | .vidioc_queryctrl = vidioc_queryctrl, | ||
2505 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
2506 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2507 | .vidioc_streamon = vidioc_streamon, | 2205 | .vidioc_streamon = vidioc_streamon, |
2508 | .vidioc_streamoff = vidioc_streamoff, | 2206 | .vidioc_streamoff = vidioc_streamoff, |
2509 | .vidioc_g_tuner = vidioc_g_tuner, | 2207 | .vidioc_g_tuner = cx231xx_g_tuner, |
2510 | .vidioc_s_tuner = vidioc_s_tuner, | 2208 | .vidioc_s_tuner = cx231xx_s_tuner, |
2511 | .vidioc_g_frequency = vidioc_g_frequency, | 2209 | .vidioc_g_frequency = cx231xx_g_frequency, |
2512 | .vidioc_s_frequency = vidioc_s_frequency, | 2210 | .vidioc_s_frequency = cx231xx_s_frequency, |
2211 | .vidioc_g_chip_ident = cx231xx_g_chip_ident, | ||
2513 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2212 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
2514 | .vidioc_g_register = vidioc_g_register, | 2213 | .vidioc_g_register = cx231xx_g_register, |
2515 | .vidioc_s_register = vidioc_s_register, | 2214 | .vidioc_s_register = cx231xx_s_register, |
2516 | #endif | 2215 | #endif |
2216 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
2217 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
2517 | }; | 2218 | }; |
2518 | 2219 | ||
2519 | static struct video_device cx231xx_vbi_template; | 2220 | static struct video_device cx231xx_vbi_template; |
@@ -2523,33 +2224,29 @@ static const struct video_device cx231xx_video_template = { | |||
2523 | .release = video_device_release, | 2224 | .release = video_device_release, |
2524 | .ioctl_ops = &video_ioctl_ops, | 2225 | .ioctl_ops = &video_ioctl_ops, |
2525 | .tvnorms = V4L2_STD_ALL, | 2226 | .tvnorms = V4L2_STD_ALL, |
2526 | .current_norm = V4L2_STD_PAL, | ||
2527 | }; | 2227 | }; |
2528 | 2228 | ||
2529 | static const struct v4l2_file_operations radio_fops = { | 2229 | static const struct v4l2_file_operations radio_fops = { |
2530 | .owner = THIS_MODULE, | 2230 | .owner = THIS_MODULE, |
2531 | .open = cx231xx_v4l2_open, | 2231 | .open = cx231xx_v4l2_open, |
2532 | .release = cx231xx_v4l2_close, | 2232 | .release = cx231xx_v4l2_close, |
2533 | .ioctl = video_ioctl2, | 2233 | .poll = v4l2_ctrl_poll, |
2234 | .unlocked_ioctl = video_ioctl2, | ||
2534 | }; | 2235 | }; |
2535 | 2236 | ||
2536 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { | 2237 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { |
2537 | .vidioc_querycap = radio_querycap, | 2238 | .vidioc_querycap = cx231xx_querycap, |
2538 | .vidioc_g_tuner = radio_g_tuner, | 2239 | .vidioc_g_tuner = radio_g_tuner, |
2539 | .vidioc_enum_input = radio_enum_input, | ||
2540 | .vidioc_g_audio = radio_g_audio, | ||
2541 | .vidioc_s_tuner = radio_s_tuner, | 2240 | .vidioc_s_tuner = radio_s_tuner, |
2542 | .vidioc_s_audio = radio_s_audio, | 2241 | .vidioc_g_frequency = cx231xx_g_frequency, |
2543 | .vidioc_s_input = radio_s_input, | 2242 | .vidioc_s_frequency = cx231xx_s_frequency, |
2544 | .vidioc_queryctrl = radio_queryctrl, | 2243 | .vidioc_g_chip_ident = cx231xx_g_chip_ident, |
2545 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
2546 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2547 | .vidioc_g_frequency = vidioc_g_frequency, | ||
2548 | .vidioc_s_frequency = vidioc_s_frequency, | ||
2549 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2244 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
2550 | .vidioc_g_register = vidioc_g_register, | 2245 | .vidioc_g_register = cx231xx_g_register, |
2551 | .vidioc_s_register = vidioc_s_register, | 2246 | .vidioc_s_register = cx231xx_s_register, |
2552 | #endif | 2247 | #endif |
2248 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
2249 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
2553 | }; | 2250 | }; |
2554 | 2251 | ||
2555 | static struct video_device cx231xx_radio_template = { | 2252 | static struct video_device cx231xx_radio_template = { |
@@ -2575,10 +2272,17 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, | |||
2575 | vfd->release = video_device_release; | 2272 | vfd->release = video_device_release; |
2576 | vfd->debug = video_debug; | 2273 | vfd->debug = video_debug; |
2577 | vfd->lock = &dev->lock; | 2274 | vfd->lock = &dev->lock; |
2275 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | ||
2578 | 2276 | ||
2579 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); | 2277 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); |
2580 | 2278 | ||
2581 | video_set_drvdata(vfd, dev); | 2279 | video_set_drvdata(vfd, dev); |
2280 | if (dev->tuner_type == TUNER_ABSENT) { | ||
2281 | v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); | ||
2282 | v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); | ||
2283 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); | ||
2284 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); | ||
2285 | } | ||
2582 | return vfd; | 2286 | return vfd; |
2583 | } | 2287 | } |
2584 | 2288 | ||
@@ -2590,7 +2294,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2590 | dev->name, CX231XX_VERSION); | 2294 | dev->name, CX231XX_VERSION); |
2591 | 2295 | ||
2592 | /* set default norm */ | 2296 | /* set default norm */ |
2593 | /*dev->norm = cx231xx_video_template.current_norm; */ | 2297 | dev->norm = V4L2_STD_PAL; |
2594 | dev->width = norm_maxw(dev); | 2298 | dev->width = norm_maxw(dev); |
2595 | dev->height = norm_maxh(dev); | 2299 | dev->height = norm_maxh(dev); |
2596 | dev->interlaced = 0; | 2300 | dev->interlaced = 0; |
@@ -2601,9 +2305,23 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2601 | /* Set the initial input */ | 2305 | /* Set the initial input */ |
2602 | video_mux(dev, dev->video_input); | 2306 | video_mux(dev, dev->video_input); |
2603 | 2307 | ||
2604 | /* Audio defaults */ | 2308 | call_all(dev, core, s_std, dev->norm); |
2605 | dev->mute = 1; | 2309 | |
2606 | dev->volume = 0x1f; | 2310 | v4l2_ctrl_handler_init(&dev->ctrl_handler, 10); |
2311 | v4l2_ctrl_handler_init(&dev->radio_ctrl_handler, 5); | ||
2312 | |||
2313 | if (dev->sd_cx25840) { | ||
2314 | v4l2_ctrl_add_handler(&dev->ctrl_handler, | ||
2315 | dev->sd_cx25840->ctrl_handler, NULL); | ||
2316 | v4l2_ctrl_add_handler(&dev->radio_ctrl_handler, | ||
2317 | dev->sd_cx25840->ctrl_handler, | ||
2318 | v4l2_ctrl_radio_filter); | ||
2319 | } | ||
2320 | |||
2321 | if (dev->ctrl_handler.error) | ||
2322 | return dev->ctrl_handler.error; | ||
2323 | if (dev->radio_ctrl_handler.error) | ||
2324 | return dev->radio_ctrl_handler.error; | ||
2607 | 2325 | ||
2608 | /* enable vbi capturing */ | 2326 | /* enable vbi capturing */ |
2609 | /* write code here... */ | 2327 | /* write code here... */ |
@@ -2615,6 +2333,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2615 | return -ENODEV; | 2333 | return -ENODEV; |
2616 | } | 2334 | } |
2617 | 2335 | ||
2336 | dev->vdev->ctrl_handler = &dev->ctrl_handler; | ||
2618 | /* register v4l2 video video_device */ | 2337 | /* register v4l2 video video_device */ |
2619 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | 2338 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, |
2620 | video_nr[dev->devno]); | 2339 | video_nr[dev->devno]); |
@@ -2634,6 +2353,11 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2634 | /* Allocate and fill vbi video_device struct */ | 2353 | /* Allocate and fill vbi video_device struct */ |
2635 | dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); | 2354 | dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); |
2636 | 2355 | ||
2356 | if (!dev->vbi_dev) { | ||
2357 | cx231xx_errdev("cannot allocate video_device.\n"); | ||
2358 | return -ENODEV; | ||
2359 | } | ||
2360 | dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; | ||
2637 | /* register v4l2 vbi video_device */ | 2361 | /* register v4l2 vbi video_device */ |
2638 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | 2362 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, |
2639 | vbi_nr[dev->devno]); | 2363 | vbi_nr[dev->devno]); |
@@ -2652,6 +2376,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2652 | cx231xx_errdev("cannot allocate video_device.\n"); | 2376 | cx231xx_errdev("cannot allocate video_device.\n"); |
2653 | return -ENODEV; | 2377 | return -ENODEV; |
2654 | } | 2378 | } |
2379 | dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; | ||
2655 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | 2380 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, |
2656 | radio_nr[dev->devno]); | 2381 | radio_nr[dev->devno]); |
2657 | if (ret < 0) { | 2382 | if (ret < 0) { |