]> Git Repo - linux.git/blob - drivers/media/usb/go7007/go7007-v4l2.c
Linux 6.14-rc3
[linux.git] / drivers / media / usb / go7007 / go7007-v4l2.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2005-2006 Micronas USA Inc.
4  */
5
6 #include <linux/module.h>
7 #include <linux/delay.h>
8 #include <linux/sched.h>
9 #include <linux/spinlock.h>
10 #include <linux/slab.h>
11 #include <linux/fs.h>
12 #include <linux/unistd.h>
13 #include <linux/time.h>
14 #include <linux/vmalloc.h>
15 #include <linux/pagemap.h>
16 #include <linux/i2c.h>
17 #include <linux/mutex.h>
18 #include <linux/uaccess.h>
19 #include <linux/videodev2.h>
20 #include <media/v4l2-common.h>
21 #include <media/v4l2-ioctl.h>
22 #include <media/v4l2-subdev.h>
23 #include <media/v4l2-event.h>
24 #include <media/videobuf2-vmalloc.h>
25 #include <media/i2c/saa7115.h>
26
27 #include "go7007-priv.h"
28
29 #define call_all(dev, o, f, args...) \
30         v4l2_device_call_until_err(dev, 0, o, f, ##args)
31
32 static bool valid_pixelformat(u32 pixelformat)
33 {
34         switch (pixelformat) {
35         case V4L2_PIX_FMT_MJPEG:
36         case V4L2_PIX_FMT_MPEG1:
37         case V4L2_PIX_FMT_MPEG2:
38         case V4L2_PIX_FMT_MPEG4:
39                 return true;
40         default:
41                 return false;
42         }
43 }
44
45 static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
46 {
47         u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
48
49         switch (format) {
50         case V4L2_PIX_FMT_MJPEG:
51                 return V4L2_BUF_FLAG_KEYFRAME;
52         case V4L2_PIX_FMT_MPEG4:
53                 switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
54                 case 0:
55                         return V4L2_BUF_FLAG_KEYFRAME;
56                 case 1:
57                         return V4L2_BUF_FLAG_PFRAME;
58                 case 2:
59                         return V4L2_BUF_FLAG_BFRAME;
60                 default:
61                         return 0;
62                 }
63         case V4L2_PIX_FMT_MPEG1:
64         case V4L2_PIX_FMT_MPEG2:
65                 switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
66                 case 1:
67                         return V4L2_BUF_FLAG_KEYFRAME;
68                 case 2:
69                         return V4L2_BUF_FLAG_PFRAME;
70                 case 3:
71                         return V4L2_BUF_FLAG_BFRAME;
72                 default:
73                         return 0;
74                 }
75         }
76
77         return 0;
78 }
79
80 static void get_resolution(struct go7007 *go, int *width, int *height)
81 {
82         switch (go->standard) {
83         case GO7007_STD_NTSC:
84                 *width = 720;
85                 *height = 480;
86                 break;
87         case GO7007_STD_PAL:
88                 *width = 720;
89                 *height = 576;
90                 break;
91         case GO7007_STD_OTHER:
92         default:
93                 *width = go->board_info->sensor_width;
94                 *height = go->board_info->sensor_height;
95                 break;
96         }
97 }
98
99 static void set_formatting(struct go7007 *go)
100 {
101         if (go->format == V4L2_PIX_FMT_MJPEG) {
102                 go->pali = 0;
103                 go->aspect_ratio = GO7007_RATIO_1_1;
104                 go->gop_size = 0;
105                 go->ipb = 0;
106                 go->closed_gop = 0;
107                 go->repeat_seqhead = 0;
108                 go->seq_header_enable = 0;
109                 go->gop_header_enable = 0;
110                 go->dvd_mode = 0;
111                 return;
112         }
113
114         switch (go->format) {
115         case V4L2_PIX_FMT_MPEG1:
116                 go->pali = 0;
117                 break;
118         default:
119         case V4L2_PIX_FMT_MPEG2:
120                 go->pali = 0x48;
121                 break;
122         case V4L2_PIX_FMT_MPEG4:
123                 /* For future reference: this is the list of MPEG4
124                  * profiles that are available, although they are
125                  * untested:
126                  *
127                  * Profile              pali
128                  * --------------       ----
129                  * PROFILE_S_L0         0x08
130                  * PROFILE_S_L1         0x01
131                  * PROFILE_S_L2         0x02
132                  * PROFILE_S_L3         0x03
133                  * PROFILE_ARTS_L1      0x91
134                  * PROFILE_ARTS_L2      0x92
135                  * PROFILE_ARTS_L3      0x93
136                  * PROFILE_ARTS_L4      0x94
137                  * PROFILE_AS_L0        0xf0
138                  * PROFILE_AS_L1        0xf1
139                  * PROFILE_AS_L2        0xf2
140                  * PROFILE_AS_L3        0xf3
141                  * PROFILE_AS_L4        0xf4
142                  * PROFILE_AS_L5        0xf5
143                  */
144                 go->pali = 0xf5;
145                 break;
146         }
147         go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
148         go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
149         go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
150         go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
151         go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
152         go->gop_header_enable = 1;
153         go->dvd_mode = 0;
154         if (go->format == V4L2_PIX_FMT_MPEG2)
155                 go->dvd_mode =
156                         go->bitrate == 9800000 &&
157                         go->gop_size == 15 &&
158                         go->ipb == 0 &&
159                         go->repeat_seqhead == 1 &&
160                         go->closed_gop;
161
162         switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
163         default:
164         case V4L2_MPEG_VIDEO_ASPECT_1x1:
165                 go->aspect_ratio = GO7007_RATIO_1_1;
166                 break;
167         case V4L2_MPEG_VIDEO_ASPECT_4x3:
168                 go->aspect_ratio = GO7007_RATIO_4_3;
169                 break;
170         case V4L2_MPEG_VIDEO_ASPECT_16x9:
171                 go->aspect_ratio = GO7007_RATIO_16_9;
172                 break;
173         }
174 }
175
176 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
177 {
178         int sensor_height = 0, sensor_width = 0;
179         int width, height;
180
181         if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
182                 return -EINVAL;
183
184         get_resolution(go, &sensor_width, &sensor_height);
185
186         if (fmt == NULL) {
187                 width = sensor_width;
188                 height = sensor_height;
189         } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
190                 if (fmt->fmt.pix.width > sensor_width)
191                         width = sensor_width;
192                 else if (fmt->fmt.pix.width < 144)
193                         width = 144;
194                 else
195                         width = fmt->fmt.pix.width & ~0x0f;
196
197                 if (fmt->fmt.pix.height > sensor_height)
198                         height = sensor_height;
199                 else if (fmt->fmt.pix.height < 96)
200                         height = 96;
201                 else
202                         height = fmt->fmt.pix.height & ~0x0f;
203         } else {
204                 width = fmt->fmt.pix.width;
205
206                 if (width <= sensor_width / 4) {
207                         width = sensor_width / 4;
208                         height = sensor_height / 4;
209                 } else if (width <= sensor_width / 2) {
210                         width = sensor_width / 2;
211                         height = sensor_height / 2;
212                 } else {
213                         width = sensor_width;
214                         height = sensor_height;
215                 }
216                 width &= ~0xf;
217                 height &= ~0xf;
218         }
219
220         if (fmt != NULL) {
221                 u32 pixelformat = fmt->fmt.pix.pixelformat;
222
223                 memset(fmt, 0, sizeof(*fmt));
224                 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
225                 fmt->fmt.pix.width = width;
226                 fmt->fmt.pix.height = height;
227                 fmt->fmt.pix.pixelformat = pixelformat;
228                 fmt->fmt.pix.field = V4L2_FIELD_NONE;
229                 fmt->fmt.pix.bytesperline = 0;
230                 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
231                 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
232         }
233
234         if (try)
235                 return 0;
236
237         if (fmt)
238                 go->format = fmt->fmt.pix.pixelformat;
239         go->width = width;
240         go->height = height;
241         go->encoder_h_offset = go->board_info->sensor_h_offset;
242         go->encoder_v_offset = go->board_info->sensor_v_offset;
243
244         if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
245                 struct v4l2_subdev_format format = {
246                         .which = V4L2_SUBDEV_FORMAT_ACTIVE,
247                 };
248
249                 format.format.code = MEDIA_BUS_FMT_FIXED;
250                 format.format.width = fmt ? fmt->fmt.pix.width : width;
251                 format.format.height = height;
252                 go->encoder_h_halve = 0;
253                 go->encoder_v_halve = 0;
254                 go->encoder_subsample = 0;
255                 call_all(&go->v4l2_dev, pad, set_fmt, NULL, &format);
256         } else {
257                 if (width <= sensor_width / 4) {
258                         go->encoder_h_halve = 1;
259                         go->encoder_v_halve = 1;
260                         go->encoder_subsample = 1;
261                 } else if (width <= sensor_width / 2) {
262                         go->encoder_h_halve = 1;
263                         go->encoder_v_halve = 1;
264                         go->encoder_subsample = 0;
265                 } else {
266                         go->encoder_h_halve = 0;
267                         go->encoder_v_halve = 0;
268                         go->encoder_subsample = 0;
269                 }
270         }
271         return 0;
272 }
273
274 static int vidioc_querycap(struct file *file, void  *priv,
275                                         struct v4l2_capability *cap)
276 {
277         struct go7007 *go = video_drvdata(file);
278
279         strscpy(cap->driver, "go7007", sizeof(cap->driver));
280         strscpy(cap->card, go->name, sizeof(cap->card));
281         strscpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
282         return 0;
283 }
284
285 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
286                                         struct v4l2_fmtdesc *fmt)
287 {
288         switch (fmt->index) {
289         case 0:
290                 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
291                 break;
292         case 1:
293                 fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
294                 break;
295         case 2:
296                 fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
297                 break;
298         case 3:
299                 fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
300                 break;
301         default:
302                 return -EINVAL;
303         }
304         return 0;
305 }
306
307 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
308                                         struct v4l2_format *fmt)
309 {
310         struct go7007 *go = video_drvdata(file);
311
312         fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
313         fmt->fmt.pix.width = go->width;
314         fmt->fmt.pix.height = go->height;
315         fmt->fmt.pix.pixelformat = go->format;
316         fmt->fmt.pix.field = V4L2_FIELD_NONE;
317         fmt->fmt.pix.bytesperline = 0;
318         fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
319         fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
320
321         return 0;
322 }
323
324 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
325                         struct v4l2_format *fmt)
326 {
327         struct go7007 *go = video_drvdata(file);
328
329         return set_capture_size(go, fmt, 1);
330 }
331
332 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
333                         struct v4l2_format *fmt)
334 {
335         struct go7007 *go = video_drvdata(file);
336
337         if (vb2_is_busy(&go->vidq))
338                 return -EBUSY;
339
340         return set_capture_size(go, fmt, 0);
341 }
342
343 static int go7007_queue_setup(struct vb2_queue *q,
344                 unsigned int *num_buffers, unsigned int *num_planes,
345                 unsigned int sizes[], struct device *alloc_devs[])
346 {
347         sizes[0] = GO7007_BUF_SIZE;
348         *num_planes = 1;
349
350         if (*num_buffers < 2)
351                 *num_buffers = 2;
352
353         return 0;
354 }
355
356 static void go7007_buf_queue(struct vb2_buffer *vb)
357 {
358         struct vb2_queue *vq = vb->vb2_queue;
359         struct go7007 *go = vb2_get_drv_priv(vq);
360         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
361         struct go7007_buffer *go7007_vb =
362                 container_of(vbuf, struct go7007_buffer, vb);
363         unsigned long flags;
364
365         spin_lock_irqsave(&go->spinlock, flags);
366         list_add_tail(&go7007_vb->list, &go->vidq_active);
367         spin_unlock_irqrestore(&go->spinlock, flags);
368 }
369
370 static int go7007_buf_prepare(struct vb2_buffer *vb)
371 {
372         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
373         struct go7007_buffer *go7007_vb =
374                 container_of(vbuf, struct go7007_buffer, vb);
375
376         go7007_vb->modet_active = 0;
377         go7007_vb->frame_offset = 0;
378         vb->planes[0].bytesused = 0;
379         return 0;
380 }
381
382 static void go7007_buf_finish(struct vb2_buffer *vb)
383 {
384         struct vb2_queue *vq = vb->vb2_queue;
385         struct go7007 *go = vb2_get_drv_priv(vq);
386         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
387         struct go7007_buffer *go7007_vb =
388                 container_of(vbuf, struct go7007_buffer, vb);
389         u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
390
391         vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
392                         V4L2_BUF_FLAG_PFRAME);
393         vbuf->flags |= frame_type_flag;
394         vbuf->field = V4L2_FIELD_NONE;
395 }
396
397 static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
398 {
399         struct go7007 *go = vb2_get_drv_priv(q);
400         int ret;
401
402         set_formatting(go);
403         mutex_lock(&go->hw_lock);
404         go->next_seq = 0;
405         go->active_buf = NULL;
406         go->modet_event_status = 0;
407         if (go7007_start_encoder(go) < 0)
408                 ret = -EIO;
409         else
410                 ret = 0;
411         mutex_unlock(&go->hw_lock);
412         if (ret)
413                 return ret;
414         call_all(&go->v4l2_dev, video, s_stream, 1);
415         v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
416         v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
417         v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
418         v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
419         /* Turn on Capture LED */
420         if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
421                 go7007_write_addr(go, 0x3c82, 0x0005);
422         return ret;
423 }
424
425 static void go7007_stop_streaming(struct vb2_queue *q)
426 {
427         struct go7007 *go = vb2_get_drv_priv(q);
428         unsigned long flags;
429
430         go7007_stream_stop(go);
431         mutex_lock(&go->hw_lock);
432         go7007_reset_encoder(go);
433         mutex_unlock(&go->hw_lock);
434         call_all(&go->v4l2_dev, video, s_stream, 0);
435
436         spin_lock_irqsave(&go->spinlock, flags);
437         INIT_LIST_HEAD(&go->vidq_active);
438         spin_unlock_irqrestore(&go->spinlock, flags);
439         v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
440         v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
441         v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
442         v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
443         /* Turn on Capture LED */
444         if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
445                 go7007_write_addr(go, 0x3c82, 0x000d);
446 }
447
448 static const struct vb2_ops go7007_video_qops = {
449         .queue_setup    = go7007_queue_setup,
450         .buf_queue      = go7007_buf_queue,
451         .buf_prepare    = go7007_buf_prepare,
452         .buf_finish     = go7007_buf_finish,
453         .start_streaming = go7007_start_streaming,
454         .stop_streaming = go7007_stop_streaming,
455 };
456
457 static int vidioc_g_parm(struct file *filp, void *priv,
458                 struct v4l2_streamparm *parm)
459 {
460         struct go7007 *go = video_drvdata(filp);
461         struct v4l2_fract timeperframe = {
462                 .numerator = 1001 *  go->fps_scale,
463                 .denominator = go->sensor_framerate,
464         };
465
466         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
467                 return -EINVAL;
468
469         parm->parm.capture.readbuffers = 2;
470         parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
471         parm->parm.capture.timeperframe = timeperframe;
472
473         return 0;
474 }
475
476 static int vidioc_s_parm(struct file *filp, void *priv,
477                 struct v4l2_streamparm *parm)
478 {
479         struct go7007 *go = video_drvdata(filp);
480         unsigned int n, d;
481
482         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
483                 return -EINVAL;
484
485         n = go->sensor_framerate *
486                 parm->parm.capture.timeperframe.numerator;
487         d = 1001 * parm->parm.capture.timeperframe.denominator;
488         if (n != 0 && d != 0 && n > d)
489                 go->fps_scale = (n + d/2) / d;
490         else
491                 go->fps_scale = 1;
492
493         return vidioc_g_parm(filp, priv, parm);
494 }
495
496 /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
497    its resolution, when the device is not connected to TV.
498    This is were an API abuse, probably used by the lack of specific IOCTL's to
499    enumerate it, by the time the driver was written.
500
501    However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
502    and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
503
504    The two functions below implement the newer ioctls
505 */
506 static int vidioc_enum_framesizes(struct file *filp, void *priv,
507                                   struct v4l2_frmsizeenum *fsize)
508 {
509         struct go7007 *go = video_drvdata(filp);
510         int width, height;
511
512         if (fsize->index > 2)
513                 return -EINVAL;
514
515         if (!valid_pixelformat(fsize->pixel_format))
516                 return -EINVAL;
517
518         get_resolution(go, &width, &height);
519         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
520         fsize->discrete.width = (width >> fsize->index) & ~0xf;
521         fsize->discrete.height = (height >> fsize->index) & ~0xf;
522         return 0;
523 }
524
525 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
526                                       struct v4l2_frmivalenum *fival)
527 {
528         struct go7007 *go = video_drvdata(filp);
529         int width, height;
530         int i;
531
532         if (fival->index > 4)
533                 return -EINVAL;
534
535         if (!valid_pixelformat(fival->pixel_format))
536                 return -EINVAL;
537
538         if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
539                 get_resolution(go, &width, &height);
540                 for (i = 0; i <= 2; i++)
541                         if (fival->width == ((width >> i) & ~0xf) &&
542                             fival->height == ((height >> i) & ~0xf))
543                                 break;
544                 if (i > 2)
545                         return -EINVAL;
546         }
547         fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
548         fival->discrete.numerator = 1001 * (fival->index + 1);
549         fival->discrete.denominator = go->sensor_framerate;
550         return 0;
551 }
552
553 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
554 {
555         struct go7007 *go = video_drvdata(file);
556
557         *std = go->std;
558         return 0;
559 }
560
561 static int go7007_s_std(struct go7007 *go)
562 {
563         if (go->std & V4L2_STD_625_50) {
564                 go->standard = GO7007_STD_PAL;
565                 go->sensor_framerate = 25025;
566         } else {
567                 go->standard = GO7007_STD_NTSC;
568                 go->sensor_framerate = 30000;
569         }
570
571         call_all(&go->v4l2_dev, video, s_std, go->std);
572         set_capture_size(go, NULL, 0);
573         return 0;
574 }
575
576 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
577 {
578         struct go7007 *go = video_drvdata(file);
579
580         if (vb2_is_busy(&go->vidq))
581                 return -EBUSY;
582
583         go->std = std;
584
585         return go7007_s_std(go);
586 }
587
588 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
589 {
590         struct go7007 *go = video_drvdata(file);
591
592         return call_all(&go->v4l2_dev, video, querystd, std);
593 }
594
595 static int vidioc_enum_input(struct file *file, void *priv,
596                                 struct v4l2_input *inp)
597 {
598         struct go7007 *go = video_drvdata(file);
599
600         if (inp->index >= go->board_info->num_inputs)
601                 return -EINVAL;
602
603         strscpy(inp->name, go->board_info->inputs[inp->index].name,
604                 sizeof(inp->name));
605
606         /* If this board has a tuner, it will be the first input */
607         if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
608                         inp->index == 0)
609                 inp->type = V4L2_INPUT_TYPE_TUNER;
610         else
611                 inp->type = V4L2_INPUT_TYPE_CAMERA;
612
613         if (go->board_info->num_aud_inputs)
614                 inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
615         else
616                 inp->audioset = 0;
617         inp->tuner = 0;
618         if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
619                 inp->std = video_devdata(file)->tvnorms;
620         else
621                 inp->std = 0;
622
623         return 0;
624 }
625
626
627 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
628 {
629         struct go7007 *go = video_drvdata(file);
630
631         *input = go->input;
632
633         return 0;
634 }
635
636 static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
637 {
638         struct go7007 *go = video_drvdata(file);
639
640         if (a->index >= go->board_info->num_aud_inputs)
641                 return -EINVAL;
642         strscpy(a->name, go->board_info->aud_inputs[a->index].name,
643                 sizeof(a->name));
644         a->capability = V4L2_AUDCAP_STEREO;
645         return 0;
646 }
647
648 static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
649 {
650         struct go7007 *go = video_drvdata(file);
651
652         a->index = go->aud_input;
653         strscpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
654                 sizeof(a->name));
655         a->capability = V4L2_AUDCAP_STEREO;
656         return 0;
657 }
658
659 static int vidioc_s_audio(struct file *file, void *fh,
660         const struct v4l2_audio *a)
661 {
662         struct go7007 *go = video_drvdata(file);
663
664         if (a->index >= go->board_info->num_aud_inputs)
665                 return -EINVAL;
666         go->aud_input = a->index;
667         v4l2_subdev_call(go->sd_audio, audio, s_routing,
668                 go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
669         return 0;
670 }
671
672 static void go7007_s_input(struct go7007 *go)
673 {
674         unsigned int input = go->input;
675
676         v4l2_subdev_call(go->sd_video, video, s_routing,
677                         go->board_info->inputs[input].video_input, 0,
678                         go->board_info->video_config);
679         if (go->board_info->num_aud_inputs) {
680                 int aud_input = go->board_info->inputs[input].audio_index;
681
682                 v4l2_subdev_call(go->sd_audio, audio, s_routing,
683                         go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
684                 go->aud_input = aud_input;
685         }
686 }
687
688 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
689 {
690         struct go7007 *go = video_drvdata(file);
691
692         if (input >= go->board_info->num_inputs)
693                 return -EINVAL;
694         if (vb2_is_busy(&go->vidq))
695                 return -EBUSY;
696
697         go->input = input;
698         go7007_s_input(go);
699
700         return 0;
701 }
702
703 static int vidioc_g_tuner(struct file *file, void *priv,
704                                 struct v4l2_tuner *t)
705 {
706         struct go7007 *go = video_drvdata(file);
707
708         if (t->index != 0)
709                 return -EINVAL;
710
711         strscpy(t->name, "Tuner", sizeof(t->name));
712         return call_all(&go->v4l2_dev, tuner, g_tuner, t);
713 }
714
715 static int vidioc_s_tuner(struct file *file, void *priv,
716                                 const struct v4l2_tuner *t)
717 {
718         struct go7007 *go = video_drvdata(file);
719
720         if (t->index != 0)
721                 return -EINVAL;
722
723         return call_all(&go->v4l2_dev, tuner, s_tuner, t);
724 }
725
726 static int vidioc_g_frequency(struct file *file, void *priv,
727                                 struct v4l2_frequency *f)
728 {
729         struct go7007 *go = video_drvdata(file);
730
731         if (f->tuner)
732                 return -EINVAL;
733
734         return call_all(&go->v4l2_dev, tuner, g_frequency, f);
735 }
736
737 static int vidioc_s_frequency(struct file *file, void *priv,
738                                 const struct v4l2_frequency *f)
739 {
740         struct go7007 *go = video_drvdata(file);
741
742         if (f->tuner)
743                 return -EINVAL;
744
745         return call_all(&go->v4l2_dev, tuner, s_frequency, f);
746 }
747
748 static int vidioc_log_status(struct file *file, void *priv)
749 {
750         struct go7007 *go = video_drvdata(file);
751
752         v4l2_ctrl_log_status(file, priv);
753         return call_all(&go->v4l2_dev, core, log_status);
754 }
755
756 static int vidioc_subscribe_event(struct v4l2_fh *fh,
757                                 const struct v4l2_event_subscription *sub)
758 {
759
760         switch (sub->type) {
761         case V4L2_EVENT_MOTION_DET:
762                 /* Allow for up to 30 events (1 second for NTSC) to be
763                  * stored. */
764                 return v4l2_event_subscribe(fh, sub, 30, NULL);
765         default:
766                 return v4l2_ctrl_subscribe_event(fh, sub);
767         }
768 }
769
770
771 static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
772 {
773         struct go7007 *go =
774                 container_of(ctrl->handler, struct go7007, hdl);
775         unsigned y;
776         u8 *mt;
777
778         switch (ctrl->id) {
779         case V4L2_CID_PIXEL_THRESHOLD0:
780                 go->modet[0].pixel_threshold = ctrl->val;
781                 break;
782         case V4L2_CID_MOTION_THRESHOLD0:
783                 go->modet[0].motion_threshold = ctrl->val;
784                 break;
785         case V4L2_CID_MB_THRESHOLD0:
786                 go->modet[0].mb_threshold = ctrl->val;
787                 break;
788         case V4L2_CID_PIXEL_THRESHOLD1:
789                 go->modet[1].pixel_threshold = ctrl->val;
790                 break;
791         case V4L2_CID_MOTION_THRESHOLD1:
792                 go->modet[1].motion_threshold = ctrl->val;
793                 break;
794         case V4L2_CID_MB_THRESHOLD1:
795                 go->modet[1].mb_threshold = ctrl->val;
796                 break;
797         case V4L2_CID_PIXEL_THRESHOLD2:
798                 go->modet[2].pixel_threshold = ctrl->val;
799                 break;
800         case V4L2_CID_MOTION_THRESHOLD2:
801                 go->modet[2].motion_threshold = ctrl->val;
802                 break;
803         case V4L2_CID_MB_THRESHOLD2:
804                 go->modet[2].mb_threshold = ctrl->val;
805                 break;
806         case V4L2_CID_PIXEL_THRESHOLD3:
807                 go->modet[3].pixel_threshold = ctrl->val;
808                 break;
809         case V4L2_CID_MOTION_THRESHOLD3:
810                 go->modet[3].motion_threshold = ctrl->val;
811                 break;
812         case V4L2_CID_MB_THRESHOLD3:
813                 go->modet[3].mb_threshold = ctrl->val;
814                 break;
815         case V4L2_CID_DETECT_MD_REGION_GRID:
816                 mt = go->modet_map;
817                 for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
818                         memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
819                 break;
820         default:
821                 return -EINVAL;
822         }
823         return 0;
824 }
825
826 static const struct v4l2_file_operations go7007_fops = {
827         .owner          = THIS_MODULE,
828         .open           = v4l2_fh_open,
829         .release        = vb2_fop_release,
830         .unlocked_ioctl = video_ioctl2,
831         .read           = vb2_fop_read,
832         .mmap           = vb2_fop_mmap,
833         .poll           = vb2_fop_poll,
834 };
835
836 static const struct v4l2_ioctl_ops video_ioctl_ops = {
837         .vidioc_querycap          = vidioc_querycap,
838         .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
839         .vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
840         .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
841         .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
842         .vidioc_reqbufs           = vb2_ioctl_reqbufs,
843         .vidioc_querybuf          = vb2_ioctl_querybuf,
844         .vidioc_qbuf              = vb2_ioctl_qbuf,
845         .vidioc_dqbuf             = vb2_ioctl_dqbuf,
846         .vidioc_g_std             = vidioc_g_std,
847         .vidioc_s_std             = vidioc_s_std,
848         .vidioc_querystd          = vidioc_querystd,
849         .vidioc_enum_input        = vidioc_enum_input,
850         .vidioc_g_input           = vidioc_g_input,
851         .vidioc_s_input           = vidioc_s_input,
852         .vidioc_enumaudio         = vidioc_enumaudio,
853         .vidioc_g_audio           = vidioc_g_audio,
854         .vidioc_s_audio           = vidioc_s_audio,
855         .vidioc_streamon          = vb2_ioctl_streamon,
856         .vidioc_streamoff         = vb2_ioctl_streamoff,
857         .vidioc_g_tuner           = vidioc_g_tuner,
858         .vidioc_s_tuner           = vidioc_s_tuner,
859         .vidioc_g_frequency       = vidioc_g_frequency,
860         .vidioc_s_frequency       = vidioc_s_frequency,
861         .vidioc_g_parm            = vidioc_g_parm,
862         .vidioc_s_parm            = vidioc_s_parm,
863         .vidioc_enum_framesizes   = vidioc_enum_framesizes,
864         .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
865         .vidioc_log_status        = vidioc_log_status,
866         .vidioc_subscribe_event   = vidioc_subscribe_event,
867         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
868 };
869
870 static const struct video_device go7007_template = {
871         .name           = "go7007",
872         .fops           = &go7007_fops,
873         .release        = video_device_release_empty,
874         .ioctl_ops      = &video_ioctl_ops,
875         .tvnorms        = V4L2_STD_ALL,
876 };
877
878 static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
879         .s_ctrl = go7007_s_ctrl,
880 };
881
882 static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
883         .ops = &go7007_ctrl_ops,
884         .id = V4L2_CID_PIXEL_THRESHOLD0,
885         .name = "Pixel Threshold Region 0",
886         .type = V4L2_CTRL_TYPE_INTEGER,
887         .def = 20,
888         .max = 32767,
889         .step = 1,
890 };
891
892 static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
893         .ops = &go7007_ctrl_ops,
894         .id = V4L2_CID_MOTION_THRESHOLD0,
895         .name = "Motion Threshold Region 0",
896         .type = V4L2_CTRL_TYPE_INTEGER,
897         .def = 80,
898         .max = 32767,
899         .step = 1,
900 };
901
902 static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
903         .ops = &go7007_ctrl_ops,
904         .id = V4L2_CID_MB_THRESHOLD0,
905         .name = "MB Threshold Region 0",
906         .type = V4L2_CTRL_TYPE_INTEGER,
907         .def = 200,
908         .max = 32767,
909         .step = 1,
910 };
911
912 static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
913         .ops = &go7007_ctrl_ops,
914         .id = V4L2_CID_PIXEL_THRESHOLD1,
915         .name = "Pixel Threshold Region 1",
916         .type = V4L2_CTRL_TYPE_INTEGER,
917         .def = 20,
918         .max = 32767,
919         .step = 1,
920 };
921
922 static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
923         .ops = &go7007_ctrl_ops,
924         .id = V4L2_CID_MOTION_THRESHOLD1,
925         .name = "Motion Threshold Region 1",
926         .type = V4L2_CTRL_TYPE_INTEGER,
927         .def = 80,
928         .max = 32767,
929         .step = 1,
930 };
931
932 static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
933         .ops = &go7007_ctrl_ops,
934         .id = V4L2_CID_MB_THRESHOLD1,
935         .name = "MB Threshold Region 1",
936         .type = V4L2_CTRL_TYPE_INTEGER,
937         .def = 200,
938         .max = 32767,
939         .step = 1,
940 };
941
942 static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
943         .ops = &go7007_ctrl_ops,
944         .id = V4L2_CID_PIXEL_THRESHOLD2,
945         .name = "Pixel Threshold Region 2",
946         .type = V4L2_CTRL_TYPE_INTEGER,
947         .def = 20,
948         .max = 32767,
949         .step = 1,
950 };
951
952 static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
953         .ops = &go7007_ctrl_ops,
954         .id = V4L2_CID_MOTION_THRESHOLD2,
955         .name = "Motion Threshold Region 2",
956         .type = V4L2_CTRL_TYPE_INTEGER,
957         .def = 80,
958         .max = 32767,
959         .step = 1,
960 };
961
962 static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
963         .ops = &go7007_ctrl_ops,
964         .id = V4L2_CID_MB_THRESHOLD2,
965         .name = "MB Threshold Region 2",
966         .type = V4L2_CTRL_TYPE_INTEGER,
967         .def = 200,
968         .max = 32767,
969         .step = 1,
970 };
971
972 static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
973         .ops = &go7007_ctrl_ops,
974         .id = V4L2_CID_PIXEL_THRESHOLD3,
975         .name = "Pixel Threshold Region 3",
976         .type = V4L2_CTRL_TYPE_INTEGER,
977         .def = 20,
978         .max = 32767,
979         .step = 1,
980 };
981
982 static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
983         .ops = &go7007_ctrl_ops,
984         .id = V4L2_CID_MOTION_THRESHOLD3,
985         .name = "Motion Threshold Region 3",
986         .type = V4L2_CTRL_TYPE_INTEGER,
987         .def = 80,
988         .max = 32767,
989         .step = 1,
990 };
991
992 static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
993         .ops = &go7007_ctrl_ops,
994         .id = V4L2_CID_MB_THRESHOLD3,
995         .name = "MB Threshold Region 3",
996         .type = V4L2_CTRL_TYPE_INTEGER,
997         .def = 200,
998         .max = 32767,
999         .step = 1,
1000 };
1001
1002 static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
1003         .ops = &go7007_ctrl_ops,
1004         .id = V4L2_CID_DETECT_MD_REGION_GRID,
1005         .dims = { 576 / 16, 720 / 16 },
1006         .max = 3,
1007         .step = 1,
1008 };
1009
1010 int go7007_v4l2_ctrl_init(struct go7007 *go)
1011 {
1012         struct v4l2_ctrl_handler *hdl = &go->hdl;
1013         struct v4l2_ctrl *ctrl;
1014
1015         v4l2_ctrl_handler_init(hdl, 22);
1016         go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
1017                         V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
1018         go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
1019                         V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
1020         go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
1021                         V4L2_CID_MPEG_VIDEO_BITRATE,
1022                         64000, 10000000, 1, 9800000);
1023         go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
1024                         V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
1025         go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
1026                         V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
1027
1028         go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
1029                         V4L2_CID_MPEG_VIDEO_ASPECT,
1030                         V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
1031                         V4L2_MPEG_VIDEO_ASPECT_1x1);
1032         ctrl = v4l2_ctrl_new_std(hdl, NULL,
1033                         V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1034                         V4L2_JPEG_ACTIVE_MARKER_DQT |
1035                         V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1036                         V4L2_JPEG_ACTIVE_MARKER_DQT |
1037                         V4L2_JPEG_ACTIVE_MARKER_DHT);
1038         if (ctrl)
1039                 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1040         v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
1041         v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
1042         v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
1043         v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
1044         v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
1045         v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
1046         v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
1047         v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
1048         v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
1049         v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
1050         v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
1051         v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
1052         v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
1053         go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
1054                         V4L2_CID_DETECT_MD_MODE,
1055                         V4L2_DETECT_MD_MODE_REGION_GRID,
1056                         1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
1057                         V4L2_DETECT_MD_MODE_DISABLED);
1058         if (hdl->error) {
1059                 int rv = hdl->error;
1060
1061                 v4l2_err(&go->v4l2_dev, "Could not register controls\n");
1062                 return rv;
1063         }
1064         go->v4l2_dev.ctrl_handler = hdl;
1065         return 0;
1066 }
1067
1068 int go7007_v4l2_init(struct go7007 *go)
1069 {
1070         struct video_device *vdev = &go->vdev;
1071         int rv;
1072
1073         mutex_init(&go->serialize_lock);
1074         mutex_init(&go->queue_lock);
1075
1076         INIT_LIST_HEAD(&go->vidq_active);
1077         go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1078         go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1079         go->vidq.ops = &go7007_video_qops;
1080         go->vidq.mem_ops = &vb2_vmalloc_memops;
1081         go->vidq.drv_priv = go;
1082         go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
1083         go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1084         go->vidq.lock = &go->queue_lock;
1085         rv = vb2_queue_init(&go->vidq);
1086         if (rv)
1087                 return rv;
1088         *vdev = go7007_template;
1089         vdev->lock = &go->serialize_lock;
1090         vdev->queue = &go->vidq;
1091         vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1092                             V4L2_CAP_STREAMING;
1093         if (go->board_info->num_aud_inputs)
1094                 vdev->device_caps |= V4L2_CAP_AUDIO;
1095         if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
1096                 vdev->device_caps |= V4L2_CAP_TUNER;
1097         video_set_drvdata(vdev, go);
1098         vdev->v4l2_dev = &go->v4l2_dev;
1099         if (!v4l2_device_has_op(&go->v4l2_dev, 0, video, querystd))
1100                 v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1101         if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1102                 v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1103                 v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1104                 v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1105                 v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1106         } else {
1107                 struct v4l2_frequency f = {
1108                         .type = V4L2_TUNER_ANALOG_TV,
1109                         .frequency = 980,
1110                 };
1111
1112                 call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1113         }
1114         if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1115                 v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1116                 v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1117                 vdev->tvnorms = 0;
1118         }
1119         if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1120                 v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1121         if (go->board_info->num_aud_inputs == 0) {
1122                 v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1123                 v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1124                 v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1125         }
1126         /* Setup correct crystal frequency on this board */
1127         if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1128                 v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1129                                 SAA7115_FREQ_24_576_MHZ,
1130                                 SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1131                                 SAA7115_FREQ_FL_DOUBLE_ASCLK);
1132         go7007_s_input(go);
1133         if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1134                 go7007_s_std(go);
1135         rv = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1136         if (rv < 0)
1137                 return rv;
1138         dev_info(go->dev, "registered device %s [v4l2]\n",
1139                  video_device_node_name(vdev));
1140
1141         return 0;
1142 }
1143
1144 void go7007_v4l2_remove(struct go7007 *go)
1145 {
1146         v4l2_ctrl_handler_free(&go->hdl);
1147 }
This page took 0.100934 seconds and 4 git commands to generate.