video.c revision 1.39 1 /* $NetBSD: video.c,v 1.39 2020/08/13 16:45:58 riastradh Exp $ */
2
3 /*
4 * Copyright (c) 2008 Patrick Mahoney <pat (at) polycrystal.org>
5 * All rights reserved.
6 *
7 * This code was written by Patrick Mahoney (pat (at) polycrystal.org) as
8 * part of Google Summer of Code 2008.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * This ia a Video4Linux 2 compatible /dev/video driver for NetBSD
34 *
35 * See http://v4l2spec.bytesex.org/ for Video4Linux 2 specifications
36 */
37
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: video.c,v 1.39 2020/08/13 16:45:58 riastradh Exp $");
40
41 #include "video.h"
42 #if NVIDEO > 0
43
44 #include <sys/param.h>
45 #include <sys/ioctl.h>
46 #include <sys/fcntl.h>
47 #include <sys/vnode.h>
48 #include <sys/poll.h>
49 #include <sys/select.h>
50 #include <sys/kmem.h>
51 #include <sys/pool.h>
52 #include <sys/conf.h>
53 #include <sys/types.h>
54 #include <sys/device.h>
55 #include <sys/condvar.h>
56 #include <sys/queue.h>
57 #include <sys/videoio.h>
58
59 #include <dev/video_if.h>
60
61 #include "ioconf.h"
62
63 /* #define VIDEO_DEBUG 1 */
64
65 #ifdef VIDEO_DEBUG
66 #define DPRINTF(x) do { if (videodebug) printf x; } while (0)
67 #define DPRINTFN(n,x) do { if (videodebug>(n)) printf x; } while (0)
68 int videodebug = VIDEO_DEBUG;
69 #else
70 #define DPRINTF(x)
71 #define DPRINTFN(n,x)
72 #endif
73
74 #define PAGE_ALIGN(a) (((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
75
76 #define VIDEO_DRIVER_VERSION \
77 (((__NetBSD_Version__ / 100000000) << 16) | \
78 ((__NetBSD_Version__ / 1000000 % 100) << 8) | \
79 (__NetBSD_Version__ / 100 % 100))
80
81 /* TODO: move to sys/intr.h */
82 #define IPL_VIDEO IPL_VM
83 #define splvideo() splvm()
84
85 #define VIDEO_MIN_BUFS 2
86 #define VIDEO_MAX_BUFS 32
87 #define VIDEO_NUM_BUFS 4
88
89 /* Scatter Buffer - an array of fixed size (PAGE_SIZE) chunks
90 * allocated non-contiguously and functions to get data into and out
91 * of the scatter buffer. */
92 struct scatter_buf {
93 pool_cache_t sb_pool;
94 size_t sb_size; /* size in bytes */
95 size_t sb_npages; /* number of pages */
96 uint8_t **sb_page_ary; /* array of page pointers */
97 };
98
99 struct scatter_io {
100 struct scatter_buf *sio_buf;
101 off_t sio_offset;
102 size_t sio_resid;
103 };
104
105 static void scatter_buf_init(struct scatter_buf *);
106 static void scatter_buf_destroy(struct scatter_buf *);
107 static int scatter_buf_set_size(struct scatter_buf *, size_t);
108 static paddr_t scatter_buf_map(struct scatter_buf *, off_t);
109
110 static bool scatter_io_init(struct scatter_buf *, off_t, size_t, struct scatter_io *);
111 static bool scatter_io_next(struct scatter_io *, void **, size_t *);
112 static void scatter_io_undo(struct scatter_io *, size_t);
113 static void scatter_io_copyin(struct scatter_io *, const void *);
114 /* static void scatter_io_copyout(struct scatter_io *, void *); */
115 static int scatter_io_uiomove(struct scatter_io *, struct uio *);
116
117
118 enum video_stream_method {
119 VIDEO_STREAM_METHOD_NONE,
120 VIDEO_STREAM_METHOD_READ,
121 VIDEO_STREAM_METHOD_MMAP,
122 VIDEO_STREAM_METHOD_USERPTR
123 };
124
125 struct video_buffer {
126 struct v4l2_buffer *vb_buf;
127 SIMPLEQ_ENTRY(video_buffer) entries;
128 };
129
130 SIMPLEQ_HEAD(sample_queue, video_buffer);
131
132 struct video_stream {
133 int vs_flags; /* flags given to open() */
134
135 struct video_format vs_format;
136
137 int vs_frameno; /* toggles between 0 and 1,
138 * or -1 if new */
139 uint32_t vs_sequence; /* absoulte frame/sample number in
140 * sequence, wraps around */
141 bool vs_drop; /* drop payloads from current
142 * frameno? */
143
144 enum v4l2_buf_type vs_type;
145 uint8_t vs_nbufs;
146 struct video_buffer **vs_buf;
147
148 struct scatter_buf vs_data; /* stores video data for MMAP
149 * and READ */
150
151 /* Video samples may exist in different locations. Initially,
152 * samples are queued into the ingress queue. The driver
153 * grabs these in turn and fills them with video data. Once
154 * filled, they are moved to the egress queue. Samples are
155 * dequeued either by user with MMAP method or, with READ
156 * method, videoread() works from the fist sample in the
157 * ingress queue without dequeing. In the first case, the
158 * user re-queues the buffer when finished, and videoread()
159 * does the same when all data has been read. The sample now
160 * returns to the ingress queue. */
161 struct sample_queue vs_ingress; /* samples under driver control */
162 struct sample_queue vs_egress; /* samples headed for userspace */
163
164 bool vs_streaming;
165 enum video_stream_method vs_method; /* method by which
166 * userspace will read
167 * samples */
168
169 kmutex_t vs_lock; /* Lock to manipulate queues.
170 * Should also be held when
171 * changing number of
172 * buffers. */
173 kcondvar_t vs_sample_cv; /* signaled on new
174 * ingress sample */
175 struct selinfo vs_sel;
176
177 uint32_t vs_bytesread; /* bytes read() from current
178 * sample thus far */
179 };
180
181 struct video_softc {
182 device_t sc_dev;
183 device_t hw_dev; /* Hardware (parent) device */
184 void * hw_softc; /* Hardware device private softc */
185 const struct video_hw_if *hw_if; /* Hardware interface */
186
187 u_int sc_open;
188 int sc_refcnt;
189 int sc_opencnt;
190 bool sc_dying;
191
192 struct video_stream sc_stream_in;
193 };
194 static int video_print(void *, const char *);
195
196 static int video_match(device_t, cfdata_t, void *);
197 static void video_attach(device_t, device_t, void *);
198 static int video_detach(device_t, int);
199 static int video_activate(device_t, enum devact);
200
201 dev_type_open(videoopen);
202 dev_type_close(videoclose);
203 dev_type_read(videoread);
204 dev_type_write(videowrite);
205 dev_type_ioctl(videoioctl);
206 dev_type_poll(videopoll);
207 dev_type_mmap(videommap);
208
209 const struct cdevsw video_cdevsw = {
210 .d_open = videoopen,
211 .d_close = videoclose,
212 .d_read = videoread,
213 .d_write = videowrite,
214 .d_ioctl = videoioctl,
215 .d_stop = nostop,
216 .d_tty = notty,
217 .d_poll = videopoll,
218 .d_mmap = videommap,
219 .d_kqfilter = nokqfilter,
220 .d_discard = nodiscard,
221 .d_flag = D_OTHER
222 };
223
224 #define VIDEOUNIT(n) (minor(n))
225
226 CFATTACH_DECL_NEW(video, sizeof(struct video_softc),
227 video_match, video_attach, video_detach, video_activate);
228
229 static const char * video_pixel_format_str(enum video_pixel_format);
230
231 /* convert various values from V4L2 to native values of this driver */
232 static uint16_t v4l2id_to_control_id(uint32_t);
233 static uint32_t control_flags_to_v4l2flags(uint32_t);
234 static enum v4l2_ctrl_type control_type_to_v4l2type(enum video_control_type);
235
236 static void v4l2_format_to_video_format(const struct v4l2_format *,
237 struct video_format *);
238 static void video_format_to_v4l2_format(const struct video_format *,
239 struct v4l2_format *);
240 static void v4l2_standard_to_video_standard(v4l2_std_id,
241 enum video_standard *);
242 static void video_standard_to_v4l2_standard(enum video_standard,
243 struct v4l2_standard *);
244 static void v4l2_input_to_video_input(const struct v4l2_input *,
245 struct video_input *);
246 static void video_input_to_v4l2_input(const struct video_input *,
247 struct v4l2_input *);
248 static void v4l2_audio_to_video_audio(const struct v4l2_audio *,
249 struct video_audio *);
250 static void video_audio_to_v4l2_audio(const struct video_audio *,
251 struct v4l2_audio *);
252 static void v4l2_tuner_to_video_tuner(const struct v4l2_tuner *,
253 struct video_tuner *);
254 static void video_tuner_to_v4l2_tuner(const struct video_tuner *,
255 struct v4l2_tuner *);
256
257 /* V4L2 api functions, typically called from videoioctl() */
258 static int video_enum_format(struct video_softc *, struct v4l2_fmtdesc *);
259 static int video_get_format(struct video_softc *,
260 struct v4l2_format *);
261 static int video_set_format(struct video_softc *,
262 struct v4l2_format *);
263 static int video_try_format(struct video_softc *,
264 struct v4l2_format *);
265 static int video_get_parm(struct video_softc *,
266 struct v4l2_streamparm *);
267 static int video_set_parm(struct video_softc *,
268 struct v4l2_streamparm *);
269 static int video_enum_standard(struct video_softc *,
270 struct v4l2_standard *);
271 static int video_get_standard(struct video_softc *, v4l2_std_id *);
272 static int video_set_standard(struct video_softc *, v4l2_std_id);
273 static int video_enum_input(struct video_softc *, struct v4l2_input *);
274 static int video_get_input(struct video_softc *, int *);
275 static int video_set_input(struct video_softc *, int);
276 static int video_enum_audio(struct video_softc *, struct v4l2_audio *);
277 static int video_get_audio(struct video_softc *, struct v4l2_audio *);
278 static int video_set_audio(struct video_softc *, struct v4l2_audio *);
279 static int video_get_tuner(struct video_softc *, struct v4l2_tuner *);
280 static int video_set_tuner(struct video_softc *, struct v4l2_tuner *);
281 static int video_get_frequency(struct video_softc *,
282 struct v4l2_frequency *);
283 static int video_set_frequency(struct video_softc *,
284 struct v4l2_frequency *);
285 static int video_query_control(struct video_softc *,
286 struct v4l2_queryctrl *);
287 static int video_get_control(struct video_softc *,
288 struct v4l2_control *);
289 static int video_set_control(struct video_softc *,
290 const struct v4l2_control *);
291 static int video_request_bufs(struct video_softc *,
292 struct v4l2_requestbuffers *);
293 static int video_query_buf(struct video_softc *, struct v4l2_buffer *);
294 static int video_queue_buf(struct video_softc *, struct v4l2_buffer *);
295 static int video_dequeue_buf(struct video_softc *, struct v4l2_buffer *);
296 static int video_stream_on(struct video_softc *, enum v4l2_buf_type);
297 static int video_stream_off(struct video_softc *, enum v4l2_buf_type);
298
299 static struct video_buffer * video_buffer_alloc(void);
300 static void video_buffer_free(struct video_buffer *);
301
302
303 /* functions for video_stream */
304 static void video_stream_init(struct video_stream *);
305 static void video_stream_fini(struct video_stream *);
306
307 static int video_stream_setup_bufs(struct video_stream *,
308 enum video_stream_method,
309 uint8_t);
310 static void video_stream_teardown_bufs(struct video_stream *);
311
312 static int video_stream_realloc_bufs(struct video_stream *, uint8_t);
313 #define video_stream_free_bufs(vs) \
314 video_stream_realloc_bufs((vs), 0)
315
316 static void video_stream_enqueue(struct video_stream *,
317 struct video_buffer *);
318 static struct video_buffer * video_stream_dequeue(struct video_stream *);
319 static void video_stream_write(struct video_stream *,
320 const struct video_payload *);
321 static void video_stream_sample_done(struct video_stream *);
322
323 #ifdef VIDEO_DEBUG
324 /* debugging */
325 static const char * video_ioctl_str(u_long);
326 #endif
327
328
329 static int
330 video_match(device_t parent, cfdata_t match, void *aux)
331 {
332 #ifdef VIDEO_DEBUG
333 struct video_attach_args *args;
334
335 args = aux;
336 DPRINTF(("video_match: hw=%p\n", args->hw_if));
337 #endif
338 return 1;
339 }
340
341
342 static void
343 video_attach(device_t parent, device_t self, void *aux)
344 {
345 struct video_softc *sc;
346 struct video_attach_args *args;
347
348 sc = device_private(self);
349 args = aux;
350
351 sc->sc_dev = self;
352 sc->hw_dev = parent;
353 sc->hw_if = args->hw_if;
354 sc->hw_softc = device_private(parent);
355
356 sc->sc_open = 0;
357 sc->sc_refcnt = 0;
358 sc->sc_opencnt = 0;
359 sc->sc_dying = false;
360
361 video_stream_init(&sc->sc_stream_in);
362
363 aprint_naive("\n");
364 aprint_normal(": %s\n", sc->hw_if->get_devname(sc->hw_softc));
365
366 DPRINTF(("video_attach: sc=%p hwif=%p\n", sc, sc->hw_if));
367
368 if (!pmf_device_register(self, NULL, NULL))
369 aprint_error_dev(self, "couldn't establish power handler\n");
370 }
371
372
373 static int
374 video_activate(device_t self, enum devact act)
375 {
376 struct video_softc *sc = device_private(self);
377
378 DPRINTF(("video_activate: sc=%p\n", sc));
379 switch (act) {
380 case DVACT_DEACTIVATE:
381 sc->sc_dying = true;
382 return 0;
383 default:
384 return EOPNOTSUPP;
385 }
386 }
387
388
389 static int
390 video_detach(device_t self, int flags)
391 {
392 struct video_softc *sc;
393 int maj, mn;
394
395 sc = device_private(self);
396 DPRINTF(("video_detach: sc=%p flags=%d\n", sc, flags));
397
398 sc->sc_dying = true;
399
400 pmf_device_deregister(self);
401
402 maj = cdevsw_lookup_major(&video_cdevsw);
403 mn = device_unit(self);
404 /* close open instances */
405 vdevgone(maj, mn, mn, VCHR);
406
407 video_stream_fini(&sc->sc_stream_in);
408
409 return 0;
410 }
411
412
413 static int
414 video_print(void *aux, const char *pnp)
415 {
416 if (pnp != NULL) {
417 DPRINTF(("video_print: have pnp\n"));
418 aprint_normal("%s at %s\n", "video", pnp);
419 } else {
420 DPRINTF(("video_print: pnp is NULL\n"));
421 }
422 return UNCONF;
423 }
424
425
426 /*
427 * Called from hardware driver. This is where the MI audio driver
428 * gets probed/attached to the hardware driver.
429 */
430 device_t
431 video_attach_mi(const struct video_hw_if *hw_if, device_t parent)
432 {
433 struct video_attach_args args;
434
435 args.hw_if = hw_if;
436 return config_found_ia(parent, "videobus", &args, video_print);
437 }
438
439 /* video_submit_payload - called by hardware driver to submit payload data */
440 void
441 video_submit_payload(device_t self, const struct video_payload *payload)
442 {
443 struct video_softc *sc;
444
445 sc = device_private(self);
446
447 if (sc == NULL)
448 return;
449
450 video_stream_write(&sc->sc_stream_in, payload);
451 }
452
453 static const char *
454 video_pixel_format_str(enum video_pixel_format px)
455 {
456 switch (px) {
457 case VIDEO_FORMAT_UYVY: return "UYVY";
458 case VIDEO_FORMAT_YUV420: return "YUV420";
459 case VIDEO_FORMAT_YUY2: return "YUYV";
460 case VIDEO_FORMAT_NV12: return "NV12";
461 case VIDEO_FORMAT_RGB24: return "RGB24";
462 case VIDEO_FORMAT_RGB555: return "RGB555";
463 case VIDEO_FORMAT_RGB565: return "RGB565";
464 case VIDEO_FORMAT_SBGGR8: return "SBGGR8";
465 case VIDEO_FORMAT_MJPEG: return "MJPEG";
466 case VIDEO_FORMAT_DV: return "DV";
467 case VIDEO_FORMAT_MPEG: return "MPEG";
468 default: return "Unknown";
469 }
470 }
471
472 /* Takes a V4L2 id and returns a "native" video driver control id.
473 * TODO: is there a better way to do this? some kind of array? */
474 static uint16_t
475 v4l2id_to_control_id(uint32_t v4l2id)
476 {
477 /* mask includes class bits and control id bits */
478 switch (v4l2id & 0xffffff) {
479 case V4L2_CID_BRIGHTNESS: return VIDEO_CONTROL_BRIGHTNESS;
480 case V4L2_CID_CONTRAST: return VIDEO_CONTROL_CONTRAST;
481 case V4L2_CID_SATURATION: return VIDEO_CONTROL_SATURATION;
482 case V4L2_CID_HUE: return VIDEO_CONTROL_HUE;
483 case V4L2_CID_HUE_AUTO: return VIDEO_CONTROL_HUE_AUTO;
484 case V4L2_CID_SHARPNESS: return VIDEO_CONTROL_SHARPNESS;
485 case V4L2_CID_GAMMA: return VIDEO_CONTROL_GAMMA;
486
487 /* "black level" means the same as "brightness", but V4L2
488 * defines two separate controls that are not identical.
489 * V4L2_CID_BLACK_LEVEL is deprecated however in V4L2. */
490 case V4L2_CID_BLACK_LEVEL: return VIDEO_CONTROL_BRIGHTNESS;
491
492 case V4L2_CID_AUDIO_VOLUME: return VIDEO_CONTROL_UNDEFINED;
493 case V4L2_CID_AUDIO_BALANCE: return VIDEO_CONTROL_UNDEFINED;
494 case V4L2_CID_AUDIO_BASS: return VIDEO_CONTROL_UNDEFINED;
495 case V4L2_CID_AUDIO_TREBLE: return VIDEO_CONTROL_UNDEFINED;
496 case V4L2_CID_AUDIO_MUTE: return VIDEO_CONTROL_UNDEFINED;
497 case V4L2_CID_AUDIO_LOUDNESS: return VIDEO_CONTROL_UNDEFINED;
498
499 case V4L2_CID_AUTO_WHITE_BALANCE:
500 return VIDEO_CONTROL_WHITE_BALANCE_AUTO;
501 case V4L2_CID_DO_WHITE_BALANCE:
502 return VIDEO_CONTROL_WHITE_BALANCE_ACTION;
503 case V4L2_CID_RED_BALANCE:
504 case V4L2_CID_BLUE_BALANCE:
505 /* This might not fit in with the control_id/value_id scheme */
506 return VIDEO_CONTROL_WHITE_BALANCE_COMPONENT;
507 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
508 return VIDEO_CONTROL_WHITE_BALANCE_TEMPERATURE;
509 case V4L2_CID_EXPOSURE:
510 return VIDEO_CONTROL_EXPOSURE_TIME_ABSOLUTE;
511 case V4L2_CID_GAIN: return VIDEO_CONTROL_GAIN;
512 case V4L2_CID_AUTOGAIN: return VIDEO_CONTROL_GAIN_AUTO;
513 case V4L2_CID_HFLIP: return VIDEO_CONTROL_HFLIP;
514 case V4L2_CID_VFLIP: return VIDEO_CONTROL_VFLIP;
515 case V4L2_CID_HCENTER_DEPRECATED:
516 case V4L2_CID_VCENTER_DEPRECATED:
517 return VIDEO_CONTROL_UNDEFINED;
518 case V4L2_CID_POWER_LINE_FREQUENCY:
519 return VIDEO_CONTROL_POWER_LINE_FREQUENCY;
520 case V4L2_CID_BACKLIGHT_COMPENSATION:
521 return VIDEO_CONTROL_BACKLIGHT_COMPENSATION;
522 default: return V4L2_CTRL_ID2CID(v4l2id);
523 }
524 }
525
526
527 static uint32_t
528 control_flags_to_v4l2flags(uint32_t flags)
529 {
530 uint32_t v4l2flags = 0;
531
532 if (flags & VIDEO_CONTROL_FLAG_DISABLED)
533 v4l2flags |= V4L2_CTRL_FLAG_INACTIVE;
534
535 if (!(flags & VIDEO_CONTROL_FLAG_WRITE))
536 v4l2flags |= V4L2_CTRL_FLAG_READ_ONLY;
537
538 if (flags & VIDEO_CONTROL_FLAG_AUTOUPDATE)
539 v4l2flags |= V4L2_CTRL_FLAG_GRABBED;
540
541 return v4l2flags;
542 }
543
544
545 static enum v4l2_ctrl_type
546 control_type_to_v4l2type(enum video_control_type type) {
547 switch (type) {
548 case VIDEO_CONTROL_TYPE_INT: return V4L2_CTRL_TYPE_INTEGER;
549 case VIDEO_CONTROL_TYPE_BOOL: return V4L2_CTRL_TYPE_BOOLEAN;
550 case VIDEO_CONTROL_TYPE_LIST: return V4L2_CTRL_TYPE_MENU;
551 case VIDEO_CONTROL_TYPE_ACTION: return V4L2_CTRL_TYPE_BUTTON;
552 default: return V4L2_CTRL_TYPE_INTEGER; /* err? */
553 }
554 }
555
556
557 static int
558 video_query_control(struct video_softc *sc,
559 struct v4l2_queryctrl *query)
560 {
561 const struct video_hw_if *hw;
562 struct video_control_desc_group desc_group;
563 struct video_control_desc desc;
564 int err;
565
566 hw = sc->hw_if;
567 if (hw->get_control_desc_group) {
568 desc.group_id = desc.control_id =
569 v4l2id_to_control_id(query->id);
570
571 desc_group.group_id = desc.group_id;
572 desc_group.length = 1;
573 desc_group.desc = &desc;
574
575 err = hw->get_control_desc_group(sc->hw_softc, &desc_group);
576 if (err != 0)
577 return err;
578
579 query->type = control_type_to_v4l2type(desc.type);
580 memcpy(query->name, desc.name, 32);
581 query->minimum = desc.min;
582 query->maximum = desc.max;
583 query->step = desc.step;
584 query->default_value = desc.def;
585 query->flags = control_flags_to_v4l2flags(desc.flags);
586
587 return 0;
588 } else {
589 return EINVAL;
590 }
591 }
592
593
594 /* Takes a single Video4Linux2 control and queries the driver for the
595 * current value. */
596 static int
597 video_get_control(struct video_softc *sc,
598 struct v4l2_control *vcontrol)
599 {
600 const struct video_hw_if *hw;
601 struct video_control_group group;
602 struct video_control control;
603 int err;
604
605 hw = sc->hw_if;
606 if (hw->get_control_group) {
607 control.group_id = control.control_id =
608 v4l2id_to_control_id(vcontrol->id);
609 /* ?? if "control_id" is arbitrarily defined by the
610 * driver, then we need some way to store it... Maybe
611 * it doesn't matter for single value controls. */
612 control.value = 0;
613
614 group.group_id = control.group_id;
615 group.length = 1;
616 group.control = &control;
617
618 err = hw->get_control_group(sc->hw_softc, &group);
619 if (err != 0)
620 return err;
621
622 vcontrol->value = control.value;
623 return 0;
624 } else {
625 return EINVAL;
626 }
627 }
628
629 static void
630 video_format_to_v4l2_format(const struct video_format *src,
631 struct v4l2_format *dest)
632 {
633 /* TODO: what about win and vbi formats? */
634 dest->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
635 dest->fmt.pix.width = src->width;
636 dest->fmt.pix.height = src->height;
637 if (VIDEO_INTERLACED(src->interlace_flags))
638 dest->fmt.pix.field = V4L2_FIELD_INTERLACED;
639 else
640 dest->fmt.pix.field = V4L2_FIELD_NONE;
641 dest->fmt.pix.bytesperline = src->stride;
642 dest->fmt.pix.sizeimage = src->sample_size;
643 dest->fmt.pix.priv = src->priv;
644
645 switch (src->color.primaries) {
646 case VIDEO_COLOR_PRIMARIES_SMPTE_170M:
647 dest->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
648 break;
649 /* XXX */
650 case VIDEO_COLOR_PRIMARIES_UNSPECIFIED:
651 default:
652 dest->fmt.pix.colorspace = 0;
653 break;
654 }
655
656 switch (src->pixel_format) {
657 case VIDEO_FORMAT_UYVY:
658 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
659 break;
660 case VIDEO_FORMAT_YUV420:
661 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
662 break;
663 case VIDEO_FORMAT_YUY2:
664 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
665 break;
666 case VIDEO_FORMAT_NV12:
667 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
668 break;
669 case VIDEO_FORMAT_RGB24:
670 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
671 break;
672 case VIDEO_FORMAT_RGB555:
673 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB555;
674 break;
675 case VIDEO_FORMAT_RGB565:
676 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
677 break;
678 case VIDEO_FORMAT_SBGGR8:
679 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
680 break;
681 case VIDEO_FORMAT_MJPEG:
682 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
683 break;
684 case VIDEO_FORMAT_DV:
685 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_DV;
686 break;
687 case VIDEO_FORMAT_MPEG:
688 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
689 break;
690 case VIDEO_FORMAT_UNDEFINED:
691 default:
692 DPRINTF(("video_get_format: unknown pixel format %d\n",
693 src->pixel_format));
694 dest->fmt.pix.pixelformat = 0; /* V4L2 doesn't define
695 * and "undefined"
696 * format? */
697 break;
698 }
699
700 }
701
702 static void
703 v4l2_format_to_video_format(const struct v4l2_format *src,
704 struct video_format *dest)
705 {
706 switch (src->type) {
707 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
708 dest->width = src->fmt.pix.width;
709 dest->height = src->fmt.pix.height;
710
711 dest->stride = src->fmt.pix.bytesperline;
712 dest->sample_size = src->fmt.pix.sizeimage;
713
714 if (src->fmt.pix.field == V4L2_FIELD_INTERLACED)
715 dest->interlace_flags = VIDEO_INTERLACE_ON;
716 else
717 dest->interlace_flags = VIDEO_INTERLACE_OFF;
718
719 switch (src->fmt.pix.colorspace) {
720 case V4L2_COLORSPACE_SMPTE170M:
721 dest->color.primaries =
722 VIDEO_COLOR_PRIMARIES_SMPTE_170M;
723 break;
724 /* XXX */
725 default:
726 dest->color.primaries =
727 VIDEO_COLOR_PRIMARIES_UNSPECIFIED;
728 break;
729 }
730
731 switch (src->fmt.pix.pixelformat) {
732 case V4L2_PIX_FMT_UYVY:
733 dest->pixel_format = VIDEO_FORMAT_UYVY;
734 break;
735 case V4L2_PIX_FMT_YUV420:
736 dest->pixel_format = VIDEO_FORMAT_YUV420;
737 break;
738 case V4L2_PIX_FMT_YUYV:
739 dest->pixel_format = VIDEO_FORMAT_YUY2;
740 break;
741 case V4L2_PIX_FMT_NV12:
742 dest->pixel_format = VIDEO_FORMAT_NV12;
743 break;
744 case V4L2_PIX_FMT_RGB24:
745 dest->pixel_format = VIDEO_FORMAT_RGB24;
746 break;
747 case V4L2_PIX_FMT_RGB555:
748 dest->pixel_format = VIDEO_FORMAT_RGB555;
749 break;
750 case V4L2_PIX_FMT_RGB565:
751 dest->pixel_format = VIDEO_FORMAT_RGB565;
752 break;
753 case V4L2_PIX_FMT_SBGGR8:
754 dest->pixel_format = VIDEO_FORMAT_SBGGR8;
755 break;
756 case V4L2_PIX_FMT_MJPEG:
757 dest->pixel_format = VIDEO_FORMAT_MJPEG;
758 break;
759 case V4L2_PIX_FMT_DV:
760 dest->pixel_format = VIDEO_FORMAT_DV;
761 break;
762 case V4L2_PIX_FMT_MPEG:
763 dest->pixel_format = VIDEO_FORMAT_MPEG;
764 break;
765 default:
766 DPRINTF(("video: unknown v4l2 pixel format %d\n",
767 src->fmt.pix.pixelformat));
768 dest->pixel_format = VIDEO_FORMAT_UNDEFINED;
769 break;
770 }
771 break;
772 default:
773 /* TODO: other v4l2 format types */
774 DPRINTF(("video: unsupported v4l2 format type %d\n",
775 src->type));
776 break;
777 }
778 }
779
780 static int
781 video_enum_format(struct video_softc *sc, struct v4l2_fmtdesc *fmtdesc)
782 {
783 const struct video_hw_if *hw;
784 struct video_format vfmt;
785 struct v4l2_format fmt;
786 int err;
787
788 hw = sc->hw_if;
789 if (hw->enum_format == NULL)
790 return ENOTTY;
791
792 err = hw->enum_format(sc->hw_softc, fmtdesc->index, &vfmt);
793 if (err != 0)
794 return err;
795
796 video_format_to_v4l2_format(&vfmt, &fmt);
797
798 fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* TODO: only one type for now */
799 fmtdesc->flags = 0;
800 if (vfmt.pixel_format >= VIDEO_FORMAT_MJPEG)
801 fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
802 strlcpy(fmtdesc->description,
803 video_pixel_format_str(vfmt.pixel_format),
804 sizeof(fmtdesc->description));
805 fmtdesc->pixelformat = fmt.fmt.pix.pixelformat;
806
807 return 0;
808 }
809
810 static int
811 video_enum_framesizes(struct video_softc *sc, struct v4l2_frmsizeenum *frmdesc)
812 {
813 const struct video_hw_if *hw;
814 struct video_format vfmt;
815 struct v4l2_format fmt;
816 int err;
817
818 hw = sc->hw_if;
819 if (hw->enum_format == NULL)
820 return ENOTTY;
821
822 err = hw->enum_format(sc->hw_softc, frmdesc->index, &vfmt);
823 if (err != 0)
824 return err;
825
826 video_format_to_v4l2_format(&vfmt, &fmt);
827 if (fmt.fmt.pix.pixelformat != frmdesc->pixel_format) {
828 printf("video_enum_framesizes: type mismatch %x %x\n",
829 fmt.fmt.pix.pixelformat, frmdesc->pixel_format);
830 }
831
832 frmdesc->type = V4L2_FRMSIZE_TYPE_DISCRETE; /* TODO: only one type for now */
833 frmdesc->discrete.width = vfmt.width;
834 frmdesc->discrete.height = vfmt.height;
835 return 0;
836 }
837
838 static int
839 video_enum_frameival(struct video_softc *sc, struct v4l2_frmivalenum *frmdesc)
840 {
841 const struct video_hw_if *hw;
842
843 hw = sc->hw_if;
844 if (hw->enum_format == NULL)
845 return ENOTTY;
846
847 frmdesc->type = V4L2_FRMSIZE_TYPE_DISCRETE;
848 frmdesc->discrete.numerator = 1;
849 frmdesc->discrete.denominator = 15;
850 return 0;
851 }
852
853 static int
854 video_get_format(struct video_softc *sc,
855 struct v4l2_format *format)
856 {
857 const struct video_hw_if *hw;
858 struct video_format vfmt;
859 int err;
860
861 hw = sc->hw_if;
862 if (hw->get_format == NULL)
863 return ENOTTY;
864
865 err = hw->get_format(sc->hw_softc, &vfmt);
866 if (err != 0)
867 return err;
868
869 video_format_to_v4l2_format(&vfmt, format);
870
871 return 0;
872 }
873
874 static int
875 video_set_format(struct video_softc *sc, struct v4l2_format *fmt)
876 {
877 const struct video_hw_if *hw;
878 struct video_format vfmt;
879 int err;
880
881 hw = sc->hw_if;
882 if (hw->set_format == NULL)
883 return ENOTTY;
884
885 v4l2_format_to_video_format(fmt, &vfmt);
886
887 err = hw->set_format(sc->hw_softc, &vfmt);
888 if (err != 0)
889 return err;
890
891 video_format_to_v4l2_format(&vfmt, fmt);
892 sc->sc_stream_in.vs_format = vfmt;
893
894 return 0;
895 }
896
897
898 static int
899 video_try_format(struct video_softc *sc,
900 struct v4l2_format *format)
901 {
902 const struct video_hw_if *hw;
903 struct video_format vfmt;
904 int err;
905
906 hw = sc->hw_if;
907 if (hw->try_format == NULL)
908 return ENOTTY;
909
910 v4l2_format_to_video_format(format, &vfmt);
911
912 err = hw->try_format(sc->hw_softc, &vfmt);
913 if (err != 0)
914 return err;
915
916 video_format_to_v4l2_format(&vfmt, format);
917
918 return 0;
919 }
920
921 static int
922 video_get_parm(struct video_softc *sc, struct v4l2_streamparm *parm)
923 {
924 struct video_fract fract;
925 const struct video_hw_if *hw;
926 int error;
927
928 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
929 return EINVAL;
930
931 hw = sc->hw_if;
932 if (hw == NULL)
933 return ENXIO;
934
935 memset(&parm->parm, 0, sizeof(parm->parm));
936 if (hw->get_framerate != NULL) {
937 error = hw->get_framerate(sc->hw_softc, &fract);
938 if (error != 0)
939 return error;
940 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
941 parm->parm.capture.timeperframe.numerator = fract.numerator;
942 parm->parm.capture.timeperframe.denominator = fract.denominator;
943 }
944
945 return 0;
946 }
947
948 static int
949 video_set_parm(struct video_softc *sc, struct v4l2_streamparm *parm)
950 {
951 struct video_fract fract;
952 const struct video_hw_if *hw;
953 int error;
954
955 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
956 return EINVAL;
957
958 hw = sc->hw_if;
959 if (hw == NULL || hw->set_framerate == NULL)
960 return ENXIO;
961
962 error = hw->set_framerate(sc->hw_softc, &fract);
963 if (error != 0)
964 return error;
965
966 parm->parm.capture.timeperframe.numerator = fract.numerator;
967 parm->parm.capture.timeperframe.denominator = fract.denominator;
968
969 return 0;
970 }
971
972 static void
973 v4l2_standard_to_video_standard(v4l2_std_id stdid,
974 enum video_standard *vstd)
975 {
976 #define VSTD(id, vid) case (id): *vstd = (vid); break;
977 switch (stdid) {
978 VSTD(V4L2_STD_NTSC_M, VIDEO_STANDARD_NTSC_M)
979 default:
980 *vstd = VIDEO_STANDARD_UNKNOWN;
981 break;
982 }
983 #undef VSTD
984 }
985
986 static void
987 video_standard_to_v4l2_standard(enum video_standard vstd,
988 struct v4l2_standard *std)
989 {
990 switch (vstd) {
991 case VIDEO_STANDARD_NTSC_M:
992 std->id = V4L2_STD_NTSC_M;
993 strlcpy(std->name, "NTSC-M", sizeof(std->name));
994 std->frameperiod.numerator = 1001;
995 std->frameperiod.denominator = 30000;
996 std->framelines = 525;
997 break;
998 default:
999 std->id = V4L2_STD_UNKNOWN;
1000 strlcpy(std->name, "Unknown", sizeof(std->name));
1001 break;
1002 }
1003 }
1004
1005 static int
1006 video_enum_standard(struct video_softc *sc, struct v4l2_standard *std)
1007 {
1008 const struct video_hw_if *hw = sc->hw_if;
1009 enum video_standard vstd;
1010 int err;
1011
1012 /* simple webcam drivers don't need to implement this callback */
1013 if (hw->enum_standard == NULL) {
1014 if (std->index != 0)
1015 return EINVAL;
1016 std->id = V4L2_STD_UNKNOWN;
1017 strlcpy(std->name, "webcam", sizeof(std->name));
1018 return 0;
1019 }
1020
1021 v4l2_standard_to_video_standard(std->id, &vstd);
1022
1023 err = hw->enum_standard(sc->hw_softc, std->index, &vstd);
1024 if (err != 0)
1025 return err;
1026
1027 video_standard_to_v4l2_standard(vstd, std);
1028
1029 return 0;
1030 }
1031
1032 static int
1033 video_get_standard(struct video_softc *sc, v4l2_std_id *stdid)
1034 {
1035 const struct video_hw_if *hw = sc->hw_if;
1036 struct v4l2_standard std;
1037 enum video_standard vstd;
1038 int err;
1039
1040 /* simple webcam drivers don't need to implement this callback */
1041 if (hw->get_standard == NULL) {
1042 *stdid = V4L2_STD_UNKNOWN;
1043 return 0;
1044 }
1045
1046 err = hw->get_standard(sc->hw_softc, &vstd);
1047 if (err != 0)
1048 return err;
1049
1050 video_standard_to_v4l2_standard(vstd, &std);
1051 *stdid = std.id;
1052
1053 return 0;
1054 }
1055
1056 static int
1057 video_set_standard(struct video_softc *sc, v4l2_std_id stdid)
1058 {
1059 const struct video_hw_if *hw = sc->hw_if;
1060 enum video_standard vstd;
1061
1062 /* simple webcam drivers don't need to implement this callback */
1063 if (hw->set_standard == NULL) {
1064 if (stdid != V4L2_STD_UNKNOWN)
1065 return EINVAL;
1066 return 0;
1067 }
1068
1069 v4l2_standard_to_video_standard(stdid, &vstd);
1070
1071 return hw->set_standard(sc->hw_softc, vstd);
1072 }
1073
1074 static void
1075 v4l2_input_to_video_input(const struct v4l2_input *input,
1076 struct video_input *vi)
1077 {
1078 vi->index = input->index;
1079 strlcpy(vi->name, input->name, sizeof(vi->name));
1080 switch (input->type) {
1081 case V4L2_INPUT_TYPE_TUNER:
1082 vi->type = VIDEO_INPUT_TYPE_TUNER;
1083 break;
1084 case V4L2_INPUT_TYPE_CAMERA:
1085 vi->type = VIDEO_INPUT_TYPE_CAMERA;
1086 break;
1087 }
1088 vi->audiomask = input->audioset;
1089 vi->tuner_index = input->tuner;
1090 vi->standards = input->std; /* ... values are the same */
1091 vi->status = 0;
1092 if (input->status & V4L2_IN_ST_NO_POWER)
1093 vi->status |= VIDEO_STATUS_NO_POWER;
1094 if (input->status & V4L2_IN_ST_NO_SIGNAL)
1095 vi->status |= VIDEO_STATUS_NO_SIGNAL;
1096 if (input->status & V4L2_IN_ST_NO_COLOR)
1097 vi->status |= VIDEO_STATUS_NO_COLOR;
1098 if (input->status & V4L2_IN_ST_NO_H_LOCK)
1099 vi->status |= VIDEO_STATUS_NO_HLOCK;
1100 if (input->status & V4L2_IN_ST_MACROVISION)
1101 vi->status |= VIDEO_STATUS_MACROVISION;
1102 }
1103
1104 static void
1105 video_input_to_v4l2_input(const struct video_input *vi,
1106 struct v4l2_input *input)
1107 {
1108 input->index = vi->index;
1109 strlcpy(input->name, vi->name, sizeof(input->name));
1110 switch (vi->type) {
1111 case VIDEO_INPUT_TYPE_TUNER:
1112 input->type = V4L2_INPUT_TYPE_TUNER;
1113 break;
1114 case VIDEO_INPUT_TYPE_CAMERA:
1115 input->type = V4L2_INPUT_TYPE_CAMERA;
1116 break;
1117 }
1118 input->audioset = vi->audiomask;
1119 input->tuner = vi->tuner_index;
1120 input->std = vi->standards; /* ... values are the same */
1121 input->status = 0;
1122 if (vi->status & VIDEO_STATUS_NO_POWER)
1123 input->status |= V4L2_IN_ST_NO_POWER;
1124 if (vi->status & VIDEO_STATUS_NO_SIGNAL)
1125 input->status |= V4L2_IN_ST_NO_SIGNAL;
1126 if (vi->status & VIDEO_STATUS_NO_COLOR)
1127 input->status |= V4L2_IN_ST_NO_COLOR;
1128 if (vi->status & VIDEO_STATUS_NO_HLOCK)
1129 input->status |= V4L2_IN_ST_NO_H_LOCK;
1130 if (vi->status & VIDEO_STATUS_MACROVISION)
1131 input->status |= V4L2_IN_ST_MACROVISION;
1132 }
1133
1134 static int
1135 video_enum_input(struct video_softc *sc, struct v4l2_input *input)
1136 {
1137 const struct video_hw_if *hw = sc->hw_if;
1138 struct video_input vi;
1139 int err;
1140
1141 /* simple webcam drivers don't need to implement this callback */
1142 if (hw->enum_input == NULL) {
1143 if (input->index != 0)
1144 return EINVAL;
1145 memset(input, 0, sizeof(*input));
1146 input->index = 0;
1147 strlcpy(input->name, "Camera", sizeof(input->name));
1148 input->type = V4L2_INPUT_TYPE_CAMERA;
1149 return 0;
1150 }
1151
1152 v4l2_input_to_video_input(input, &vi);
1153
1154 err = hw->enum_input(sc->hw_softc, input->index, &vi);
1155 if (err != 0)
1156 return err;
1157
1158 video_input_to_v4l2_input(&vi, input);
1159
1160 return 0;
1161 }
1162
1163 static int
1164 video_get_input(struct video_softc *sc, int *index)
1165 {
1166 const struct video_hw_if *hw = sc->hw_if;
1167 struct video_input vi;
1168 struct v4l2_input input;
1169 int err;
1170
1171 /* simple webcam drivers don't need to implement this callback */
1172 if (hw->get_input == NULL) {
1173 *index = 0;
1174 return 0;
1175 }
1176
1177 input.index = *index;
1178 v4l2_input_to_video_input(&input, &vi);
1179
1180 err = hw->get_input(sc->hw_softc, &vi);
1181 if (err != 0)
1182 return err;
1183
1184 video_input_to_v4l2_input(&vi, &input);
1185 *index = input.index;
1186
1187 return 0;
1188 }
1189
1190 static int
1191 video_set_input(struct video_softc *sc, int index)
1192 {
1193 const struct video_hw_if *hw = sc->hw_if;
1194 struct video_input vi;
1195 struct v4l2_input input;
1196
1197 /* simple webcam drivers don't need to implement this callback */
1198 if (hw->set_input == NULL) {
1199 if (index != 0)
1200 return EINVAL;
1201 return 0;
1202 }
1203
1204 input.index = index;
1205 v4l2_input_to_video_input(&input, &vi);
1206
1207 return hw->set_input(sc->hw_softc, &vi);
1208 }
1209
1210 static void
1211 v4l2_audio_to_video_audio(const struct v4l2_audio *audio,
1212 struct video_audio *va)
1213 {
1214 va->index = audio->index;
1215 strlcpy(va->name, audio->name, sizeof(va->name));
1216 va->caps = va->mode = 0;
1217 if (audio->capability & V4L2_AUDCAP_STEREO)
1218 va->caps |= VIDEO_AUDIO_F_STEREO;
1219 if (audio->capability & V4L2_AUDCAP_AVL)
1220 va->caps |= VIDEO_AUDIO_F_AVL;
1221 if (audio->mode & V4L2_AUDMODE_AVL)
1222 va->mode |= VIDEO_AUDIO_F_AVL;
1223 }
1224
1225 static void
1226 video_audio_to_v4l2_audio(const struct video_audio *va,
1227 struct v4l2_audio *audio)
1228 {
1229 audio->index = va->index;
1230 strlcpy(audio->name, va->name, sizeof(audio->name));
1231 audio->capability = audio->mode = 0;
1232 if (va->caps & VIDEO_AUDIO_F_STEREO)
1233 audio->capability |= V4L2_AUDCAP_STEREO;
1234 if (va->caps & VIDEO_AUDIO_F_AVL)
1235 audio->capability |= V4L2_AUDCAP_AVL;
1236 if (va->mode & VIDEO_AUDIO_F_AVL)
1237 audio->mode |= V4L2_AUDMODE_AVL;
1238 }
1239
1240 static int
1241 video_enum_audio(struct video_softc *sc, struct v4l2_audio *audio)
1242 {
1243 const struct video_hw_if *hw = sc->hw_if;
1244 struct video_audio va;
1245 int err;
1246
1247 if (hw->enum_audio == NULL)
1248 return ENOTTY;
1249
1250 v4l2_audio_to_video_audio(audio, &va);
1251
1252 err = hw->enum_audio(sc->hw_softc, audio->index, &va);
1253 if (err != 0)
1254 return err;
1255
1256 video_audio_to_v4l2_audio(&va, audio);
1257
1258 return 0;
1259 }
1260
1261 static int
1262 video_get_audio(struct video_softc *sc, struct v4l2_audio *audio)
1263 {
1264 const struct video_hw_if *hw = sc->hw_if;
1265 struct video_audio va;
1266 int err;
1267
1268 if (hw->get_audio == NULL)
1269 return ENOTTY;
1270
1271 v4l2_audio_to_video_audio(audio, &va);
1272
1273 err = hw->get_audio(sc->hw_softc, &va);
1274 if (err != 0)
1275 return err;
1276
1277 video_audio_to_v4l2_audio(&va, audio);
1278
1279 return 0;
1280 }
1281
1282 static int
1283 video_set_audio(struct video_softc *sc, struct v4l2_audio *audio)
1284 {
1285 const struct video_hw_if *hw = sc->hw_if;
1286 struct video_audio va;
1287
1288 if (hw->set_audio == NULL)
1289 return ENOTTY;
1290
1291 v4l2_audio_to_video_audio(audio, &va);
1292
1293 return hw->set_audio(sc->hw_softc, &va);
1294 }
1295
1296 static void
1297 v4l2_tuner_to_video_tuner(const struct v4l2_tuner *tuner,
1298 struct video_tuner *vt)
1299 {
1300 vt->index = tuner->index;
1301 strlcpy(vt->name, tuner->name, sizeof(vt->name));
1302 vt->freq_lo = tuner->rangelow;
1303 vt->freq_hi = tuner->rangehigh;
1304 vt->signal = tuner->signal;
1305 vt->afc = tuner->afc;
1306 vt->caps = 0;
1307 if (tuner->capability & V4L2_TUNER_CAP_STEREO)
1308 vt->caps |= VIDEO_TUNER_F_STEREO;
1309 if (tuner->capability & V4L2_TUNER_CAP_LANG1)
1310 vt->caps |= VIDEO_TUNER_F_LANG1;
1311 if (tuner->capability & V4L2_TUNER_CAP_LANG2)
1312 vt->caps |= VIDEO_TUNER_F_LANG2;
1313 switch (tuner->audmode) {
1314 case V4L2_TUNER_MODE_MONO:
1315 vt->mode = VIDEO_TUNER_F_MONO;
1316 break;
1317 case V4L2_TUNER_MODE_STEREO:
1318 vt->mode = VIDEO_TUNER_F_STEREO;
1319 break;
1320 case V4L2_TUNER_MODE_LANG1:
1321 vt->mode = VIDEO_TUNER_F_LANG1;
1322 break;
1323 case V4L2_TUNER_MODE_LANG2:
1324 vt->mode = VIDEO_TUNER_F_LANG2;
1325 break;
1326 case V4L2_TUNER_MODE_LANG1_LANG2:
1327 vt->mode = VIDEO_TUNER_F_LANG1 | VIDEO_TUNER_F_LANG2;
1328 break;
1329 }
1330 }
1331
1332 static void
1333 video_tuner_to_v4l2_tuner(const struct video_tuner *vt,
1334 struct v4l2_tuner *tuner)
1335 {
1336 tuner->index = vt->index;
1337 strlcpy(tuner->name, vt->name, sizeof(tuner->name));
1338 tuner->rangelow = vt->freq_lo;
1339 tuner->rangehigh = vt->freq_hi;
1340 tuner->signal = vt->signal;
1341 tuner->afc = vt->afc;
1342 tuner->capability = 0;
1343 if (vt->caps & VIDEO_TUNER_F_STEREO)
1344 tuner->capability |= V4L2_TUNER_CAP_STEREO;
1345 if (vt->caps & VIDEO_TUNER_F_LANG1)
1346 tuner->capability |= V4L2_TUNER_CAP_LANG1;
1347 if (vt->caps & VIDEO_TUNER_F_LANG2)
1348 tuner->capability |= V4L2_TUNER_CAP_LANG2;
1349 switch (vt->mode) {
1350 case VIDEO_TUNER_F_MONO:
1351 tuner->audmode = V4L2_TUNER_MODE_MONO;
1352 break;
1353 case VIDEO_TUNER_F_STEREO:
1354 tuner->audmode = V4L2_TUNER_MODE_STEREO;
1355 break;
1356 case VIDEO_TUNER_F_LANG1:
1357 tuner->audmode = V4L2_TUNER_MODE_LANG1;
1358 break;
1359 case VIDEO_TUNER_F_LANG2:
1360 tuner->audmode = V4L2_TUNER_MODE_LANG2;
1361 break;
1362 case VIDEO_TUNER_F_LANG1|VIDEO_TUNER_F_LANG2:
1363 tuner->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
1364 break;
1365 }
1366 }
1367
1368 static int
1369 video_get_tuner(struct video_softc *sc, struct v4l2_tuner *tuner)
1370 {
1371 const struct video_hw_if *hw = sc->hw_if;
1372 struct video_tuner vt;
1373 int err;
1374
1375 if (hw->get_tuner == NULL)
1376 return ENOTTY;
1377
1378 v4l2_tuner_to_video_tuner(tuner, &vt);
1379
1380 err = hw->get_tuner(sc->hw_softc, &vt);
1381 if (err != 0)
1382 return err;
1383
1384 video_tuner_to_v4l2_tuner(&vt, tuner);
1385
1386 return 0;
1387 }
1388
1389 static int
1390 video_set_tuner(struct video_softc *sc, struct v4l2_tuner *tuner)
1391 {
1392 const struct video_hw_if *hw = sc->hw_if;
1393 struct video_tuner vt;
1394
1395 if (hw->set_tuner == NULL)
1396 return ENOTTY;
1397
1398 v4l2_tuner_to_video_tuner(tuner, &vt);
1399
1400 return hw->set_tuner(sc->hw_softc, &vt);
1401 }
1402
1403 static int
1404 video_get_frequency(struct video_softc *sc, struct v4l2_frequency *freq)
1405 {
1406 const struct video_hw_if *hw = sc->hw_if;
1407 struct video_frequency vfreq;
1408 int err;
1409
1410 if (hw->get_frequency == NULL)
1411 return ENOTTY;
1412
1413 err = hw->get_frequency(sc->hw_softc, &vfreq);
1414 if (err)
1415 return err;
1416
1417 freq->tuner = vfreq.tuner_index;
1418 freq->type = V4L2_TUNER_ANALOG_TV;
1419 freq->frequency = vfreq.frequency;
1420
1421 return 0;
1422 }
1423
1424 static int
1425 video_set_frequency(struct video_softc *sc, struct v4l2_frequency *freq)
1426 {
1427 const struct video_hw_if *hw = sc->hw_if;
1428 struct video_frequency vfreq;
1429 struct video_tuner vt;
1430 int error;
1431
1432 if (hw->set_frequency == NULL || hw->get_tuner == NULL)
1433 return ENOTTY;
1434 if (freq->type != V4L2_TUNER_ANALOG_TV)
1435 return EINVAL;
1436
1437 vt.index = freq->tuner;
1438 error = hw->get_tuner(sc->hw_softc, &vt);
1439 if (error)
1440 return error;
1441
1442 if (freq->frequency < vt.freq_lo)
1443 freq->frequency = vt.freq_lo;
1444 else if (freq->frequency > vt.freq_hi)
1445 freq->frequency = vt.freq_hi;
1446
1447 vfreq.tuner_index = freq->tuner;
1448 vfreq.frequency = freq->frequency;
1449
1450 return hw->set_frequency(sc->hw_softc, &vfreq);
1451 }
1452
1453 /* Takes a single Video4Linux2 control, converts it to a struct
1454 * video_control, and calls the hardware driver. */
1455 static int
1456 video_set_control(struct video_softc *sc,
1457 const struct v4l2_control *vcontrol)
1458 {
1459 const struct video_hw_if *hw;
1460 struct video_control_group group;
1461 struct video_control control;
1462
1463 hw = sc->hw_if;
1464 if (hw->set_control_group) {
1465 control.group_id = control.control_id =
1466 v4l2id_to_control_id(vcontrol->id);
1467 /* ?? if "control_id" is arbitrarily defined by the
1468 * driver, then we need some way to store it... Maybe
1469 * it doesn't matter for single value controls. */
1470 control.value = vcontrol->value;
1471
1472 group.group_id = control.group_id;
1473 group.length = 1;
1474 group.control = &control;
1475
1476 return (hw->set_control_group(sc->hw_softc, &group));
1477 } else {
1478 return EINVAL;
1479 }
1480 }
1481
1482 static int
1483 video_request_bufs(struct video_softc *sc,
1484 struct v4l2_requestbuffers *req)
1485 {
1486 struct video_stream *vs = &sc->sc_stream_in;
1487 struct v4l2_buffer *buf;
1488 int i, err;
1489
1490 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1491 return EINVAL;
1492
1493 vs->vs_type = req->type;
1494
1495 switch (req->memory) {
1496 case V4L2_MEMORY_MMAP:
1497 if (req->count < VIDEO_MIN_BUFS)
1498 req->count = VIDEO_MIN_BUFS;
1499 else if (req->count > VIDEO_MAX_BUFS)
1500 req->count = VIDEO_MAX_BUFS;
1501
1502 err = video_stream_setup_bufs(vs,
1503 VIDEO_STREAM_METHOD_MMAP,
1504 req->count);
1505 if (err != 0)
1506 return err;
1507
1508 for (i = 0; i < req->count; ++i) {
1509 buf = vs->vs_buf[i]->vb_buf;
1510 buf->memory = V4L2_MEMORY_MMAP;
1511 buf->flags |= V4L2_BUF_FLAG_MAPPED;
1512 }
1513 break;
1514 case V4L2_MEMORY_USERPTR:
1515 default:
1516 return EINVAL;
1517 }
1518
1519 return 0;
1520 }
1521
1522 static int
1523 video_query_buf(struct video_softc *sc,
1524 struct v4l2_buffer *buf)
1525 {
1526 struct video_stream *vs = &sc->sc_stream_in;
1527
1528 if (buf->type != vs->vs_type)
1529 return EINVAL;
1530 if (buf->index >= vs->vs_nbufs)
1531 return EINVAL;
1532
1533 memcpy(buf, vs->vs_buf[buf->index]->vb_buf, sizeof(*buf));
1534
1535 return 0;
1536 }
1537
1538 /* Accept a buffer descriptor from userspace and return the indicated
1539 * buffer to the driver's queue. */
1540 static int
1541 video_queue_buf(struct video_softc *sc, struct v4l2_buffer *userbuf)
1542 {
1543 struct video_stream *vs = &sc->sc_stream_in;
1544 struct video_buffer *vb;
1545 struct v4l2_buffer *driverbuf;
1546
1547 if (userbuf->type != vs->vs_type) {
1548 DPRINTF(("video_queue_buf: expected type=%d got type=%d\n",
1549 userbuf->type, vs->vs_type));
1550 return EINVAL;
1551 }
1552 if (userbuf->index >= vs->vs_nbufs) {
1553 DPRINTF(("video_queue_buf: invalid index %d >= %d\n",
1554 userbuf->index, vs->vs_nbufs));
1555 return EINVAL;
1556 }
1557
1558 switch (vs->vs_method) {
1559 case VIDEO_STREAM_METHOD_MMAP:
1560 if (userbuf->memory != V4L2_MEMORY_MMAP) {
1561 DPRINTF(("video_queue_buf: invalid memory=%d\n",
1562 userbuf->memory));
1563 return EINVAL;
1564 }
1565
1566 mutex_enter(&vs->vs_lock);
1567
1568 vb = vs->vs_buf[userbuf->index];
1569 driverbuf = vb->vb_buf;
1570 if (driverbuf->flags & V4L2_BUF_FLAG_QUEUED) {
1571 DPRINTF(("video_queue_buf: buf already queued; "
1572 "flags=0x%x\n", driverbuf->flags));
1573 mutex_exit(&vs->vs_lock);
1574 return EINVAL;
1575 }
1576 video_stream_enqueue(vs, vb);
1577 memcpy(userbuf, driverbuf, sizeof(*driverbuf));
1578
1579 mutex_exit(&vs->vs_lock);
1580 break;
1581 default:
1582 return EINVAL;
1583 }
1584
1585 return 0;
1586 }
1587
1588 /* Dequeue the described buffer from the driver queue, making it
1589 * available for reading via mmap. */
1590 static int
1591 video_dequeue_buf(struct video_softc *sc, struct v4l2_buffer *buf)
1592 {
1593 struct video_stream *vs = &sc->sc_stream_in;
1594 struct video_buffer *vb;
1595 int err;
1596
1597 if (buf->type != vs->vs_type) {
1598 aprint_debug_dev(sc->sc_dev,
1599 "requested type %d (expected %d)\n",
1600 buf->type, vs->vs_type);
1601 return EINVAL;
1602 }
1603
1604 switch (vs->vs_method) {
1605 case VIDEO_STREAM_METHOD_MMAP:
1606 if (buf->memory != V4L2_MEMORY_MMAP) {
1607 aprint_debug_dev(sc->sc_dev,
1608 "requested memory %d (expected %d)\n",
1609 buf->memory, V4L2_MEMORY_MMAP);
1610 return EINVAL;
1611 }
1612
1613 mutex_enter(&vs->vs_lock);
1614
1615 if (vs->vs_flags & O_NONBLOCK) {
1616 vb = video_stream_dequeue(vs);
1617 if (vb == NULL) {
1618 mutex_exit(&vs->vs_lock);
1619 return EAGAIN;
1620 }
1621 } else {
1622 /* Block until we have sample */
1623 while ((vb = video_stream_dequeue(vs)) == NULL) {
1624 if (!vs->vs_streaming) {
1625 mutex_exit(&vs->vs_lock);
1626 return EINVAL;
1627 }
1628 err = cv_wait_sig(&vs->vs_sample_cv,
1629 &vs->vs_lock);
1630 if (err != 0) {
1631 mutex_exit(&vs->vs_lock);
1632 return EINTR;
1633 }
1634 }
1635 }
1636
1637 memcpy(buf, vb->vb_buf, sizeof(*buf));
1638
1639 mutex_exit(&vs->vs_lock);
1640 break;
1641 default:
1642 aprint_debug_dev(sc->sc_dev, "unknown vs_method %d\n",
1643 vs->vs_method);
1644 return EINVAL;
1645 }
1646
1647 return 0;
1648 }
1649
1650 static int
1651 video_stream_on(struct video_softc *sc, enum v4l2_buf_type type)
1652 {
1653 int err;
1654 struct video_stream *vs = &sc->sc_stream_in;
1655 const struct video_hw_if *hw;
1656
1657 if (vs->vs_streaming)
1658 return 0;
1659 if (type != vs->vs_type)
1660 return EINVAL;
1661
1662 hw = sc->hw_if;
1663 if (hw == NULL)
1664 return ENXIO;
1665
1666
1667 err = hw->start_transfer(sc->hw_softc);
1668 if (err != 0)
1669 return err;
1670
1671 vs->vs_streaming = true;
1672 return 0;
1673 }
1674
1675 static int
1676 video_stream_off(struct video_softc *sc, enum v4l2_buf_type type)
1677 {
1678 int err;
1679 struct video_stream *vs = &sc->sc_stream_in;
1680 const struct video_hw_if *hw;
1681
1682 if (!vs->vs_streaming)
1683 return 0;
1684 if (type != vs->vs_type)
1685 return EINVAL;
1686
1687 hw = sc->hw_if;
1688 if (hw == NULL)
1689 return ENXIO;
1690
1691 err = hw->stop_transfer(sc->hw_softc);
1692 if (err != 0)
1693 return err;
1694
1695 vs->vs_frameno = -1;
1696 vs->vs_sequence = 0;
1697 vs->vs_streaming = false;
1698
1699 return 0;
1700 }
1701
1702 int
1703 videoopen(dev_t dev, int flags, int ifmt, struct lwp *l)
1704 {
1705 struct video_softc *sc;
1706 const struct video_hw_if *hw;
1707 struct video_stream *vs;
1708 int err;
1709
1710 DPRINTF(("videoopen\n"));
1711
1712 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev)));
1713 if (sc == NULL) {
1714 DPRINTF(("videoopen: failed to get softc for unit %d\n",
1715 VIDEOUNIT(dev)));
1716 return ENXIO;
1717 }
1718
1719 if (sc->sc_dying) {
1720 DPRINTF(("videoopen: dying\n"));
1721 return EIO;
1722 }
1723
1724 sc->sc_stream_in.vs_flags = flags;
1725
1726 DPRINTF(("videoopen: flags=0x%x sc=%p parent=%p\n",
1727 flags, sc, sc->hw_dev));
1728
1729 hw = sc->hw_if;
1730 if (hw == NULL)
1731 return ENXIO;
1732
1733 device_active(sc->sc_dev, DVA_SYSTEM);
1734
1735 sc->sc_opencnt++;
1736
1737 if (hw->open != NULL) {
1738 err = hw->open(sc->hw_softc, flags);
1739 if (err)
1740 return err;
1741 }
1742
1743 /* set up input stream. TODO: check flags to determine if
1744 * "read" is desired? */
1745 vs = &sc->sc_stream_in;
1746
1747 if (hw->get_format != NULL) {
1748 err = hw->get_format(sc->hw_softc, &vs->vs_format);
1749 if (err != 0)
1750 return err;
1751 }
1752 return 0;
1753 }
1754
1755
1756 int
1757 videoclose(dev_t dev, int flags, int ifmt, struct lwp *l)
1758 {
1759 struct video_softc *sc;
1760 const struct video_hw_if *hw;
1761
1762 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev)));
1763 if (sc == NULL)
1764 return ENXIO;
1765
1766 DPRINTF(("videoclose: sc=%p\n", sc));
1767
1768 hw = sc->hw_if;
1769 if (hw == NULL)
1770 return ENXIO;
1771
1772 device_active(sc->sc_dev, DVA_SYSTEM);
1773
1774 video_stream_off(sc, sc->sc_stream_in.vs_type);
1775
1776 /* ignore error */
1777 if (hw->close != NULL)
1778 hw->close(sc->hw_softc);
1779
1780 video_stream_teardown_bufs(&sc->sc_stream_in);
1781
1782 sc->sc_open = 0;
1783 sc->sc_opencnt--;
1784
1785 return 0;
1786 }
1787
1788
1789 int
1790 videoread(dev_t dev, struct uio *uio, int ioflag)
1791 {
1792 struct video_softc *sc;
1793 struct video_stream *vs;
1794 struct video_buffer *vb;
1795 struct scatter_io sio;
1796 int err;
1797 size_t len;
1798 off_t offset;
1799
1800 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev)));
1801 if (sc == NULL)
1802 return ENXIO;
1803
1804 if (sc->sc_dying)
1805 return EIO;
1806
1807 vs = &sc->sc_stream_in;
1808
1809 /* userspace has chosen read() method */
1810 if (vs->vs_method == VIDEO_STREAM_METHOD_NONE) {
1811 err = video_stream_setup_bufs(vs,
1812 VIDEO_STREAM_METHOD_READ,
1813 VIDEO_NUM_BUFS);
1814 if (err != 0)
1815 return err;
1816
1817 err = video_stream_on(sc, vs->vs_type);
1818 if (err != 0)
1819 return err;
1820 } else if (vs->vs_method != VIDEO_STREAM_METHOD_READ) {
1821 return EBUSY;
1822 }
1823
1824 mutex_enter(&vs->vs_lock);
1825
1826 retry:
1827 if (SIMPLEQ_EMPTY(&vs->vs_egress)) {
1828 if (vs->vs_flags & O_NONBLOCK) {
1829 mutex_exit(&vs->vs_lock);
1830 return EAGAIN;
1831 }
1832
1833 /* Block until we have a sample */
1834 while (SIMPLEQ_EMPTY(&vs->vs_egress)) {
1835 err = cv_wait_sig(&vs->vs_sample_cv,
1836 &vs->vs_lock);
1837 if (err != 0) {
1838 mutex_exit(&vs->vs_lock);
1839 return EINTR;
1840 }
1841 }
1842
1843 vb = SIMPLEQ_FIRST(&vs->vs_egress);
1844 } else {
1845 vb = SIMPLEQ_FIRST(&vs->vs_egress);
1846 }
1847
1848 /* Oops, empty sample buffer. */
1849 if (vb->vb_buf->bytesused == 0) {
1850 vb = video_stream_dequeue(vs);
1851 video_stream_enqueue(vs, vb);
1852 vs->vs_bytesread = 0;
1853 goto retry;
1854 }
1855
1856 mutex_exit(&vs->vs_lock);
1857
1858 len = uimin(uio->uio_resid, vb->vb_buf->bytesused - vs->vs_bytesread);
1859 offset = vb->vb_buf->m.offset + vs->vs_bytesread;
1860
1861 if (scatter_io_init(&vs->vs_data, offset, len, &sio)) {
1862 err = scatter_io_uiomove(&sio, uio);
1863 if (err == EFAULT)
1864 return EFAULT;
1865 vs->vs_bytesread += (len - sio.sio_resid);
1866 } else {
1867 DPRINTF(("video: invalid read\n"));
1868 }
1869
1870 /* Move the sample to the ingress queue if everything has
1871 * been read */
1872 if (vs->vs_bytesread >= vb->vb_buf->bytesused) {
1873 mutex_enter(&vs->vs_lock);
1874 vb = video_stream_dequeue(vs);
1875 video_stream_enqueue(vs, vb);
1876 mutex_exit(&vs->vs_lock);
1877
1878 vs->vs_bytesread = 0;
1879 }
1880
1881 return 0;
1882 }
1883
1884
1885 int
1886 videowrite(dev_t dev, struct uio *uio, int ioflag)
1887 {
1888 return ENXIO;
1889 }
1890
1891
1892 /*
1893 * Before 64-bit time_t, timeval's tv_sec was 'long'. Thus on LP64 ports
1894 * v4l2_buffer is the same size and layout as before. However it did change
1895 * on LP32 ports, and we thus handle this difference here for "COMPAT_50".
1896 */
1897
1898 #ifndef _LP64
1899 static void
1900 buf50tobuf(const void *data, struct v4l2_buffer *buf)
1901 {
1902 const struct v4l2_buffer50 *b50 = data;
1903
1904 buf->index = b50->index;
1905 buf->type = b50->type;
1906 buf->bytesused = b50->bytesused;
1907 buf->flags = b50->flags;
1908 buf->field = b50->field;
1909 timeval50_to_timeval(&b50->timestamp, &buf->timestamp);
1910 buf->timecode = b50->timecode;
1911 buf->sequence = b50->sequence;
1912 buf->memory = b50->memory;
1913 buf->m.offset = b50->m.offset;
1914 /* XXX: Handle userptr */
1915 buf->length = b50->length;
1916 buf->reserved2 = b50->reserved2;
1917 buf->reserved = b50->reserved;
1918 }
1919
1920 static void
1921 buftobuf50(void *data, const struct v4l2_buffer *buf)
1922 {
1923 struct v4l2_buffer50 *b50 = data;
1924
1925 b50->index = buf->index;
1926 b50->type = buf->type;
1927 b50->bytesused = buf->bytesused;
1928 b50->flags = buf->flags;
1929 b50->field = buf->field;
1930 timeval_to_timeval50(&buf->timestamp, &b50->timestamp);
1931 b50->timecode = buf->timecode;
1932 b50->sequence = buf->sequence;
1933 b50->memory = buf->memory;
1934 b50->m.offset = buf->m.offset;
1935 /* XXX: Handle userptr */
1936 b50->length = buf->length;
1937 b50->reserved2 = buf->reserved2;
1938 b50->reserved = buf->reserved;
1939 }
1940 #endif
1941
1942 int
1943 videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
1944 {
1945 struct video_softc *sc;
1946 const struct video_hw_if *hw;
1947 struct v4l2_capability *cap;
1948 struct v4l2_fmtdesc *fmtdesc;
1949 struct v4l2_format *fmt;
1950 struct v4l2_standard *std;
1951 struct v4l2_input *input;
1952 struct v4l2_audio *audio;
1953 struct v4l2_tuner *tuner;
1954 struct v4l2_frequency *freq;
1955 struct v4l2_control *control;
1956 struct v4l2_queryctrl *query;
1957 struct v4l2_requestbuffers *reqbufs;
1958 struct v4l2_buffer *buf;
1959 struct v4l2_streamparm *parm;
1960 struct v4l2_frmsizeenum *size;
1961 struct v4l2_frmivalenum *ival;
1962 v4l2_std_id *stdid;
1963 enum v4l2_buf_type *typep;
1964 int *ip;
1965 #ifndef _LP64
1966 struct v4l2_buffer bufspace;
1967 int error;
1968 #endif
1969
1970 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev)));
1971
1972 if (sc->sc_dying)
1973 return EIO;
1974
1975 hw = sc->hw_if;
1976 if (hw == NULL)
1977 return ENXIO;
1978
1979 switch (cmd) {
1980 case VIDIOC_QUERYCAP:
1981 cap = data;
1982 memset(cap, 0, sizeof(*cap));
1983 strlcpy(cap->driver,
1984 device_cfdriver(sc->hw_dev)->cd_name,
1985 sizeof(cap->driver));
1986 strlcpy(cap->card, hw->get_devname(sc->hw_softc),
1987 sizeof(cap->card));
1988 strlcpy(cap->bus_info, hw->get_businfo(sc->hw_softc),
1989 sizeof(cap->bus_info));
1990 cap->version = VIDEO_DRIVER_VERSION;
1991 cap->capabilities = 0;
1992 if (hw->start_transfer != NULL && hw->stop_transfer != NULL)
1993 cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE |
1994 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1995 if (hw->set_tuner != NULL && hw->get_tuner != NULL)
1996 cap->capabilities |= V4L2_CAP_TUNER;
1997 if (hw->set_audio != NULL && hw->get_audio != NULL &&
1998 hw->enum_audio != NULL)
1999 cap->capabilities |= V4L2_CAP_AUDIO;
2000 return 0;
2001 case VIDIOC_ENUM_FMT:
2002 /* TODO: for now, just enumerate one default format */
2003 fmtdesc = data;
2004 if (fmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2005 return EINVAL;
2006 return video_enum_format(sc, fmtdesc);
2007 case VIDIOC_G_FMT:
2008 fmt = data;
2009 return video_get_format(sc, fmt);
2010 case VIDIOC_S_FMT:
2011 fmt = data;
2012 if ((flag & FWRITE) == 0)
2013 return EPERM;
2014 return video_set_format(sc, fmt);
2015 case VIDIOC_TRY_FMT:
2016 fmt = data;
2017 return video_try_format(sc, fmt);
2018 case VIDIOC_G_PARM:
2019 parm = data;
2020 return video_get_parm(sc, parm);
2021 case VIDIOC_S_PARM:
2022 parm = data;
2023 if ((flag & FWRITE) == 0)
2024 return EPERM;
2025 return video_set_parm(sc, parm);
2026 case VIDIOC_ENUMSTD:
2027 std = data;
2028 return video_enum_standard(sc, std);
2029 case VIDIOC_G_STD:
2030 stdid = data;
2031 return video_get_standard(sc, stdid);
2032 case VIDIOC_S_STD:
2033 stdid = data;
2034 if ((flag & FWRITE) == 0)
2035 return EPERM;
2036 return video_set_standard(sc, *stdid);
2037 case VIDIOC_ENUMINPUT:
2038 input = data;
2039 return video_enum_input(sc, input);
2040 case VIDIOC_G_INPUT:
2041 ip = data;
2042 return video_get_input(sc, ip);
2043 case VIDIOC_S_INPUT:
2044 ip = data;
2045 if ((flag & FWRITE) == 0)
2046 return EPERM;
2047 return video_set_input(sc, *ip);
2048 case VIDIOC_ENUMAUDIO:
2049 audio = data;
2050 return video_enum_audio(sc, audio);
2051 case VIDIOC_G_AUDIO:
2052 audio = data;
2053 return video_get_audio(sc, audio);
2054 case VIDIOC_S_AUDIO:
2055 audio = data;
2056 if ((flag & FWRITE) == 0)
2057 return EPERM;
2058 return video_set_audio(sc, audio);
2059 case VIDIOC_G_TUNER:
2060 tuner = data;
2061 return video_get_tuner(sc, tuner);
2062 case VIDIOC_S_TUNER:
2063 tuner = data;
2064 if ((flag & FWRITE) == 0)
2065 return EPERM;
2066 return video_set_tuner(sc, tuner);
2067 case VIDIOC_G_FREQUENCY:
2068 freq = data;
2069 return video_get_frequency(sc, freq);
2070 case VIDIOC_S_FREQUENCY:
2071 freq = data;
2072 if ((flag & FWRITE) == 0)
2073 return EPERM;
2074 return video_set_frequency(sc, freq);
2075 case VIDIOC_QUERYCTRL:
2076 query = data;
2077 return (video_query_control(sc, query));
2078 case VIDIOC_G_CTRL:
2079 control = data;
2080 return (video_get_control(sc, control));
2081 case VIDIOC_S_CTRL:
2082 control = data;
2083 if ((flag & FWRITE) == 0)
2084 return EPERM;
2085 return (video_set_control(sc, control));
2086 case VIDIOC_REQBUFS:
2087 reqbufs = data;
2088 return (video_request_bufs(sc, reqbufs));
2089 case VIDIOC_QUERYBUF:
2090 buf = data;
2091 return video_query_buf(sc, buf);
2092 #ifndef _LP64
2093 case VIDIOC_QUERYBUF50:
2094 buf50tobuf(data, buf = &bufspace);
2095 if ((error = video_query_buf(sc, buf)) != 0)
2096 return error;
2097 buftobuf50(data, buf);
2098 return 0;
2099 #endif
2100 case VIDIOC_QBUF:
2101 buf = data;
2102 return video_queue_buf(sc, buf);
2103 #ifndef _LP64
2104 case VIDIOC_QBUF50:
2105 buf50tobuf(data, buf = &bufspace);
2106 return video_queue_buf(sc, buf);
2107 #endif
2108 case VIDIOC_DQBUF:
2109 buf = data;
2110 return video_dequeue_buf(sc, buf);
2111 #ifndef _LP64
2112 case VIDIOC_DQBUF50:
2113 buf50tobuf(data, buf = &bufspace);
2114 if ((error = video_dequeue_buf(sc, buf)) != 0)
2115 return error;
2116 buftobuf50(data, buf);
2117 return 0;
2118 #endif
2119 case VIDIOC_STREAMON:
2120 typep = data;
2121 return video_stream_on(sc, *typep);
2122 case VIDIOC_STREAMOFF:
2123 typep = data;
2124 return video_stream_off(sc, *typep);
2125 case VIDIOC_ENUM_FRAMESIZES:
2126 size = data;
2127 return video_enum_framesizes(sc, size);
2128 case VIDIOC_ENUM_FRAMEINTERVALS:
2129 ival = data;
2130 return video_enum_frameival(sc, ival);
2131 default:
2132 DPRINTF(("videoioctl: invalid cmd %s (%lx)\n",
2133 video_ioctl_str(cmd), cmd));
2134 return EINVAL;
2135 }
2136 }
2137
2138 #ifdef VIDEO_DEBUG
2139 static const char *
2140 video_ioctl_str(u_long cmd)
2141 {
2142 const char *str;
2143
2144 switch (cmd) {
2145 case VIDIOC_QUERYCAP:
2146 str = "VIDIOC_QUERYCAP";
2147 break;
2148 case VIDIOC_RESERVED:
2149 str = "VIDIOC_RESERVED";
2150 break;
2151 case VIDIOC_ENUM_FMT:
2152 str = "VIDIOC_ENUM_FMT";
2153 break;
2154 case VIDIOC_G_FMT:
2155 str = "VIDIOC_G_FMT";
2156 break;
2157 case VIDIOC_S_FMT:
2158 str = "VIDIOC_S_FMT";
2159 break;
2160 /* 6 and 7 are VIDIOC_[SG]_COMP, which are unsupported */
2161 case VIDIOC_REQBUFS:
2162 str = "VIDIOC_REQBUFS";
2163 break;
2164 case VIDIOC_QUERYBUF:
2165 str = "VIDIOC_QUERYBUF";
2166 break;
2167 #ifndef _LP64
2168 case VIDIOC_QUERYBUF50:
2169 str = "VIDIOC_QUERYBUF50";
2170 break;
2171 #endif
2172 case VIDIOC_G_FBUF:
2173 str = "VIDIOC_G_FBUF";
2174 break;
2175 case VIDIOC_S_FBUF:
2176 str = "VIDIOC_S_FBUF";
2177 break;
2178 case VIDIOC_OVERLAY:
2179 str = "VIDIOC_OVERLAY";
2180 break;
2181 case VIDIOC_QBUF:
2182 str = "VIDIOC_QBUF";
2183 break;
2184 #ifndef _LP64
2185 case VIDIOC_QBUF50:
2186 str = "VIDIOC_QBUF50";
2187 break;
2188 #endif
2189 case VIDIOC_DQBUF:
2190 str = "VIDIOC_DQBUF";
2191 break;
2192 #ifndef _LP64
2193 case VIDIOC_DQBUF50:
2194 str = "VIDIOC_DQBUF50";
2195 break;
2196 #endif
2197 case VIDIOC_STREAMON:
2198 str = "VIDIOC_STREAMON";
2199 break;
2200 case VIDIOC_STREAMOFF:
2201 str = "VIDIOC_STREAMOFF";
2202 break;
2203 case VIDIOC_G_PARM:
2204 str = "VIDIOC_G_PARM";
2205 break;
2206 case VIDIOC_S_PARM:
2207 str = "VIDIOC_S_PARM";
2208 break;
2209 case VIDIOC_G_STD:
2210 str = "VIDIOC_G_STD";
2211 break;
2212 case VIDIOC_S_STD:
2213 str = "VIDIOC_S_STD";
2214 break;
2215 case VIDIOC_ENUMSTD:
2216 str = "VIDIOC_ENUMSTD";
2217 break;
2218 case VIDIOC_ENUMINPUT:
2219 str = "VIDIOC_ENUMINPUT";
2220 break;
2221 case VIDIOC_G_CTRL:
2222 str = "VIDIOC_G_CTRL";
2223 break;
2224 case VIDIOC_S_CTRL:
2225 str = "VIDIOC_S_CTRL";
2226 break;
2227 case VIDIOC_G_TUNER:
2228 str = "VIDIOC_G_TUNER";
2229 break;
2230 case VIDIOC_S_TUNER:
2231 str = "VIDIOC_S_TUNER";
2232 break;
2233 case VIDIOC_G_AUDIO:
2234 str = "VIDIOC_G_AUDIO";
2235 break;
2236 case VIDIOC_S_AUDIO:
2237 str = "VIDIOC_S_AUDIO";
2238 break;
2239 case VIDIOC_QUERYCTRL:
2240 str = "VIDIOC_QUERYCTRL";
2241 break;
2242 case VIDIOC_QUERYMENU:
2243 str = "VIDIOC_QUERYMENU";
2244 break;
2245 case VIDIOC_G_INPUT:
2246 str = "VIDIOC_G_INPUT";
2247 break;
2248 case VIDIOC_S_INPUT:
2249 str = "VIDIOC_S_INPUT";
2250 break;
2251 case VIDIOC_G_OUTPUT:
2252 str = "VIDIOC_G_OUTPUT";
2253 break;
2254 case VIDIOC_S_OUTPUT:
2255 str = "VIDIOC_S_OUTPUT";
2256 break;
2257 case VIDIOC_ENUMOUTPUT:
2258 str = "VIDIOC_ENUMOUTPUT";
2259 break;
2260 case VIDIOC_G_AUDOUT:
2261 str = "VIDIOC_G_AUDOUT";
2262 break;
2263 case VIDIOC_S_AUDOUT:
2264 str = "VIDIOC_S_AUDOUT";
2265 break;
2266 case VIDIOC_G_MODULATOR:
2267 str = "VIDIOC_G_MODULATOR";
2268 break;
2269 case VIDIOC_S_MODULATOR:
2270 str = "VIDIOC_S_MODULATOR";
2271 break;
2272 case VIDIOC_G_FREQUENCY:
2273 str = "VIDIOC_G_FREQUENCY";
2274 break;
2275 case VIDIOC_S_FREQUENCY:
2276 str = "VIDIOC_S_FREQUENCY";
2277 break;
2278 case VIDIOC_CROPCAP:
2279 str = "VIDIOC_CROPCAP";
2280 break;
2281 case VIDIOC_G_CROP:
2282 str = "VIDIOC_G_CROP";
2283 break;
2284 case VIDIOC_S_CROP:
2285 str = "VIDIOC_S_CROP";
2286 break;
2287 case VIDIOC_G_JPEGCOMP:
2288 str = "VIDIOC_G_JPEGCOMP";
2289 break;
2290 case VIDIOC_S_JPEGCOMP:
2291 str = "VIDIOC_S_JPEGCOMP";
2292 break;
2293 case VIDIOC_QUERYSTD:
2294 str = "VIDIOC_QUERYSTD";
2295 break;
2296 case VIDIOC_TRY_FMT:
2297 str = "VIDIOC_TRY_FMT";
2298 break;
2299 case VIDIOC_ENUMAUDIO:
2300 str = "VIDIOC_ENUMAUDIO";
2301 break;
2302 case VIDIOC_ENUMAUDOUT:
2303 str = "VIDIOC_ENUMAUDOUT";
2304 break;
2305 case VIDIOC_G_PRIORITY:
2306 str = "VIDIOC_G_PRIORITY";
2307 break;
2308 case VIDIOC_S_PRIORITY:
2309 str = "VIDIOC_S_PRIORITY";
2310 break;
2311 case VIDIOC_ENUM_FRAMESIZES:
2312 str = "VIDIOC_ENUM_FRAMESIZES";
2313 break;
2314 case VIDIOC_ENUM_FRAMEINTERVALS:
2315 str = "VIDIOC_FRAMEINTERVALS";
2316 break;
2317 default:
2318 str = "unknown";
2319 break;
2320 }
2321 return str;
2322 }
2323 #endif
2324
2325
2326 int
2327 videopoll(dev_t dev, int events, struct lwp *l)
2328 {
2329 struct video_softc *sc;
2330 struct video_stream *vs;
2331 int err, revents = 0;
2332
2333 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev)));
2334 vs = &sc->sc_stream_in;
2335
2336 if (sc->sc_dying)
2337 return (POLLHUP);
2338
2339 /* userspace has chosen read() method */
2340 if (vs->vs_method == VIDEO_STREAM_METHOD_NONE) {
2341 err = video_stream_setup_bufs(vs,
2342 VIDEO_STREAM_METHOD_READ,
2343 VIDEO_NUM_BUFS);
2344 if (err != 0)
2345 return POLLERR;
2346
2347 err = video_stream_on(sc, vs->vs_type);
2348 if (err != 0)
2349 return POLLERR;
2350 }
2351
2352 mutex_enter(&vs->vs_lock);
2353 if (!SIMPLEQ_EMPTY(&sc->sc_stream_in.vs_egress))
2354 revents |= events & (POLLIN | POLLRDNORM);
2355 else
2356 selrecord(l, &vs->vs_sel);
2357 mutex_exit(&vs->vs_lock);
2358
2359 return (revents);
2360 }
2361
2362
2363 paddr_t
2364 videommap(dev_t dev, off_t off, int prot)
2365 {
2366 struct video_softc *sc;
2367 struct video_stream *vs;
2368 /* paddr_t pa; */
2369
2370 sc = device_lookup_private(&video_cd, VIDEOUNIT(dev));
2371 if (sc->sc_dying)
2372 return -1;
2373
2374 vs = &sc->sc_stream_in;
2375
2376 return scatter_buf_map(&vs->vs_data, off);
2377 }
2378
2379
2380 /* Allocates buffers and initizlizes some fields. The format field
2381 * must already have been initialized. */
2382 void
2383 video_stream_init(struct video_stream *vs)
2384 {
2385 vs->vs_method = VIDEO_STREAM_METHOD_NONE;
2386 vs->vs_flags = 0;
2387 vs->vs_frameno = -1;
2388 vs->vs_sequence = 0;
2389 vs->vs_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2390 vs->vs_nbufs = 0;
2391 vs->vs_buf = NULL;
2392 vs->vs_streaming = false;
2393
2394 memset(&vs->vs_format, 0, sizeof(vs->vs_format));
2395
2396 SIMPLEQ_INIT(&vs->vs_ingress);
2397 SIMPLEQ_INIT(&vs->vs_egress);
2398
2399 mutex_init(&vs->vs_lock, MUTEX_DEFAULT, IPL_NONE);
2400 cv_init(&vs->vs_sample_cv, "video");
2401 selinit(&vs->vs_sel);
2402
2403 scatter_buf_init(&vs->vs_data);
2404 }
2405
2406 void
2407 video_stream_fini(struct video_stream *vs)
2408 {
2409 /* Sample data in queues has already been freed */
2410 /* while (SIMPLEQ_FIRST(&vs->vs_ingress) != NULL)
2411 SIMPLEQ_REMOVE_HEAD(&vs->vs_ingress, entries);
2412 while (SIMPLEQ_FIRST(&vs->vs_egress) != NULL)
2413 SIMPLEQ_REMOVE_HEAD(&vs->vs_egress, entries); */
2414
2415 mutex_destroy(&vs->vs_lock);
2416 cv_destroy(&vs->vs_sample_cv);
2417 seldestroy(&vs->vs_sel);
2418
2419 scatter_buf_destroy(&vs->vs_data);
2420 }
2421
2422 static int
2423 video_stream_setup_bufs(struct video_stream *vs,
2424 enum video_stream_method method,
2425 uint8_t nbufs)
2426 {
2427 int i, err;
2428
2429 mutex_enter(&vs->vs_lock);
2430
2431 /* Ensure that all allocated buffers are queued and not under
2432 * userspace control. */
2433 for (i = 0; i < vs->vs_nbufs; ++i) {
2434 if (!(vs->vs_buf[i]->vb_buf->flags & V4L2_BUF_FLAG_QUEUED)) {
2435 mutex_exit(&vs->vs_lock);
2436 return EBUSY;
2437 }
2438 }
2439
2440 /* Allocate the buffers */
2441 err = video_stream_realloc_bufs(vs, nbufs);
2442 if (err != 0) {
2443 mutex_exit(&vs->vs_lock);
2444 return err;
2445 }
2446
2447 /* Queue up buffers for read method. Other methods are queued
2448 * by VIDIOC_QBUF ioctl. */
2449 if (method == VIDEO_STREAM_METHOD_READ) {
2450 for (i = 0; i < nbufs; ++i)
2451 if (!(vs->vs_buf[i]->vb_buf->flags & V4L2_BUF_FLAG_QUEUED))
2452 video_stream_enqueue(vs, vs->vs_buf[i]);
2453 }
2454
2455 vs->vs_method = method;
2456 mutex_exit(&vs->vs_lock);
2457
2458 return 0;
2459 }
2460
2461 /* Free all buffer memory in preparation for close(). This should
2462 * free buffers regardless of errors. Use video_stream_setup_bufs if
2463 * you need to check for errors. Streaming should be off before
2464 * calling this function. */
2465 static void
2466 video_stream_teardown_bufs(struct video_stream *vs)
2467 {
2468 int err;
2469
2470 mutex_enter(&vs->vs_lock);
2471
2472 if (vs->vs_streaming) {
2473 DPRINTF(("video_stream_teardown_bufs: "
2474 "tearing down bufs while streaming\n"));
2475 }
2476
2477 /* dequeue all buffers */
2478 while (SIMPLEQ_FIRST(&vs->vs_ingress) != NULL)
2479 SIMPLEQ_REMOVE_HEAD(&vs->vs_ingress, entries);
2480 while (SIMPLEQ_FIRST(&vs->vs_egress) != NULL)
2481 SIMPLEQ_REMOVE_HEAD(&vs->vs_egress, entries);
2482
2483 err = video_stream_free_bufs(vs);
2484 if (err != 0) {
2485 DPRINTF(("video_stream_teardown_bufs: "
2486 "error releasing buffers: %d\n",
2487 err));
2488 }
2489 vs->vs_method = VIDEO_STREAM_METHOD_NONE;
2490
2491 mutex_exit(&vs->vs_lock);
2492 }
2493
2494 static struct video_buffer *
2495 video_buffer_alloc(void)
2496 {
2497 struct video_buffer *vb;
2498
2499 vb = kmem_alloc(sizeof(*vb), KM_SLEEP);
2500 vb->vb_buf = kmem_alloc(sizeof(*vb->vb_buf), KM_SLEEP);
2501 return vb;
2502 }
2503
2504 static void
2505 video_buffer_free(struct video_buffer *vb)
2506 {
2507 kmem_free(vb->vb_buf, sizeof(*vb->vb_buf));
2508 vb->vb_buf = NULL;
2509 kmem_free(vb, sizeof(*vb));
2510 }
2511
2512 /* TODO: for userptr method
2513 struct video_buffer *
2514 video_buf_alloc_with_ubuf(struct v4l2_buffer *buf)
2515 {
2516 }
2517
2518 void
2519 video_buffer_free_with_ubuf(struct video_buffer *vb)
2520 {
2521 }
2522 */
2523
2524 static int
2525 video_stream_realloc_bufs(struct video_stream *vs, uint8_t nbufs)
2526 {
2527 int i, err;
2528 uint8_t minnbufs, oldnbufs;
2529 size_t size;
2530 off_t offset;
2531 struct video_buffer **oldbuf;
2532 struct v4l2_buffer *buf;
2533
2534 size = PAGE_ALIGN(vs->vs_format.sample_size) * nbufs;
2535 err = scatter_buf_set_size(&vs->vs_data, size);
2536 if (err != 0)
2537 return err;
2538
2539 oldnbufs = vs->vs_nbufs;
2540 oldbuf = vs->vs_buf;
2541
2542 vs->vs_nbufs = nbufs;
2543 if (nbufs > 0) {
2544 vs->vs_buf =
2545 kmem_alloc(sizeof(struct video_buffer *) * nbufs, KM_SLEEP);
2546 } else {
2547 vs->vs_buf = NULL;
2548 }
2549
2550 minnbufs = uimin(vs->vs_nbufs, oldnbufs);
2551 /* copy any bufs that will be reused */
2552 for (i = 0; i < minnbufs; ++i)
2553 vs->vs_buf[i] = oldbuf[i];
2554 /* allocate any necessary new bufs */
2555 for (; i < vs->vs_nbufs; ++i)
2556 vs->vs_buf[i] = video_buffer_alloc();
2557 /* free any bufs no longer used */
2558 for (; i < oldnbufs; ++i) {
2559 video_buffer_free(oldbuf[i]);
2560 oldbuf[i] = NULL;
2561 }
2562
2563 /* Free old buffer metadata */
2564 if (oldbuf != NULL)
2565 kmem_free(oldbuf, sizeof(struct video_buffer *) * oldnbufs);
2566
2567 /* initialize bufs */
2568 offset = 0;
2569 for (i = 0; i < vs->vs_nbufs; ++i) {
2570 buf = vs->vs_buf[i]->vb_buf;
2571 buf->index = i;
2572 buf->type = vs->vs_type;
2573 buf->bytesused = 0;
2574 buf->flags = 0;
2575 buf->field = 0;
2576 buf->sequence = 0;
2577 buf->memory = V4L2_MEMORY_MMAP;
2578 buf->m.offset = offset;
2579 buf->length = PAGE_ALIGN(vs->vs_format.sample_size);
2580 buf->reserved2 = 0;
2581 buf->reserved = 0;
2582
2583 offset += buf->length;
2584 }
2585
2586 return 0;
2587 }
2588
2589 /* Accepts a video_sample into the ingress queue. Caller must hold
2590 * the stream lock. */
2591 void
2592 video_stream_enqueue(struct video_stream *vs, struct video_buffer *vb)
2593 {
2594 if (vb->vb_buf->flags & V4L2_BUF_FLAG_QUEUED) {
2595 DPRINTF(("video_stream_enqueue: sample already queued\n"));
2596 return;
2597 }
2598
2599 vb->vb_buf->flags |= V4L2_BUF_FLAG_QUEUED;
2600 vb->vb_buf->flags &= ~V4L2_BUF_FLAG_DONE;
2601
2602 vb->vb_buf->bytesused = 0;
2603
2604 SIMPLEQ_INSERT_TAIL(&vs->vs_ingress, vb, entries);
2605 }
2606
2607
2608 /* Removes the head of the egress queue for use by userspace. Caller
2609 * must hold the stream lock. */
2610 struct video_buffer *
2611 video_stream_dequeue(struct video_stream *vs)
2612 {
2613 struct video_buffer *vb;
2614
2615 if (!SIMPLEQ_EMPTY(&vs->vs_egress)) {
2616 vb = SIMPLEQ_FIRST(&vs->vs_egress);
2617 SIMPLEQ_REMOVE_HEAD(&vs->vs_egress, entries);
2618 vb->vb_buf->flags &= ~V4L2_BUF_FLAG_QUEUED;
2619 vb->vb_buf->flags |= V4L2_BUF_FLAG_DONE;
2620 return vb;
2621 } else {
2622 return NULL;
2623 }
2624 }
2625
2626 static void
2627 v4l2buf_set_timestamp(struct v4l2_buffer *buf)
2628 {
2629
2630 getmicrotime(&buf->timestamp);
2631 }
2632
2633 /*
2634 * write payload data to the appropriate video sample, possibly moving
2635 * the sample from ingress to egress queues
2636 */
2637 void
2638 video_stream_write(struct video_stream *vs,
2639 const struct video_payload *payload)
2640 {
2641 struct video_buffer *vb;
2642 struct v4l2_buffer *buf;
2643 struct scatter_io sio;
2644
2645 mutex_enter(&vs->vs_lock);
2646
2647 /* change of frameno implies end of current frame */
2648 if (vs->vs_frameno >= 0 && vs->vs_frameno != payload->frameno)
2649 video_stream_sample_done(vs);
2650
2651 vs->vs_frameno = payload->frameno;
2652
2653 if (vs->vs_drop || SIMPLEQ_EMPTY(&vs->vs_ingress)) {
2654 /* DPRINTF(("video_stream_write: dropping sample %d\n",
2655 vs->vs_sequence)); */
2656 vs->vs_drop = true;
2657 } else if (payload->size > 0) {
2658 vb = SIMPLEQ_FIRST(&vs->vs_ingress);
2659 buf = vb->vb_buf;
2660 if (!buf->bytesused)
2661 v4l2buf_set_timestamp(buf);
2662 if (payload->size > buf->length - buf->bytesused) {
2663 DPRINTF(("video_stream_write: "
2664 "payload would overflow\n"));
2665 } else if (scatter_io_init(&vs->vs_data,
2666 buf->m.offset + buf->bytesused,
2667 payload->size,
2668 &sio))
2669 {
2670 scatter_io_copyin(&sio, payload->data);
2671 buf->bytesused += (payload->size - sio.sio_resid);
2672 } else {
2673 DPRINTF(("video_stream_write: failed to init scatter io "
2674 "vb=%p buf=%p "
2675 "buf->m.offset=%d buf->bytesused=%u "
2676 "payload->size=%zu\n",
2677 vb, buf,
2678 buf->m.offset, buf->bytesused, payload->size));
2679 }
2680 }
2681
2682 /* if the payload marks it, we can do sample_done() early */
2683 if (payload->end_of_frame)
2684 video_stream_sample_done(vs);
2685
2686 mutex_exit(&vs->vs_lock);
2687 }
2688
2689
2690 /* Moves the head of the ingress queue to the tail of the egress
2691 * queue, or resets drop status if we were dropping this sample.
2692 * Caller should hold the stream queue lock. */
2693 void
2694 video_stream_sample_done(struct video_stream *vs)
2695 {
2696 struct video_buffer *vb;
2697
2698 if (vs->vs_drop) {
2699 vs->vs_drop = false;
2700 } else if (!SIMPLEQ_EMPTY(&vs->vs_ingress)) {
2701 vb = SIMPLEQ_FIRST(&vs->vs_ingress);
2702 vb->vb_buf->sequence = vs->vs_sequence;
2703 SIMPLEQ_REMOVE_HEAD(&vs->vs_ingress, entries);
2704
2705 SIMPLEQ_INSERT_TAIL(&vs->vs_egress, vb, entries);
2706 cv_signal(&vs->vs_sample_cv);
2707 selnotify(&vs->vs_sel, 0, 0);
2708 } else {
2709 DPRINTF(("video_stream_sample_done: no sample\n"));
2710 }
2711
2712 vs->vs_frameno ^= 1;
2713 vs->vs_sequence++;
2714 }
2715
2716 /* Check if all buffers are queued, i.e. none are under control of
2717 * userspace. */
2718 /*
2719 static bool
2720 video_stream_all_queued(struct video_stream *vs)
2721 {
2722 }
2723 */
2724
2725
2726 static void
2727 scatter_buf_init(struct scatter_buf *sb)
2728 {
2729 sb->sb_pool = pool_cache_init(PAGE_SIZE, 0, 0, 0,
2730 "video", NULL, IPL_VIDEO,
2731 NULL, NULL, NULL);
2732 sb->sb_size = 0;
2733 sb->sb_npages = 0;
2734 sb->sb_page_ary = NULL;
2735 }
2736
2737 static void
2738 scatter_buf_destroy(struct scatter_buf *sb)
2739 {
2740 /* Do we need to return everything to the pool first? */
2741 scatter_buf_set_size(sb, 0);
2742 pool_cache_destroy(sb->sb_pool);
2743 sb->sb_pool = 0;
2744 sb->sb_npages = 0;
2745 sb->sb_page_ary = NULL;
2746 }
2747
2748 /* Increase or decrease the size of the buffer */
2749 static int
2750 scatter_buf_set_size(struct scatter_buf *sb, size_t sz)
2751 {
2752 int i;
2753 size_t npages, minpages, oldnpages;
2754 uint8_t **old_ary;
2755
2756 npages = (sz >> PAGE_SHIFT) + ((sz & PAGE_MASK) > 0);
2757
2758 if (sb->sb_npages == npages) {
2759 return 0;
2760 }
2761
2762 oldnpages = sb->sb_npages;
2763 old_ary = sb->sb_page_ary;
2764
2765 sb->sb_npages = npages;
2766 if (npages > 0) {
2767 sb->sb_page_ary =
2768 kmem_alloc(sizeof(uint8_t *) * npages, KM_SLEEP);
2769 } else {
2770 sb->sb_page_ary = NULL;
2771 }
2772
2773 minpages = uimin(npages, oldnpages);
2774 /* copy any pages that will be reused */
2775 for (i = 0; i < minpages; ++i)
2776 sb->sb_page_ary[i] = old_ary[i];
2777 /* allocate any new pages */
2778 for (; i < npages; ++i)
2779 sb->sb_page_ary[i] = pool_cache_get(sb->sb_pool, PR_WAITOK);
2780 /* return any pages no longer needed */
2781 for (; i < oldnpages; ++i)
2782 pool_cache_put(sb->sb_pool, old_ary[i]);
2783
2784 if (old_ary != NULL)
2785 kmem_free(old_ary, sizeof(uint8_t *) * oldnpages);
2786
2787 sb->sb_size = sb->sb_npages << PAGE_SHIFT;
2788
2789 return 0;
2790 }
2791
2792
2793 static paddr_t
2794 scatter_buf_map(struct scatter_buf *sb, off_t off)
2795 {
2796 size_t pg;
2797 paddr_t pa;
2798
2799 pg = off >> PAGE_SHIFT;
2800
2801 if (pg >= sb->sb_npages)
2802 return -1;
2803 else if (!pmap_extract(pmap_kernel(), (vaddr_t)sb->sb_page_ary[pg], &pa))
2804 return -1;
2805
2806 return atop(pa);
2807 }
2808
2809 /* Initialize data for an io operation on a scatter buffer. Returns
2810 * true if the transfer is valid, or false if out of range. */
2811 static bool
2812 scatter_io_init(struct scatter_buf *sb,
2813 off_t off, size_t len,
2814 struct scatter_io *sio)
2815 {
2816 if ((off + len) > sb->sb_size) {
2817 DPRINTF(("video: scatter_io_init failed: off=%" PRId64
2818 " len=%zu sb->sb_size=%zu\n",
2819 off, len, sb->sb_size));
2820 return false;
2821 }
2822
2823 sio->sio_buf = sb;
2824 sio->sio_offset = off;
2825 sio->sio_resid = len;
2826
2827 return true;
2828 }
2829
2830 /* Store the pointer and size of the next contiguous segment. Returns
2831 * true if the segment is valid, or false if all has been transferred.
2832 * Does not check for overflow. */
2833 static bool
2834 scatter_io_next(struct scatter_io *sio, void **p, size_t *sz)
2835 {
2836 size_t pg, pgo;
2837
2838 if (sio->sio_resid == 0)
2839 return false;
2840
2841 pg = sio->sio_offset >> PAGE_SHIFT;
2842 pgo = sio->sio_offset & PAGE_MASK;
2843
2844 *sz = uimin(PAGE_SIZE - pgo, sio->sio_resid);
2845 *p = sio->sio_buf->sb_page_ary[pg] + pgo;
2846
2847 sio->sio_offset += *sz;
2848 sio->sio_resid -= *sz;
2849
2850 return true;
2851 }
2852
2853 /* Semi-undo of a failed segment copy. Updates the scatter_io
2854 * struct to the previous values prior to a failed segment copy. */
2855 static void
2856 scatter_io_undo(struct scatter_io *sio, size_t sz)
2857 {
2858 sio->sio_offset -= sz;
2859 sio->sio_resid += sz;
2860 }
2861
2862 /* Copy data from src into the scatter_buf as described by io. */
2863 static void
2864 scatter_io_copyin(struct scatter_io *sio, const void *p)
2865 {
2866 void *dst;
2867 const uint8_t *src = p;
2868 size_t sz;
2869
2870 while(scatter_io_next(sio, &dst, &sz)) {
2871 memcpy(dst, src, sz);
2872 src += sz;
2873 }
2874 }
2875
2876 /* --not used; commented to avoid compiler warnings--
2877 static void
2878 scatter_io_copyout(struct scatter_io *sio, void *p)
2879 {
2880 void *src;
2881 uint8_t *dst = p;
2882 size_t sz;
2883
2884 while(scatter_io_next(sio, &src, &sz)) {
2885 memcpy(dst, src, sz);
2886 dst += sz;
2887 }
2888 }
2889 */
2890
2891 /* Performat a series of uiomove calls on a scatter buf. Returns
2892 * EFAULT if uiomove EFAULTs on the first segment. Otherwise, returns
2893 * an incomplete transfer but with no error. */
2894 static int
2895 scatter_io_uiomove(struct scatter_io *sio, struct uio *uio)
2896 {
2897 void *p;
2898 size_t sz;
2899 bool first = true;
2900 int err;
2901
2902 while(scatter_io_next(sio, &p, &sz)) {
2903 err = uiomove(p, sz, uio);
2904 if (err == EFAULT) {
2905 scatter_io_undo(sio, sz);
2906 if (first)
2907 return EFAULT;
2908 else
2909 return 0;
2910 }
2911 first = false;
2912 }
2913
2914 return 0;
2915 }
2916
2917 #endif /* NVIDEO > 0 */
2918