| .. | .. |
|---|
| 243 | 243 | |
|---|
| 244 | 244 | static void rvin_group_cleanup(struct rvin_group *group) |
|---|
| 245 | 245 | { |
|---|
| 246 | | - media_device_unregister(&group->mdev); |
|---|
| 247 | 246 | media_device_cleanup(&group->mdev); |
|---|
| 248 | 247 | mutex_destroy(&group->lock); |
|---|
| 249 | 248 | } |
|---|
| .. | .. |
|---|
| 253 | 252 | struct media_device *mdev = &group->mdev; |
|---|
| 254 | 253 | const struct of_device_id *match; |
|---|
| 255 | 254 | struct device_node *np; |
|---|
| 256 | | - int ret; |
|---|
| 257 | 255 | |
|---|
| 258 | 256 | mutex_init(&group->lock); |
|---|
| 259 | 257 | |
|---|
| .. | .. |
|---|
| 271 | 269 | match = of_match_node(vin->dev->driver->of_match_table, |
|---|
| 272 | 270 | vin->dev->of_node); |
|---|
| 273 | 271 | |
|---|
| 274 | | - strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); |
|---|
| 275 | | - strlcpy(mdev->model, match->compatible, sizeof(mdev->model)); |
|---|
| 272 | + strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); |
|---|
| 273 | + strscpy(mdev->model, match->compatible, sizeof(mdev->model)); |
|---|
| 276 | 274 | snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", |
|---|
| 277 | 275 | dev_name(mdev->dev)); |
|---|
| 278 | 276 | |
|---|
| 279 | 277 | media_device_init(mdev); |
|---|
| 280 | 278 | |
|---|
| 281 | | - ret = media_device_register(&group->mdev); |
|---|
| 282 | | - if (ret) |
|---|
| 283 | | - rvin_group_cleanup(group); |
|---|
| 284 | | - |
|---|
| 285 | | - return ret; |
|---|
| 279 | + return 0; |
|---|
| 286 | 280 | } |
|---|
| 287 | 281 | |
|---|
| 288 | 282 | static void rvin_group_release(struct kref *kref) |
|---|
| .. | .. |
|---|
| 390 | 384 | } |
|---|
| 391 | 385 | |
|---|
| 392 | 386 | /* ----------------------------------------------------------------------------- |
|---|
| 387 | + * Controls |
|---|
| 388 | + */ |
|---|
| 389 | + |
|---|
| 390 | +static int rvin_s_ctrl(struct v4l2_ctrl *ctrl) |
|---|
| 391 | +{ |
|---|
| 392 | + struct rvin_dev *vin = |
|---|
| 393 | + container_of(ctrl->handler, struct rvin_dev, ctrl_handler); |
|---|
| 394 | + |
|---|
| 395 | + switch (ctrl->id) { |
|---|
| 396 | + case V4L2_CID_ALPHA_COMPONENT: |
|---|
| 397 | + rvin_set_alpha(vin, ctrl->val); |
|---|
| 398 | + break; |
|---|
| 399 | + } |
|---|
| 400 | + |
|---|
| 401 | + return 0; |
|---|
| 402 | +} |
|---|
| 403 | + |
|---|
| 404 | +static const struct v4l2_ctrl_ops rvin_ctrl_ops = { |
|---|
| 405 | + .s_ctrl = rvin_s_ctrl, |
|---|
| 406 | +}; |
|---|
| 407 | + |
|---|
| 408 | +/* ----------------------------------------------------------------------------- |
|---|
| 393 | 409 | * Async notifier |
|---|
| 394 | 410 | */ |
|---|
| 395 | 411 | |
|---|
| .. | .. |
|---|
| 478 | 494 | if (ret < 0) |
|---|
| 479 | 495 | return ret; |
|---|
| 480 | 496 | |
|---|
| 497 | + v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, |
|---|
| 498 | + V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); |
|---|
| 499 | + |
|---|
| 500 | + if (vin->ctrl_handler.error) { |
|---|
| 501 | + ret = vin->ctrl_handler.error; |
|---|
| 502 | + v4l2_ctrl_handler_free(&vin->ctrl_handler); |
|---|
| 503 | + return ret; |
|---|
| 504 | + } |
|---|
| 505 | + |
|---|
| 481 | 506 | ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler, |
|---|
| 482 | | - NULL); |
|---|
| 507 | + NULL, true); |
|---|
| 483 | 508 | if (ret < 0) { |
|---|
| 484 | 509 | v4l2_ctrl_handler_free(&vin->ctrl_handler); |
|---|
| 485 | 510 | return ret; |
|---|
| .. | .. |
|---|
| 595 | 620 | |
|---|
| 596 | 621 | switch (vin->parallel->mbus_type) { |
|---|
| 597 | 622 | case V4L2_MBUS_PARALLEL: |
|---|
| 598 | | - vin_dbg(vin, "Found PARALLEL media bus\n"); |
|---|
| 599 | | - vin->parallel->mbus_flags = vep->bus.parallel.flags; |
|---|
| 600 | | - break; |
|---|
| 601 | 623 | case V4L2_MBUS_BT656: |
|---|
| 602 | | - vin_dbg(vin, "Found BT656 media bus\n"); |
|---|
| 603 | | - vin->parallel->mbus_flags = 0; |
|---|
| 624 | + vin_dbg(vin, "Found %s media bus\n", |
|---|
| 625 | + vin->parallel->mbus_type == V4L2_MBUS_PARALLEL ? |
|---|
| 626 | + "PARALLEL" : "BT656"); |
|---|
| 627 | + vin->parallel->bus = vep->bus.parallel; |
|---|
| 604 | 628 | break; |
|---|
| 605 | 629 | default: |
|---|
| 606 | 630 | vin_err(vin, "Unknown media bus type\n"); |
|---|
| .. | .. |
|---|
| 613 | 637 | static int rvin_parallel_init(struct rvin_dev *vin) |
|---|
| 614 | 638 | { |
|---|
| 615 | 639 | int ret; |
|---|
| 640 | + |
|---|
| 641 | + v4l2_async_notifier_init(&vin->notifier); |
|---|
| 616 | 642 | |
|---|
| 617 | 643 | ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( |
|---|
| 618 | 644 | vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity), |
|---|
| .. | .. |
|---|
| 648 | 674 | const struct rvin_group_route *route; |
|---|
| 649 | 675 | unsigned int i; |
|---|
| 650 | 676 | int ret; |
|---|
| 677 | + |
|---|
| 678 | + ret = media_device_register(&vin->group->mdev); |
|---|
| 679 | + if (ret) |
|---|
| 680 | + return ret; |
|---|
| 651 | 681 | |
|---|
| 652 | 682 | ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); |
|---|
| 653 | 683 | if (ret) { |
|---|
| .. | .. |
|---|
| 729 | 759 | } |
|---|
| 730 | 760 | |
|---|
| 731 | 761 | mutex_unlock(&vin->group->lock); |
|---|
| 762 | + |
|---|
| 763 | + media_device_unregister(&vin->group->mdev); |
|---|
| 732 | 764 | } |
|---|
| 733 | 765 | |
|---|
| 734 | 766 | static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, |
|---|
| .. | .. |
|---|
| 764 | 796 | struct v4l2_async_subdev *asd) |
|---|
| 765 | 797 | { |
|---|
| 766 | 798 | struct rvin_dev *vin = dev_get_drvdata(dev); |
|---|
| 799 | + int ret = 0; |
|---|
| 767 | 800 | |
|---|
| 768 | 801 | if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX) |
|---|
| 769 | 802 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 774 | 807 | return -ENOTCONN; |
|---|
| 775 | 808 | } |
|---|
| 776 | 809 | |
|---|
| 810 | + mutex_lock(&vin->group->lock); |
|---|
| 811 | + |
|---|
| 777 | 812 | if (vin->group->csi[vep->base.id].fwnode) { |
|---|
| 778 | 813 | vin_dbg(vin, "OF device %pOF already handled\n", |
|---|
| 779 | 814 | to_of_node(asd->match.fwnode)); |
|---|
| 780 | | - return -ENOTCONN; |
|---|
| 815 | + ret = -ENOTCONN; |
|---|
| 816 | + goto out; |
|---|
| 781 | 817 | } |
|---|
| 782 | 818 | |
|---|
| 783 | 819 | vin->group->csi[vep->base.id].fwnode = asd->match.fwnode; |
|---|
| 784 | 820 | |
|---|
| 785 | 821 | vin_dbg(vin, "Add group OF device %pOF to slot %u\n", |
|---|
| 786 | 822 | to_of_node(asd->match.fwnode), vep->base.id); |
|---|
| 823 | +out: |
|---|
| 824 | + mutex_unlock(&vin->group->lock); |
|---|
| 787 | 825 | |
|---|
| 788 | | - return 0; |
|---|
| 826 | + return ret; |
|---|
| 789 | 827 | } |
|---|
| 790 | 828 | |
|---|
| 791 | 829 | static int rvin_mc_parse_of_graph(struct rvin_dev *vin) |
|---|
| 792 | 830 | { |
|---|
| 793 | | - unsigned int count = 0; |
|---|
| 831 | + unsigned int count = 0, vin_mask = 0; |
|---|
| 794 | 832 | unsigned int i; |
|---|
| 795 | 833 | int ret; |
|---|
| 796 | 834 | |
|---|
| 797 | 835 | mutex_lock(&vin->group->lock); |
|---|
| 798 | 836 | |
|---|
| 799 | 837 | /* If not all VIN's are registered don't register the notifier. */ |
|---|
| 800 | | - for (i = 0; i < RCAR_VIN_NUM; i++) |
|---|
| 801 | | - if (vin->group->vin[i]) |
|---|
| 838 | + for (i = 0; i < RCAR_VIN_NUM; i++) { |
|---|
| 839 | + if (vin->group->vin[i]) { |
|---|
| 802 | 840 | count++; |
|---|
| 841 | + vin_mask |= BIT(i); |
|---|
| 842 | + } |
|---|
| 843 | + } |
|---|
| 803 | 844 | |
|---|
| 804 | 845 | if (vin->group->count != count) { |
|---|
| 805 | 846 | mutex_unlock(&vin->group->lock); |
|---|
| 806 | 847 | return 0; |
|---|
| 807 | 848 | } |
|---|
| 849 | + |
|---|
| 850 | + mutex_unlock(&vin->group->lock); |
|---|
| 851 | + |
|---|
| 852 | + v4l2_async_notifier_init(&vin->group->notifier); |
|---|
| 808 | 853 | |
|---|
| 809 | 854 | /* |
|---|
| 810 | 855 | * Have all VIN's look for CSI-2 subdevices. Some subdevices will |
|---|
| .. | .. |
|---|
| 812 | 857 | * will only be registered once with the group notifier. |
|---|
| 813 | 858 | */ |
|---|
| 814 | 859 | for (i = 0; i < RCAR_VIN_NUM; i++) { |
|---|
| 815 | | - if (!vin->group->vin[i]) |
|---|
| 860 | + if (!(vin_mask & BIT(i))) |
|---|
| 816 | 861 | continue; |
|---|
| 817 | 862 | |
|---|
| 818 | 863 | ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( |
|---|
| 819 | 864 | vin->group->vin[i]->dev, &vin->group->notifier, |
|---|
| 820 | 865 | sizeof(struct v4l2_async_subdev), 1, |
|---|
| 821 | 866 | rvin_mc_parse_of_endpoint); |
|---|
| 822 | | - if (ret) { |
|---|
| 823 | | - mutex_unlock(&vin->group->lock); |
|---|
| 867 | + if (ret) |
|---|
| 824 | 868 | return ret; |
|---|
| 825 | | - } |
|---|
| 826 | 869 | } |
|---|
| 827 | 870 | |
|---|
| 828 | | - mutex_unlock(&vin->group->lock); |
|---|
| 829 | | - |
|---|
| 830 | | - if (!vin->group->notifier.num_subdevs) |
|---|
| 871 | + if (list_empty(&vin->group->notifier.asd_list)) |
|---|
| 831 | 872 | return 0; |
|---|
| 832 | 873 | |
|---|
| 833 | 874 | vin->group->notifier.ops = &rvin_group_notify_ops; |
|---|
| .. | .. |
|---|
| 859 | 900 | if (ret) |
|---|
| 860 | 901 | rvin_group_put(vin); |
|---|
| 861 | 902 | |
|---|
| 903 | + ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1); |
|---|
| 904 | + if (ret < 0) |
|---|
| 905 | + return ret; |
|---|
| 906 | + |
|---|
| 907 | + v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, |
|---|
| 908 | + V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); |
|---|
| 909 | + |
|---|
| 910 | + if (vin->ctrl_handler.error) { |
|---|
| 911 | + ret = vin->ctrl_handler.error; |
|---|
| 912 | + v4l2_ctrl_handler_free(&vin->ctrl_handler); |
|---|
| 913 | + return ret; |
|---|
| 914 | + } |
|---|
| 915 | + |
|---|
| 916 | + vin->vdev.ctrl_handler = &vin->ctrl_handler; |
|---|
| 917 | + |
|---|
| 862 | 918 | return ret; |
|---|
| 863 | 919 | } |
|---|
| 864 | 920 | |
|---|
| .. | .. |
|---|
| 885 | 941 | .use_mc = false, |
|---|
| 886 | 942 | .max_width = 2048, |
|---|
| 887 | 943 | .max_height = 2048, |
|---|
| 944 | +}; |
|---|
| 945 | + |
|---|
| 946 | +static const struct rvin_group_route rcar_info_r8a774e1_routes[] = { |
|---|
| 947 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) }, |
|---|
| 948 | + { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) }, |
|---|
| 949 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) }, |
|---|
| 950 | + { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) }, |
|---|
| 951 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) }, |
|---|
| 952 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) }, |
|---|
| 953 | + { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) }, |
|---|
| 954 | + { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) }, |
|---|
| 955 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) }, |
|---|
| 956 | + { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) }, |
|---|
| 957 | + { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) }, |
|---|
| 958 | + { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) }, |
|---|
| 959 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) }, |
|---|
| 960 | + { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) }, |
|---|
| 961 | + { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) }, |
|---|
| 962 | + { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) }, |
|---|
| 963 | + { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) }, |
|---|
| 964 | + { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) }, |
|---|
| 965 | + { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) }, |
|---|
| 966 | + { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) }, |
|---|
| 967 | + { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) }, |
|---|
| 968 | + { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) }, |
|---|
| 969 | + { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) }, |
|---|
| 970 | + { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) }, |
|---|
| 971 | + { /* Sentinel */ } |
|---|
| 972 | +}; |
|---|
| 973 | + |
|---|
| 974 | +static const struct rvin_info rcar_info_r8a774e1 = { |
|---|
| 975 | + .model = RCAR_GEN3, |
|---|
| 976 | + .use_mc = true, |
|---|
| 977 | + .max_width = 4096, |
|---|
| 978 | + .max_height = 4096, |
|---|
| 979 | + .routes = rcar_info_r8a774e1_routes, |
|---|
| 888 | 980 | }; |
|---|
| 889 | 981 | |
|---|
| 890 | 982 | static const struct rvin_group_route rcar_info_r8a7795_routes[] = { |
|---|
| .. | .. |
|---|
| 926 | 1018 | static const struct rvin_info rcar_info_r8a7795 = { |
|---|
| 927 | 1019 | .model = RCAR_GEN3, |
|---|
| 928 | 1020 | .use_mc = true, |
|---|
| 1021 | + .nv12 = true, |
|---|
| 929 | 1022 | .max_width = 4096, |
|---|
| 930 | 1023 | .max_height = 4096, |
|---|
| 931 | 1024 | .routes = rcar_info_r8a7795_routes, |
|---|
| .. | .. |
|---|
| 1020 | 1113 | static const struct rvin_info rcar_info_r8a7796 = { |
|---|
| 1021 | 1114 | .model = RCAR_GEN3, |
|---|
| 1022 | 1115 | .use_mc = true, |
|---|
| 1116 | + .nv12 = true, |
|---|
| 1023 | 1117 | .max_width = 4096, |
|---|
| 1024 | 1118 | .max_height = 4096, |
|---|
| 1025 | 1119 | .routes = rcar_info_r8a7796_routes, |
|---|
| .. | .. |
|---|
| 1064 | 1158 | static const struct rvin_info rcar_info_r8a77965 = { |
|---|
| 1065 | 1159 | .model = RCAR_GEN3, |
|---|
| 1066 | 1160 | .use_mc = true, |
|---|
| 1161 | + .nv12 = true, |
|---|
| 1067 | 1162 | .max_width = 4096, |
|---|
| 1068 | 1163 | .max_height = 4096, |
|---|
| 1069 | 1164 | .routes = rcar_info_r8a77965_routes, |
|---|
| .. | .. |
|---|
| 1088 | 1183 | .routes = rcar_info_r8a77970_routes, |
|---|
| 1089 | 1184 | }; |
|---|
| 1090 | 1185 | |
|---|
| 1186 | +static const struct rvin_group_route rcar_info_r8a77980_routes[] = { |
|---|
| 1187 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) }, |
|---|
| 1188 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) }, |
|---|
| 1189 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) }, |
|---|
| 1190 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) }, |
|---|
| 1191 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) }, |
|---|
| 1192 | + { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) }, |
|---|
| 1193 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) }, |
|---|
| 1194 | + { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) }, |
|---|
| 1195 | + { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) }, |
|---|
| 1196 | + { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) }, |
|---|
| 1197 | + { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) }, |
|---|
| 1198 | + { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) }, |
|---|
| 1199 | + { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) }, |
|---|
| 1200 | + { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) }, |
|---|
| 1201 | + { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) }, |
|---|
| 1202 | + { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) }, |
|---|
| 1203 | + { /* Sentinel */ } |
|---|
| 1204 | +}; |
|---|
| 1205 | + |
|---|
| 1206 | +static const struct rvin_info rcar_info_r8a77980 = { |
|---|
| 1207 | + .model = RCAR_GEN3, |
|---|
| 1208 | + .use_mc = true, |
|---|
| 1209 | + .nv12 = true, |
|---|
| 1210 | + .max_width = 4096, |
|---|
| 1211 | + .max_height = 4096, |
|---|
| 1212 | + .routes = rcar_info_r8a77980_routes, |
|---|
| 1213 | +}; |
|---|
| 1214 | + |
|---|
| 1215 | +static const struct rvin_group_route rcar_info_r8a77990_routes[] = { |
|---|
| 1216 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) }, |
|---|
| 1217 | + { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) }, |
|---|
| 1218 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) }, |
|---|
| 1219 | + { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) }, |
|---|
| 1220 | + { /* Sentinel */ } |
|---|
| 1221 | +}; |
|---|
| 1222 | + |
|---|
| 1223 | +static const struct rvin_info rcar_info_r8a77990 = { |
|---|
| 1224 | + .model = RCAR_GEN3, |
|---|
| 1225 | + .use_mc = true, |
|---|
| 1226 | + .nv12 = true, |
|---|
| 1227 | + .max_width = 4096, |
|---|
| 1228 | + .max_height = 4096, |
|---|
| 1229 | + .routes = rcar_info_r8a77990_routes, |
|---|
| 1230 | +}; |
|---|
| 1231 | + |
|---|
| 1091 | 1232 | static const struct rvin_group_route rcar_info_r8a77995_routes[] = { |
|---|
| 1092 | 1233 | { /* Sentinel */ } |
|---|
| 1093 | 1234 | }; |
|---|
| .. | .. |
|---|
| 1095 | 1236 | static const struct rvin_info rcar_info_r8a77995 = { |
|---|
| 1096 | 1237 | .model = RCAR_GEN3, |
|---|
| 1097 | 1238 | .use_mc = true, |
|---|
| 1239 | + .nv12 = true, |
|---|
| 1098 | 1240 | .max_width = 4096, |
|---|
| 1099 | 1241 | .max_height = 4096, |
|---|
| 1100 | 1242 | .routes = rcar_info_r8a77995_routes, |
|---|
| 1101 | 1243 | }; |
|---|
| 1102 | 1244 | |
|---|
| 1103 | 1245 | static const struct of_device_id rvin_of_id_table[] = { |
|---|
| 1246 | + { |
|---|
| 1247 | + .compatible = "renesas,vin-r8a774a1", |
|---|
| 1248 | + .data = &rcar_info_r8a7796, |
|---|
| 1249 | + }, |
|---|
| 1250 | + { |
|---|
| 1251 | + .compatible = "renesas,vin-r8a774b1", |
|---|
| 1252 | + .data = &rcar_info_r8a77965, |
|---|
| 1253 | + }, |
|---|
| 1254 | + { |
|---|
| 1255 | + .compatible = "renesas,vin-r8a774c0", |
|---|
| 1256 | + .data = &rcar_info_r8a77990, |
|---|
| 1257 | + }, |
|---|
| 1258 | + { |
|---|
| 1259 | + .compatible = "renesas,vin-r8a774e1", |
|---|
| 1260 | + .data = &rcar_info_r8a774e1, |
|---|
| 1261 | + }, |
|---|
| 1104 | 1262 | { |
|---|
| 1105 | 1263 | .compatible = "renesas,vin-r8a7778", |
|---|
| 1106 | 1264 | .data = &rcar_info_m1, |
|---|
| .. | .. |
|---|
| 1146 | 1304 | .data = &rcar_info_r8a77970, |
|---|
| 1147 | 1305 | }, |
|---|
| 1148 | 1306 | { |
|---|
| 1307 | + .compatible = "renesas,vin-r8a77980", |
|---|
| 1308 | + .data = &rcar_info_r8a77980, |
|---|
| 1309 | + }, |
|---|
| 1310 | + { |
|---|
| 1311 | + .compatible = "renesas,vin-r8a77990", |
|---|
| 1312 | + .data = &rcar_info_r8a77990, |
|---|
| 1313 | + }, |
|---|
| 1314 | + { |
|---|
| 1149 | 1315 | .compatible = "renesas,vin-r8a77995", |
|---|
| 1150 | 1316 | .data = &rcar_info_r8a77995, |
|---|
| 1151 | 1317 | }, |
|---|
| .. | .. |
|---|
| 1165 | 1331 | { |
|---|
| 1166 | 1332 | const struct soc_device_attribute *attr; |
|---|
| 1167 | 1333 | struct rvin_dev *vin; |
|---|
| 1168 | | - struct resource *mem; |
|---|
| 1169 | 1334 | int irq, ret; |
|---|
| 1170 | 1335 | |
|---|
| 1171 | 1336 | vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 1174 | 1339 | |
|---|
| 1175 | 1340 | vin->dev = &pdev->dev; |
|---|
| 1176 | 1341 | vin->info = of_device_get_match_data(&pdev->dev); |
|---|
| 1342 | + vin->alpha = 0xff; |
|---|
| 1177 | 1343 | |
|---|
| 1178 | 1344 | /* |
|---|
| 1179 | 1345 | * Special care is needed on r8a7795 ES1.x since it |
|---|
| .. | .. |
|---|
| 1183 | 1349 | if (attr) |
|---|
| 1184 | 1350 | vin->info = attr->data; |
|---|
| 1185 | 1351 | |
|---|
| 1186 | | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 1187 | | - if (mem == NULL) |
|---|
| 1188 | | - return -EINVAL; |
|---|
| 1189 | | - |
|---|
| 1190 | | - vin->base = devm_ioremap_resource(vin->dev, mem); |
|---|
| 1352 | + vin->base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 1191 | 1353 | if (IS_ERR(vin->base)) |
|---|
| 1192 | 1354 | return PTR_ERR(vin->base); |
|---|
| 1193 | 1355 | |
|---|
| .. | .. |
|---|
| 1217 | 1379 | return 0; |
|---|
| 1218 | 1380 | |
|---|
| 1219 | 1381 | error_group_unregister: |
|---|
| 1382 | + v4l2_ctrl_handler_free(&vin->ctrl_handler); |
|---|
| 1383 | + |
|---|
| 1220 | 1384 | if (vin->info->use_mc) { |
|---|
| 1221 | 1385 | mutex_lock(&vin->group->lock); |
|---|
| 1222 | 1386 | if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { |
|---|
| .. | .. |
|---|
| 1245 | 1409 | v4l2_async_notifier_cleanup(&vin->notifier); |
|---|
| 1246 | 1410 | |
|---|
| 1247 | 1411 | if (vin->info->use_mc) { |
|---|
| 1248 | | - mutex_lock(&vin->group->lock); |
|---|
| 1249 | | - if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { |
|---|
| 1250 | | - v4l2_async_notifier_unregister(&vin->group->notifier); |
|---|
| 1251 | | - v4l2_async_notifier_cleanup(&vin->group->notifier); |
|---|
| 1252 | | - } |
|---|
| 1253 | | - mutex_unlock(&vin->group->lock); |
|---|
| 1412 | + v4l2_async_notifier_unregister(&vin->group->notifier); |
|---|
| 1413 | + v4l2_async_notifier_cleanup(&vin->group->notifier); |
|---|
| 1254 | 1414 | rvin_group_put(vin); |
|---|
| 1255 | | - } else { |
|---|
| 1256 | | - v4l2_ctrl_handler_free(&vin->ctrl_handler); |
|---|
| 1257 | 1415 | } |
|---|
| 1258 | 1416 | |
|---|
| 1417 | + v4l2_ctrl_handler_free(&vin->ctrl_handler); |
|---|
| 1418 | + |
|---|
| 1259 | 1419 | rvin_dma_unregister(vin); |
|---|
| 1260 | 1420 | |
|---|
| 1261 | 1421 | return 0; |
|---|