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