1 /* $NetBSD: video.c,v 1.39 2020/08/13 16:45:58 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org> 5 * All rights reserved. 6 * 7 * This code was written by Patrick Mahoney (pat@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