.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Zoran 364xx based USB webcam module version 0.73 |
---|
3 | 4 | * |
---|
4 | 5 | * Allows you to use your USB webcam with V4L2 applications |
---|
5 | | - * This is still in heavy developpement ! |
---|
| 6 | + * This is still in heavy development ! |
---|
6 | 7 | * |
---|
7 | 8 | * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com> |
---|
8 | 9 | * http://royale.zerezo.com/zr364xx/ |
---|
.. | .. |
---|
11 | 12 | * V4L2 version inspired by meye.c driver |
---|
12 | 13 | * |
---|
13 | 14 | * Some video buffer code by Lamarque based on s2255drv.c and vivi.c drivers. |
---|
14 | | - * |
---|
15 | | - * This program is free software; you can redistribute it and/or modify |
---|
16 | | - * it under the terms of the GNU General Public License as published by |
---|
17 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
18 | | - * (at your option) any later version. |
---|
19 | | - * |
---|
20 | | - * This program is distributed in the hope that it will be useful, |
---|
21 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
22 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
23 | | - * GNU General Public License for more details. |
---|
24 | 15 | */ |
---|
25 | 16 | |
---|
26 | 17 | |
---|
.. | .. |
---|
29 | 20 | #include <linux/usb.h> |
---|
30 | 21 | #include <linux/vmalloc.h> |
---|
31 | 22 | #include <linux/slab.h> |
---|
32 | | -#include <linux/proc_fs.h> |
---|
33 | 23 | #include <linux/highmem.h> |
---|
34 | 24 | #include <media/v4l2-common.h> |
---|
35 | 25 | #include <media/v4l2-ioctl.h> |
---|
.. | .. |
---|
150 | 140 | }; |
---|
151 | 141 | |
---|
152 | 142 | struct zr364xx_fmt { |
---|
153 | | - char *name; |
---|
154 | 143 | u32 fourcc; |
---|
155 | 144 | int depth; |
---|
156 | 145 | }; |
---|
.. | .. |
---|
158 | 147 | /* image formats. */ |
---|
159 | 148 | static const struct zr364xx_fmt formats[] = { |
---|
160 | 149 | { |
---|
161 | | - .name = "JPG", |
---|
162 | 150 | .fourcc = V4L2_PIX_FMT_JPEG, |
---|
163 | 151 | .depth = 24 |
---|
164 | 152 | } |
---|
.. | .. |
---|
208 | 196 | { |
---|
209 | 197 | int status; |
---|
210 | 198 | |
---|
211 | | - unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); |
---|
| 199 | + unsigned char *transfer_buffer = kmemdup(cp, size, GFP_KERNEL); |
---|
212 | 200 | if (!transfer_buffer) |
---|
213 | 201 | return -ENOMEM; |
---|
214 | | - |
---|
215 | | - memcpy(transfer_buffer, cp, size); |
---|
216 | 202 | |
---|
217 | 203 | status = usb_control_msg(udev, |
---|
218 | 204 | usb_sndctrlpipe(udev, 0), |
---|
.. | .. |
---|
385 | 371 | vb); |
---|
386 | 372 | int rc; |
---|
387 | 373 | |
---|
388 | | - DBG("%s, field=%d, fmt name = %s\n", __func__, field, |
---|
389 | | - cam->fmt ? cam->fmt->name : ""); |
---|
| 374 | + DBG("%s, field=%d\n", __func__, field); |
---|
390 | 375 | if (!cam->fmt) |
---|
391 | 376 | return -EINVAL; |
---|
392 | 377 | |
---|
.. | .. |
---|
521 | 506 | /* tell v4l buffer was filled */ |
---|
522 | 507 | |
---|
523 | 508 | buf->vb.field_count = cam->frame_count * 2; |
---|
524 | | - v4l2_get_timestamp(&buf->vb.ts); |
---|
| 509 | + buf->vb.ts = ktime_get_ns(); |
---|
525 | 510 | buf->vb.state = VIDEOBUF_DONE; |
---|
526 | 511 | } |
---|
527 | 512 | |
---|
.. | .. |
---|
549 | 534 | goto unlock; |
---|
550 | 535 | } |
---|
551 | 536 | list_del(&buf->vb.queue); |
---|
552 | | - v4l2_get_timestamp(&buf->vb.ts); |
---|
| 537 | + buf->vb.ts = ktime_get_ns(); |
---|
553 | 538 | DBG("[%p/%d] wakeup\n", buf, buf->vb.i); |
---|
554 | 539 | zr364xx_fillbuff(cam, buf, jpgsize); |
---|
555 | 540 | wake_up(&buf->vb.done); |
---|
.. | .. |
---|
570 | 555 | { |
---|
571 | 556 | unsigned char *pdest; |
---|
572 | 557 | unsigned char *psrc; |
---|
573 | | - s32 idx = -1; |
---|
574 | | - struct zr364xx_framei *frm; |
---|
| 558 | + s32 idx = cam->cur_frame; |
---|
| 559 | + struct zr364xx_framei *frm = &cam->buffer.frame[idx]; |
---|
575 | 560 | int i = 0; |
---|
576 | 561 | unsigned char *ptr = NULL; |
---|
577 | 562 | |
---|
578 | 563 | _DBG("buffer to user\n"); |
---|
579 | | - idx = cam->cur_frame; |
---|
580 | | - frm = &cam->buffer.frame[idx]; |
---|
581 | 564 | |
---|
582 | 565 | /* swap bytes if camera needs it */ |
---|
583 | 566 | if (cam->method == METHOD0) { |
---|
.. | .. |
---|
702 | 685 | { |
---|
703 | 686 | struct zr364xx_camera *cam = video_drvdata(file); |
---|
704 | 687 | |
---|
705 | | - strlcpy(cap->driver, DRIVER_DESC, sizeof(cap->driver)); |
---|
| 688 | + strscpy(cap->driver, DRIVER_DESC, sizeof(cap->driver)); |
---|
706 | 689 | if (cam->udev->product) |
---|
707 | | - strlcpy(cap->card, cam->udev->product, sizeof(cap->card)); |
---|
708 | | - strlcpy(cap->bus_info, dev_name(&cam->udev->dev), |
---|
| 690 | + strscpy(cap->card, cam->udev->product, sizeof(cap->card)); |
---|
| 691 | + strscpy(cap->bus_info, dev_name(&cam->udev->dev), |
---|
709 | 692 | sizeof(cap->bus_info)); |
---|
710 | | - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | |
---|
711 | | - V4L2_CAP_READWRITE | |
---|
712 | | - V4L2_CAP_STREAMING; |
---|
713 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
---|
714 | | - |
---|
715 | 693 | return 0; |
---|
716 | 694 | } |
---|
717 | 695 | |
---|
.. | .. |
---|
720 | 698 | { |
---|
721 | 699 | if (i->index != 0) |
---|
722 | 700 | return -EINVAL; |
---|
723 | | - strcpy(i->name, DRIVER_DESC " Camera"); |
---|
| 701 | + strscpy(i->name, DRIVER_DESC " Camera", sizeof(i->name)); |
---|
724 | 702 | i->type = V4L2_INPUT_TYPE_CAMERA; |
---|
725 | 703 | return 0; |
---|
726 | 704 | } |
---|
.. | .. |
---|
765 | 743 | { |
---|
766 | 744 | if (f->index > 0) |
---|
767 | 745 | return -EINVAL; |
---|
768 | | - f->flags = V4L2_FMT_FLAG_COMPRESSED; |
---|
769 | | - strcpy(f->description, formats[0].name); |
---|
770 | 746 | f->pixelformat = formats[0].fourcc; |
---|
771 | 747 | return 0; |
---|
772 | 748 | } |
---|
.. | .. |
---|
1208 | 1184 | return err; |
---|
1209 | 1185 | } |
---|
1210 | 1186 | |
---|
1211 | | -static void zr364xx_release(struct v4l2_device *v4l2_dev) |
---|
| 1187 | +static void zr364xx_board_uninit(struct zr364xx_camera *cam) |
---|
1212 | 1188 | { |
---|
1213 | | - struct zr364xx_camera *cam = |
---|
1214 | | - container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); |
---|
1215 | 1189 | unsigned long i; |
---|
1216 | 1190 | |
---|
1217 | | - v4l2_device_unregister(&cam->v4l2_dev); |
---|
1218 | | - |
---|
1219 | | - videobuf_mmap_free(&cam->vb_vidq); |
---|
| 1191 | + zr364xx_stop_readpipe(cam); |
---|
1220 | 1192 | |
---|
1221 | 1193 | /* release sys buffers */ |
---|
1222 | 1194 | for (i = 0; i < FRAMES; i++) { |
---|
.. | .. |
---|
1227 | 1199 | cam->buffer.frame[i].lpvbits = NULL; |
---|
1228 | 1200 | } |
---|
1229 | 1201 | |
---|
1230 | | - v4l2_ctrl_handler_free(&cam->ctrl_handler); |
---|
1231 | 1202 | /* release transfer buffer */ |
---|
1232 | 1203 | kfree(cam->pipe->transfer_buffer); |
---|
| 1204 | +} |
---|
| 1205 | + |
---|
| 1206 | +static void zr364xx_release(struct v4l2_device *v4l2_dev) |
---|
| 1207 | +{ |
---|
| 1208 | + struct zr364xx_camera *cam = |
---|
| 1209 | + container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); |
---|
| 1210 | + |
---|
| 1211 | + videobuf_mmap_free(&cam->vb_vidq); |
---|
| 1212 | + v4l2_ctrl_handler_free(&cam->ctrl_handler); |
---|
| 1213 | + zr364xx_board_uninit(cam); |
---|
| 1214 | + v4l2_device_unregister(&cam->v4l2_dev); |
---|
1233 | 1215 | kfree(cam); |
---|
1234 | 1216 | } |
---|
1235 | 1217 | |
---|
.. | .. |
---|
1339 | 1321 | .fops = &zr364xx_fops, |
---|
1340 | 1322 | .ioctl_ops = &zr364xx_ioctl_ops, |
---|
1341 | 1323 | .release = video_device_release_empty, |
---|
| 1324 | + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | |
---|
| 1325 | + V4L2_CAP_STREAMING, |
---|
1342 | 1326 | }; |
---|
1343 | 1327 | |
---|
1344 | 1328 | |
---|
.. | .. |
---|
1350 | 1334 | { |
---|
1351 | 1335 | struct zr364xx_pipeinfo *pipe = cam->pipe; |
---|
1352 | 1336 | unsigned long i; |
---|
| 1337 | + int err; |
---|
1353 | 1338 | |
---|
1354 | 1339 | DBG("board init: %p\n", cam); |
---|
1355 | 1340 | memset(pipe, 0, sizeof(*pipe)); |
---|
.. | .. |
---|
1382 | 1367 | |
---|
1383 | 1368 | if (i == 0) { |
---|
1384 | 1369 | printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n"); |
---|
1385 | | - kfree(cam->pipe->transfer_buffer); |
---|
1386 | | - cam->pipe->transfer_buffer = NULL; |
---|
1387 | | - return -ENOMEM; |
---|
| 1370 | + err = -ENOMEM; |
---|
| 1371 | + goto err_free; |
---|
1388 | 1372 | } else |
---|
1389 | 1373 | cam->buffer.dwFrames = i; |
---|
1390 | 1374 | |
---|
.. | .. |
---|
1399 | 1383 | /*** end create system buffers ***/ |
---|
1400 | 1384 | |
---|
1401 | 1385 | /* start read pipe */ |
---|
1402 | | - zr364xx_start_readpipe(cam); |
---|
| 1386 | + err = zr364xx_start_readpipe(cam); |
---|
| 1387 | + if (err) |
---|
| 1388 | + goto err_free_frames; |
---|
| 1389 | + |
---|
1403 | 1390 | DBG(": board initialized\n"); |
---|
1404 | 1391 | return 0; |
---|
| 1392 | + |
---|
| 1393 | +err_free_frames: |
---|
| 1394 | + for (i = 0; i < FRAMES; i++) |
---|
| 1395 | + vfree(cam->buffer.frame[i].lpvbits); |
---|
| 1396 | +err_free: |
---|
| 1397 | + kfree(cam->pipe->transfer_buffer); |
---|
| 1398 | + cam->pipe->transfer_buffer = NULL; |
---|
| 1399 | + return err; |
---|
1405 | 1400 | } |
---|
1406 | 1401 | |
---|
1407 | 1402 | static int zr364xx_probe(struct usb_interface *intf, |
---|
.. | .. |
---|
1426 | 1421 | if (!cam) |
---|
1427 | 1422 | return -ENOMEM; |
---|
1428 | 1423 | |
---|
1429 | | - cam->v4l2_dev.release = zr364xx_release; |
---|
1430 | 1424 | err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); |
---|
1431 | 1425 | if (err < 0) { |
---|
1432 | 1426 | dev_err(&udev->dev, "couldn't register v4l2_device\n"); |
---|
1433 | | - kfree(cam); |
---|
1434 | | - return err; |
---|
| 1427 | + goto free_cam; |
---|
1435 | 1428 | } |
---|
1436 | 1429 | hdl = &cam->ctrl_handler; |
---|
1437 | 1430 | v4l2_ctrl_handler_init(hdl, 1); |
---|
.. | .. |
---|
1440 | 1433 | if (hdl->error) { |
---|
1441 | 1434 | err = hdl->error; |
---|
1442 | 1435 | dev_err(&udev->dev, "couldn't register control\n"); |
---|
1443 | | - goto fail; |
---|
| 1436 | + goto free_hdlr_and_unreg_dev; |
---|
1444 | 1437 | } |
---|
1445 | 1438 | /* save the init method used by this camera */ |
---|
1446 | 1439 | cam->method = id->driver_info; |
---|
.. | .. |
---|
1513 | 1506 | if (!cam->read_endpoint) { |
---|
1514 | 1507 | err = -ENOMEM; |
---|
1515 | 1508 | dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); |
---|
1516 | | - goto fail; |
---|
| 1509 | + goto free_hdlr_and_unreg_dev; |
---|
1517 | 1510 | } |
---|
1518 | 1511 | |
---|
1519 | 1512 | /* v4l */ |
---|
.. | .. |
---|
1524 | 1517 | |
---|
1525 | 1518 | /* load zr364xx board specific */ |
---|
1526 | 1519 | err = zr364xx_board_init(cam); |
---|
1527 | | - if (!err) |
---|
1528 | | - err = v4l2_ctrl_handler_setup(hdl); |
---|
1529 | 1520 | if (err) |
---|
1530 | | - goto fail; |
---|
| 1521 | + goto free_hdlr_and_unreg_dev; |
---|
| 1522 | + err = v4l2_ctrl_handler_setup(hdl); |
---|
| 1523 | + if (err) |
---|
| 1524 | + goto board_uninit; |
---|
1531 | 1525 | |
---|
1532 | 1526 | spin_lock_init(&cam->slock); |
---|
1533 | 1527 | |
---|
.. | .. |
---|
1539 | 1533 | V4L2_FIELD_NONE, |
---|
1540 | 1534 | sizeof(struct zr364xx_buffer), cam, &cam->lock); |
---|
1541 | 1535 | |
---|
1542 | | - err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); |
---|
| 1536 | + err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1); |
---|
1543 | 1537 | if (err) { |
---|
1544 | 1538 | dev_err(&udev->dev, "video_register_device failed\n"); |
---|
1545 | | - goto fail; |
---|
| 1539 | + goto board_uninit; |
---|
1546 | 1540 | } |
---|
| 1541 | + cam->v4l2_dev.release = zr364xx_release; |
---|
1547 | 1542 | |
---|
1548 | 1543 | dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", |
---|
1549 | 1544 | video_device_node_name(&cam->vdev)); |
---|
1550 | 1545 | return 0; |
---|
1551 | 1546 | |
---|
1552 | | -fail: |
---|
| 1547 | +board_uninit: |
---|
| 1548 | + zr364xx_board_uninit(cam); |
---|
| 1549 | +free_hdlr_and_unreg_dev: |
---|
1553 | 1550 | v4l2_ctrl_handler_free(hdl); |
---|
1554 | 1551 | v4l2_device_unregister(&cam->v4l2_dev); |
---|
| 1552 | +free_cam: |
---|
1555 | 1553 | kfree(cam); |
---|
1556 | 1554 | return err; |
---|
1557 | 1555 | } |
---|
.. | .. |
---|
1598 | 1596 | if (!cam->was_streaming) |
---|
1599 | 1597 | return 0; |
---|
1600 | 1598 | |
---|
1601 | | - zr364xx_start_readpipe(cam); |
---|
| 1599 | + res = zr364xx_start_readpipe(cam); |
---|
| 1600 | + if (res) |
---|
| 1601 | + return res; |
---|
| 1602 | + |
---|
1602 | 1603 | res = zr364xx_prepare(cam); |
---|
1603 | | - if (!res) |
---|
1604 | | - zr364xx_start_acquire(cam); |
---|
| 1604 | + if (res) |
---|
| 1605 | + goto err_prepare; |
---|
| 1606 | + |
---|
| 1607 | + zr364xx_start_acquire(cam); |
---|
| 1608 | + return 0; |
---|
| 1609 | + |
---|
| 1610 | +err_prepare: |
---|
| 1611 | + zr364xx_stop_readpipe(cam); |
---|
1605 | 1612 | return res; |
---|
1606 | 1613 | } |
---|
1607 | 1614 | #endif |
---|