.. | .. |
---|
18 | 18 | #include "camss-video.h" |
---|
19 | 19 | #include "camss.h" |
---|
20 | 20 | |
---|
| 21 | +#define CAMSS_FRAME_MIN_WIDTH 1 |
---|
| 22 | +#define CAMSS_FRAME_MAX_WIDTH 8191 |
---|
| 23 | +#define CAMSS_FRAME_MIN_HEIGHT 1 |
---|
| 24 | +#define CAMSS_FRAME_MAX_HEIGHT_RDI 8191 |
---|
| 25 | +#define CAMSS_FRAME_MAX_HEIGHT_PIX 4096 |
---|
| 26 | + |
---|
21 | 27 | struct fract { |
---|
22 | 28 | u8 numerator; |
---|
23 | 29 | u8 denominator; |
---|
.. | .. |
---|
521 | 527 | { |
---|
522 | 528 | struct camss_video *video = video_drvdata(file); |
---|
523 | 529 | |
---|
524 | | - strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver)); |
---|
525 | | - strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card)); |
---|
| 530 | + strscpy(cap->driver, "qcom-camss", sizeof(cap->driver)); |
---|
| 531 | + strscpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card)); |
---|
526 | 532 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
---|
527 | 533 | dev_name(video->camss->dev)); |
---|
528 | 534 | |
---|
529 | 535 | return 0; |
---|
530 | 536 | } |
---|
531 | 537 | |
---|
532 | | -static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) |
---|
| 538 | +/* |
---|
| 539 | + * Returns the index in the video->formats[] array of the element which |
---|
| 540 | + * has the "ndx"th unique value of pixelformat field. |
---|
| 541 | + * If not found (no more unique pixelformat's) returns -EINVAL. |
---|
| 542 | + */ |
---|
| 543 | +static int video_get_unique_pixelformat_by_index(struct camss_video *video, |
---|
| 544 | + int ndx) |
---|
533 | 545 | { |
---|
534 | | - struct camss_video *video = video_drvdata(file); |
---|
535 | 546 | int i, j, k; |
---|
536 | | - |
---|
537 | | - if (f->type != video->type) |
---|
538 | | - return -EINVAL; |
---|
539 | | - |
---|
540 | | - if (f->index >= video->nformats) |
---|
541 | | - return -EINVAL; |
---|
542 | 547 | |
---|
543 | 548 | /* find index "i" of "k"th unique pixelformat in formats array */ |
---|
544 | 549 | k = -1; |
---|
.. | .. |
---|
552 | 557 | if (j == i) |
---|
553 | 558 | k++; |
---|
554 | 559 | |
---|
555 | | - if (k == f->index) |
---|
556 | | - break; |
---|
| 560 | + if (k == ndx) |
---|
| 561 | + return i; |
---|
557 | 562 | } |
---|
558 | 563 | |
---|
559 | | - if (k < f->index) |
---|
| 564 | + return -EINVAL; |
---|
| 565 | +} |
---|
| 566 | + |
---|
| 567 | +/* |
---|
| 568 | + * Returns the index in the video->formats[] array of the element which |
---|
| 569 | + * has code equal to mcode. |
---|
| 570 | + * If not found returns -EINVAL. |
---|
| 571 | + */ |
---|
| 572 | +static int video_get_pixelformat_by_mbus_code(struct camss_video *video, |
---|
| 573 | + u32 mcode) |
---|
| 574 | +{ |
---|
| 575 | + int i; |
---|
| 576 | + |
---|
| 577 | + for (i = 0; i < video->nformats; i++) { |
---|
| 578 | + if (video->formats[i].code == mcode) |
---|
| 579 | + return i; |
---|
| 580 | + } |
---|
| 581 | + |
---|
| 582 | + return -EINVAL; |
---|
| 583 | +} |
---|
| 584 | + |
---|
| 585 | +static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) |
---|
| 586 | +{ |
---|
| 587 | + struct camss_video *video = video_drvdata(file); |
---|
| 588 | + int i; |
---|
| 589 | + |
---|
| 590 | + if (f->type != video->type) |
---|
| 591 | + return -EINVAL; |
---|
| 592 | + |
---|
| 593 | + if (f->index >= video->nformats) |
---|
| 594 | + return -EINVAL; |
---|
| 595 | + |
---|
| 596 | + if (f->mbus_code) { |
---|
| 597 | + /* Each entry in formats[] table has unique mbus_code */ |
---|
| 598 | + if (f->index > 0) |
---|
| 599 | + return -EINVAL; |
---|
| 600 | + |
---|
| 601 | + i = video_get_pixelformat_by_mbus_code(video, f->mbus_code); |
---|
| 602 | + } else { |
---|
| 603 | + i = video_get_unique_pixelformat_by_index(video, f->index); |
---|
| 604 | + } |
---|
| 605 | + |
---|
| 606 | + if (i < 0) |
---|
560 | 607 | return -EINVAL; |
---|
561 | 608 | |
---|
562 | 609 | f->pixelformat = video->formats[i].pixelformat; |
---|
| 610 | + |
---|
| 611 | + return 0; |
---|
| 612 | +} |
---|
| 613 | + |
---|
| 614 | +static int video_enum_framesizes(struct file *file, void *fh, |
---|
| 615 | + struct v4l2_frmsizeenum *fsize) |
---|
| 616 | +{ |
---|
| 617 | + struct camss_video *video = video_drvdata(file); |
---|
| 618 | + int i; |
---|
| 619 | + |
---|
| 620 | + if (fsize->index) |
---|
| 621 | + return -EINVAL; |
---|
| 622 | + |
---|
| 623 | + /* Only accept pixel format present in the formats[] table */ |
---|
| 624 | + for (i = 0; i < video->nformats; i++) { |
---|
| 625 | + if (video->formats[i].pixelformat == fsize->pixel_format) |
---|
| 626 | + break; |
---|
| 627 | + } |
---|
| 628 | + |
---|
| 629 | + if (i == video->nformats) |
---|
| 630 | + return -EINVAL; |
---|
| 631 | + |
---|
| 632 | + fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; |
---|
| 633 | + fsize->stepwise.min_width = CAMSS_FRAME_MIN_WIDTH; |
---|
| 634 | + fsize->stepwise.max_width = CAMSS_FRAME_MAX_WIDTH; |
---|
| 635 | + fsize->stepwise.min_height = CAMSS_FRAME_MIN_HEIGHT; |
---|
| 636 | + fsize->stepwise.max_height = (video->line_based) ? |
---|
| 637 | + CAMSS_FRAME_MAX_HEIGHT_PIX : CAMSS_FRAME_MAX_HEIGHT_RDI; |
---|
| 638 | + fsize->stepwise.step_width = 1; |
---|
| 639 | + fsize->stepwise.step_height = 1; |
---|
563 | 640 | |
---|
564 | 641 | return 0; |
---|
565 | 642 | } |
---|
.. | .. |
---|
593 | 670 | 1, 65528); |
---|
594 | 671 | sizeimage[i] = clamp_t(u32, p->sizeimage, |
---|
595 | 672 | bytesperline[i], |
---|
596 | | - bytesperline[i] * 4096); |
---|
| 673 | + bytesperline[i] * CAMSS_FRAME_MAX_HEIGHT_PIX); |
---|
597 | 674 | } |
---|
598 | 675 | |
---|
599 | 676 | for (j = 0; j < video->nformats; j++) |
---|
.. | .. |
---|
610 | 687 | memset(pix_mp, 0, sizeof(*pix_mp)); |
---|
611 | 688 | |
---|
612 | 689 | pix_mp->pixelformat = fi->pixelformat; |
---|
613 | | - pix_mp->width = clamp_t(u32, width, 1, 8191); |
---|
614 | | - pix_mp->height = clamp_t(u32, height, 1, 8191); |
---|
| 690 | + pix_mp->width = clamp_t(u32, width, 1, CAMSS_FRAME_MAX_WIDTH); |
---|
| 691 | + pix_mp->height = clamp_t(u32, height, 1, CAMSS_FRAME_MAX_HEIGHT_RDI); |
---|
615 | 692 | pix_mp->num_planes = fi->planes; |
---|
616 | 693 | for (i = 0; i < pix_mp->num_planes; i++) { |
---|
617 | 694 | bpl = pix_mp->width / fi->hsub[i].numerator * |
---|
.. | .. |
---|
637 | 714 | 1, 65528); |
---|
638 | 715 | p->sizeimage = clamp_t(u32, p->sizeimage, |
---|
639 | 716 | p->bytesperline, |
---|
640 | | - p->bytesperline * 4096); |
---|
| 717 | + p->bytesperline * CAMSS_FRAME_MAX_HEIGHT_PIX); |
---|
641 | 718 | lines = p->sizeimage / p->bytesperline; |
---|
642 | 719 | |
---|
643 | 720 | if (p->bytesperline < bytesperline[i]) |
---|
.. | .. |
---|
683 | 760 | if (input->index > 0) |
---|
684 | 761 | return -EINVAL; |
---|
685 | 762 | |
---|
686 | | - strlcpy(input->name, "camera", sizeof(input->name)); |
---|
| 763 | + strscpy(input->name, "camera", sizeof(input->name)); |
---|
687 | 764 | input->type = V4L2_INPUT_TYPE_CAMERA; |
---|
688 | 765 | |
---|
689 | 766 | return 0; |
---|
.. | .. |
---|
703 | 780 | |
---|
704 | 781 | static const struct v4l2_ioctl_ops msm_vid_ioctl_ops = { |
---|
705 | 782 | .vidioc_querycap = video_querycap, |
---|
706 | | - .vidioc_enum_fmt_vid_cap_mplane = video_enum_fmt, |
---|
| 783 | + .vidioc_enum_fmt_vid_cap = video_enum_fmt, |
---|
| 784 | + .vidioc_enum_framesizes = video_enum_framesizes, |
---|
707 | 785 | .vidioc_g_fmt_vid_cap_mplane = video_g_fmt, |
---|
708 | 786 | .vidioc_s_fmt_vid_cap_mplane = video_s_fmt, |
---|
709 | 787 | .vidioc_try_fmt_vid_cap_mplane = video_try_fmt, |
---|
.. | .. |
---|
745 | 823 | |
---|
746 | 824 | file->private_data = vfh; |
---|
747 | 825 | |
---|
748 | | - ret = v4l2_pipeline_pm_use(&vdev->entity, 1); |
---|
| 826 | + ret = v4l2_pipeline_pm_get(&vdev->entity); |
---|
749 | 827 | if (ret < 0) { |
---|
750 | 828 | dev_err(video->camss->dev, "Failed to power up pipeline: %d\n", |
---|
751 | 829 | ret); |
---|
.. | .. |
---|
771 | 849 | |
---|
772 | 850 | vb2_fop_release(file); |
---|
773 | 851 | |
---|
774 | | - v4l2_pipeline_pm_use(&vdev->entity, 0); |
---|
| 852 | + v4l2_pipeline_pm_put(&vdev->entity); |
---|
775 | 853 | |
---|
776 | 854 | file->private_data = NULL; |
---|
777 | 855 | |
---|
.. | .. |
---|
879 | 957 | if (ret < 0) { |
---|
880 | 958 | dev_err(v4l2_dev->dev, "Failed to init video entity: %d\n", |
---|
881 | 959 | ret); |
---|
882 | | - goto error_media_init; |
---|
| 960 | + goto error_vb2_init; |
---|
883 | 961 | } |
---|
884 | 962 | |
---|
885 | 963 | mutex_init(&video->lock); |
---|
.. | .. |
---|
912 | 990 | } |
---|
913 | 991 | |
---|
914 | 992 | vdev->fops = &msm_vid_fops; |
---|
915 | | - vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING | |
---|
916 | | - V4L2_CAP_READWRITE; |
---|
| 993 | + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
---|
| 994 | + | V4L2_CAP_READWRITE | V4L2_CAP_IO_MC; |
---|
917 | 995 | vdev->ioctl_ops = &msm_vid_ioctl_ops; |
---|
918 | 996 | vdev->release = msm_video_release; |
---|
919 | 997 | vdev->v4l2_dev = v4l2_dev; |
---|
920 | 998 | vdev->vfl_dir = VFL_DIR_RX; |
---|
921 | 999 | vdev->queue = &video->vb2_q; |
---|
922 | 1000 | vdev->lock = &video->lock; |
---|
923 | | - strlcpy(vdev->name, name, sizeof(vdev->name)); |
---|
| 1001 | + strscpy(vdev->name, name, sizeof(vdev->name)); |
---|
924 | 1002 | |
---|
925 | | - ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); |
---|
| 1003 | + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); |
---|
926 | 1004 | if (ret < 0) { |
---|
927 | 1005 | dev_err(v4l2_dev->dev, "Failed to register video device: %d\n", |
---|
928 | 1006 | ret); |
---|
.. | .. |
---|
937 | 1015 | error_video_register: |
---|
938 | 1016 | media_entity_cleanup(&vdev->entity); |
---|
939 | 1017 | mutex_destroy(&video->lock); |
---|
940 | | -error_media_init: |
---|
941 | | - vb2_queue_release(&video->vb2_q); |
---|
942 | 1018 | error_vb2_init: |
---|
943 | 1019 | mutex_destroy(&video->q_lock); |
---|
944 | 1020 | |
---|
945 | 1021 | return ret; |
---|
946 | 1022 | } |
---|
947 | 1023 | |
---|
948 | | -void msm_video_stop_streaming(struct camss_video *video) |
---|
949 | | -{ |
---|
950 | | - if (vb2_is_streaming(&video->vb2_q)) |
---|
951 | | - vb2_queue_release(&video->vb2_q); |
---|
952 | | -} |
---|
953 | | - |
---|
954 | 1024 | void msm_video_unregister(struct camss_video *video) |
---|
955 | 1025 | { |
---|
956 | 1026 | atomic_inc(&video->camss->ref_count); |
---|
957 | | - video_unregister_device(&video->vdev); |
---|
| 1027 | + vb2_video_unregister_device(&video->vdev); |
---|
958 | 1028 | atomic_dec(&video->camss->ref_count); |
---|
959 | 1029 | } |
---|