.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /**************************************************************************** |
---|
2 | 3 | * |
---|
3 | 4 | * Filename: cpia2_v4l.c |
---|
.. | .. |
---|
10 | 11 | * This is a USB driver for CPia2 based video cameras. |
---|
11 | 12 | * The infrastructure of this driver is based on the cpia usb driver by |
---|
12 | 13 | * Jochen Scharrlach and Johannes Erdfeldt. |
---|
13 | | - * |
---|
14 | | - * This program is free software; you can redistribute it and/or modify |
---|
15 | | - * it under the terms of the GNU General Public License as published by |
---|
16 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
17 | | - * (at your option) any later version. |
---|
18 | | - * |
---|
19 | | - * This program is distributed in the hope that it will be useful, |
---|
20 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
21 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
22 | | - * GNU General Public License for more details. |
---|
23 | 14 | * |
---|
24 | 15 | * Stripped of 2.4 stuff ready for main kernel submit by |
---|
25 | 16 | * Alan Cox <alan@lxorguk.ukuu.org.uk> |
---|
.. | .. |
---|
219 | 210 | { |
---|
220 | 211 | struct camera_data *cam = video_drvdata(file); |
---|
221 | 212 | |
---|
222 | | - strcpy(vc->driver, "cpia2"); |
---|
| 213 | + strscpy(vc->driver, "cpia2", sizeof(vc->driver)); |
---|
223 | 214 | |
---|
224 | 215 | if (cam->params.pnp_id.product == 0x151) |
---|
225 | | - strcpy(vc->card, "QX5 Microscope"); |
---|
| 216 | + strscpy(vc->card, "QX5 Microscope", sizeof(vc->card)); |
---|
226 | 217 | else |
---|
227 | | - strcpy(vc->card, "CPiA2 Camera"); |
---|
| 218 | + strscpy(vc->card, "CPiA2 Camera", sizeof(vc->card)); |
---|
228 | 219 | switch (cam->params.pnp_id.device_type) { |
---|
229 | 220 | case DEVICE_STV_672: |
---|
230 | 221 | strcat(vc->card, " (672/"); |
---|
.. | .. |
---|
259 | 250 | |
---|
260 | 251 | if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) |
---|
261 | 252 | memset(vc->bus_info,0, sizeof(vc->bus_info)); |
---|
262 | | - |
---|
263 | | - vc->device_caps = V4L2_CAP_VIDEO_CAPTURE | |
---|
264 | | - V4L2_CAP_READWRITE | |
---|
265 | | - V4L2_CAP_STREAMING; |
---|
266 | | - vc->capabilities = vc->device_caps | |
---|
267 | | - V4L2_CAP_DEVICE_CAPS; |
---|
268 | | - |
---|
269 | 253 | return 0; |
---|
270 | 254 | } |
---|
271 | 255 | |
---|
.. | .. |
---|
281 | 265 | { |
---|
282 | 266 | if (i->index) |
---|
283 | 267 | return -EINVAL; |
---|
284 | | - strcpy(i->name, "Camera"); |
---|
| 268 | + strscpy(i->name, "Camera", sizeof(i->name)); |
---|
285 | 269 | i->type = V4L2_INPUT_TYPE_CAMERA; |
---|
286 | 270 | return 0; |
---|
287 | 271 | } |
---|
.. | .. |
---|
308 | 292 | static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh, |
---|
309 | 293 | struct v4l2_fmtdesc *f) |
---|
310 | 294 | { |
---|
311 | | - int index = f->index; |
---|
312 | | - |
---|
313 | | - if (index < 0 || index > 1) |
---|
314 | | - return -EINVAL; |
---|
315 | | - |
---|
316 | | - memset(f, 0, sizeof(*f)); |
---|
317 | | - f->index = index; |
---|
318 | | - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
---|
319 | | - f->flags = V4L2_FMT_FLAG_COMPRESSED; |
---|
320 | | - switch(index) { |
---|
321 | | - case 0: |
---|
322 | | - strcpy(f->description, "MJPEG"); |
---|
323 | | - f->pixelformat = V4L2_PIX_FMT_MJPEG; |
---|
324 | | - break; |
---|
325 | | - case 1: |
---|
326 | | - strcpy(f->description, "JPEG"); |
---|
327 | | - f->pixelformat = V4L2_PIX_FMT_JPEG; |
---|
328 | | - break; |
---|
329 | | - default: |
---|
| 295 | + if (f->index > 1) |
---|
330 | 296 | return -EINVAL; |
---|
331 | | - } |
---|
332 | 297 | |
---|
| 298 | + if (f->index == 0) |
---|
| 299 | + f->pixelformat = V4L2_PIX_FMT_MJPEG; |
---|
| 300 | + else |
---|
| 301 | + f->pixelformat = V4L2_PIX_FMT_JPEG; |
---|
333 | 302 | return 0; |
---|
334 | 303 | } |
---|
335 | 304 | |
---|
.. | .. |
---|
354 | 323 | f->fmt.pix.bytesperline = 0; |
---|
355 | 324 | f->fmt.pix.sizeimage = cam->frame_size; |
---|
356 | 325 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; |
---|
357 | | - f->fmt.pix.priv = 0; |
---|
358 | 326 | |
---|
359 | 327 | switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) { |
---|
360 | 328 | case VIDEOSIZE_VGA: |
---|
.. | .. |
---|
465 | 433 | f->fmt.pix.bytesperline = 0; |
---|
466 | 434 | f->fmt.pix.sizeimage = cam->frame_size; |
---|
467 | 435 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; |
---|
468 | | - f->fmt.pix.priv = 0; |
---|
469 | 436 | |
---|
470 | 437 | return 0; |
---|
471 | 438 | } |
---|
.. | .. |
---|
479 | 446 | * |
---|
480 | 447 | *****************************************************************************/ |
---|
481 | 448 | |
---|
482 | | -static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c) |
---|
| 449 | +static int cpia2_g_selection(struct file *file, void *fh, |
---|
| 450 | + struct v4l2_selection *s) |
---|
483 | 451 | { |
---|
484 | 452 | struct camera_data *cam = video_drvdata(file); |
---|
485 | 453 | |
---|
486 | | - if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
---|
487 | | - return -EINVAL; |
---|
| 454 | + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
---|
| 455 | + return -EINVAL; |
---|
488 | 456 | |
---|
489 | | - c->bounds.left = 0; |
---|
490 | | - c->bounds.top = 0; |
---|
491 | | - c->bounds.width = cam->width; |
---|
492 | | - c->bounds.height = cam->height; |
---|
493 | | - c->defrect.left = 0; |
---|
494 | | - c->defrect.top = 0; |
---|
495 | | - c->defrect.width = cam->width; |
---|
496 | | - c->defrect.height = cam->height; |
---|
497 | | - c->pixelaspect.numerator = 1; |
---|
498 | | - c->pixelaspect.denominator = 1; |
---|
499 | | - |
---|
| 457 | + switch (s->target) { |
---|
| 458 | + case V4L2_SEL_TGT_CROP_BOUNDS: |
---|
| 459 | + case V4L2_SEL_TGT_CROP_DEFAULT: |
---|
| 460 | + s->r.left = 0; |
---|
| 461 | + s->r.top = 0; |
---|
| 462 | + s->r.width = cam->width; |
---|
| 463 | + s->r.height = cam->height; |
---|
| 464 | + break; |
---|
| 465 | + default: |
---|
| 466 | + return -EINVAL; |
---|
| 467 | + } |
---|
500 | 468 | return 0; |
---|
501 | 469 | } |
---|
502 | 470 | |
---|
.. | .. |
---|
832 | 800 | break; |
---|
833 | 801 | case FRAME_READY: |
---|
834 | 802 | buf->bytesused = cam->buffers[buf->index].length; |
---|
835 | | - buf->timestamp = cam->buffers[buf->index].timestamp; |
---|
| 803 | + v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts); |
---|
836 | 804 | buf->sequence = cam->buffers[buf->index].seq; |
---|
837 | 805 | buf->flags = V4L2_BUF_FLAG_DONE; |
---|
838 | 806 | break; |
---|
.. | .. |
---|
888 | 856 | found = i; |
---|
889 | 857 | } else { |
---|
890 | 858 | /* find which buffer is earlier */ |
---|
891 | | - struct timeval *tv1, *tv2; |
---|
892 | | - tv1 = &cam->buffers[i].timestamp; |
---|
893 | | - tv2 = &cam->buffers[found].timestamp; |
---|
894 | | - if(tv1->tv_sec < tv2->tv_sec || |
---|
895 | | - (tv1->tv_sec == tv2->tv_sec && |
---|
896 | | - tv1->tv_usec < tv2->tv_usec)) |
---|
| 859 | + if (cam->buffers[i].ts < cam->buffers[found].ts) |
---|
897 | 860 | found = i; |
---|
898 | 861 | } |
---|
899 | 862 | } |
---|
.. | .. |
---|
944 | 907 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE |
---|
945 | 908 | | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
---|
946 | 909 | buf->field = V4L2_FIELD_NONE; |
---|
947 | | - buf->timestamp = cam->buffers[buf->index].timestamp; |
---|
| 910 | + v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts); |
---|
948 | 911 | buf->sequence = cam->buffers[buf->index].seq; |
---|
949 | 912 | buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; |
---|
950 | 913 | buf->length = cam->frame_size; |
---|
951 | 914 | buf->reserved2 = 0; |
---|
952 | | - buf->reserved = 0; |
---|
| 915 | + buf->request_fd = 0; |
---|
953 | 916 | memset(&buf->timecode, 0, sizeof(buf->timecode)); |
---|
954 | 917 | |
---|
955 | 918 | DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index, |
---|
.. | .. |
---|
1047 | 1010 | .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap, |
---|
1048 | 1011 | .vidioc_g_jpegcomp = cpia2_g_jpegcomp, |
---|
1049 | 1012 | .vidioc_s_jpegcomp = cpia2_s_jpegcomp, |
---|
1050 | | - .vidioc_cropcap = cpia2_cropcap, |
---|
| 1013 | + .vidioc_g_selection = cpia2_g_selection, |
---|
1051 | 1014 | .vidioc_reqbufs = cpia2_reqbufs, |
---|
1052 | 1015 | .vidioc_querybuf = cpia2_querybuf, |
---|
1053 | 1016 | .vidioc_qbuf = cpia2_qbuf, |
---|
.. | .. |
---|
1165 | 1128 | cam->vdev.lock = &cam->v4l2_lock; |
---|
1166 | 1129 | cam->vdev.ctrl_handler = hdl; |
---|
1167 | 1130 | cam->vdev.v4l2_dev = &cam->v4l2_dev; |
---|
| 1131 | + cam->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | |
---|
| 1132 | + V4L2_CAP_STREAMING; |
---|
1168 | 1133 | |
---|
1169 | 1134 | reset_camera_struct_v4l(cam); |
---|
1170 | 1135 | |
---|
1171 | 1136 | /* register v4l device */ |
---|
1172 | | - if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { |
---|
| 1137 | + if (video_register_device(&cam->vdev, VFL_TYPE_VIDEO, video_nr) < 0) { |
---|
1173 | 1138 | ERR("video_register_device failed\n"); |
---|
1174 | 1139 | return -ENODEV; |
---|
1175 | 1140 | } |
---|