| .. | .. |
|---|
| 118 | 118 | struct v4l2_ctrl *vblank; |
|---|
| 119 | 119 | struct v4l2_ctrl *test_pattern; |
|---|
| 120 | 120 | struct mutex mutex; |
|---|
| 121 | + struct v4l2_fract cur_fps; |
|---|
| 122 | + u32 cur_vts; |
|---|
| 121 | 123 | bool streaming; |
|---|
| 122 | 124 | bool power_on; |
|---|
| 123 | 125 | const struct sc2239_mode *cur_mode; |
|---|
| .. | .. |
|---|
| 406 | 408 | __v4l2_ctrl_modify_range(sc2239->vblank, vblank_def, |
|---|
| 407 | 409 | SC2239_VTS_MAX - mode->height, |
|---|
| 408 | 410 | 1, vblank_def); |
|---|
| 411 | + sc2239->cur_fps = mode->max_fps; |
|---|
| 412 | + sc2239->cur_vts = mode->vts_def; |
|---|
| 409 | 413 | } |
|---|
| 410 | 414 | |
|---|
| 411 | 415 | mutex_unlock(&sc2239->mutex); |
|---|
| .. | .. |
|---|
| 542 | 546 | } |
|---|
| 543 | 547 | |
|---|
| 544 | 548 | ret = sc2239_ioctl(sd, cmd, inf); |
|---|
| 545 | | - if (!ret) |
|---|
| 549 | + if (!ret) { |
|---|
| 546 | 550 | ret = copy_to_user(up, inf, sizeof(*inf)); |
|---|
| 551 | + if (ret) |
|---|
| 552 | + ret = -EFAULT; |
|---|
| 553 | + } |
|---|
| 547 | 554 | kfree(inf); |
|---|
| 548 | 555 | break; |
|---|
| 549 | 556 | case RKMODULE_AWB_CFG: |
|---|
| .. | .. |
|---|
| 556 | 563 | ret = copy_from_user(cfg, up, sizeof(*cfg)); |
|---|
| 557 | 564 | if (!ret) |
|---|
| 558 | 565 | ret = sc2239_ioctl(sd, cmd, cfg); |
|---|
| 566 | + else |
|---|
| 567 | + ret = -EFAULT; |
|---|
| 559 | 568 | kfree(cfg); |
|---|
| 560 | 569 | break; |
|---|
| 561 | 570 | case RKMODULE_SET_QUICK_STREAM: |
|---|
| 562 | 571 | ret = copy_from_user(&stream, up, sizeof(u32)); |
|---|
| 563 | 572 | if (!ret) |
|---|
| 564 | 573 | ret = sc2239_ioctl(sd, cmd, &stream); |
|---|
| 574 | + else |
|---|
| 575 | + ret = -EFAULT; |
|---|
| 565 | 576 | break; |
|---|
| 566 | 577 | default: |
|---|
| 567 | 578 | ret = -ENOIOCTLCMD; |
|---|
| .. | .. |
|---|
| 698 | 709 | struct sc2239 *sc2239 = to_sc2239(sd); |
|---|
| 699 | 710 | const struct sc2239_mode *mode = sc2239->cur_mode; |
|---|
| 700 | 711 | |
|---|
| 701 | | - mutex_lock(&sc2239->mutex); |
|---|
| 702 | | - fi->interval = mode->max_fps; |
|---|
| 703 | | - mutex_unlock(&sc2239->mutex); |
|---|
| 712 | + if (sc2239->streaming) |
|---|
| 713 | + fi->interval = sc2239->cur_fps; |
|---|
| 714 | + else |
|---|
| 715 | + fi->interval = mode->max_fps; |
|---|
| 704 | 716 | |
|---|
| 705 | 717 | return 0; |
|---|
| 706 | 718 | } |
|---|
| .. | .. |
|---|
| 843 | 855 | } |
|---|
| 844 | 856 | #endif |
|---|
| 845 | 857 | |
|---|
| 846 | | -static int sc2239_g_mbus_config(struct v4l2_subdev *sd, |
|---|
| 858 | +static int sc2239_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
|---|
| 847 | 859 | struct v4l2_mbus_config *config) |
|---|
| 848 | 860 | { |
|---|
| 849 | 861 | u32 val = 1 << (SC2239_LANES - 1) | |
|---|
| 850 | 862 | V4L2_MBUS_CSI2_CHANNEL_0 | |
|---|
| 851 | 863 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
|---|
| 852 | 864 | |
|---|
| 853 | | - config->type = V4L2_MBUS_CSI2; |
|---|
| 865 | + config->type = V4L2_MBUS_CSI2_DPHY; |
|---|
| 854 | 866 | config->flags = val; |
|---|
| 855 | 867 | |
|---|
| 856 | 868 | return 0; |
|---|
| .. | .. |
|---|
| 863 | 875 | if (fie->index >= ARRAY_SIZE(supported_modes)) |
|---|
| 864 | 876 | return -EINVAL; |
|---|
| 865 | 877 | |
|---|
| 866 | | - if (fie->code != PIX_FORMAT) |
|---|
| 867 | | - return -EINVAL; |
|---|
| 878 | + fie->code = PIX_FORMAT; |
|---|
| 868 | 879 | |
|---|
| 869 | 880 | fie->width = supported_modes[fie->index].width; |
|---|
| 870 | 881 | fie->height = supported_modes[fie->index].height; |
|---|
| .. | .. |
|---|
| 894 | 905 | static const struct v4l2_subdev_video_ops sc2239_video_ops = { |
|---|
| 895 | 906 | .s_stream = sc2239_s_stream, |
|---|
| 896 | 907 | .g_frame_interval = sc2239_g_frame_interval, |
|---|
| 897 | | - .g_mbus_config = sc2239_g_mbus_config, |
|---|
| 898 | 908 | }; |
|---|
| 899 | 909 | |
|---|
| 900 | 910 | static const struct v4l2_subdev_pad_ops sc2239_pad_ops = { |
|---|
| .. | .. |
|---|
| 903 | 913 | .enum_frame_interval = sc2239_enum_frame_interval, |
|---|
| 904 | 914 | .get_fmt = sc2239_get_fmt, |
|---|
| 905 | 915 | .set_fmt = sc2239_set_fmt, |
|---|
| 916 | + .get_mbus_config = sc2239_g_mbus_config, |
|---|
| 906 | 917 | }; |
|---|
| 907 | 918 | |
|---|
| 908 | 919 | static const struct v4l2_subdev_ops sc2239_subdev_ops = { |
|---|
| .. | .. |
|---|
| 910 | 921 | .video = &sc2239_video_ops, |
|---|
| 911 | 922 | .pad = &sc2239_pad_ops, |
|---|
| 912 | 923 | }; |
|---|
| 924 | + |
|---|
| 925 | +static void sc2239_modify_fps_info(struct sc2239 *sc2239) |
|---|
| 926 | +{ |
|---|
| 927 | + const struct sc2239_mode *mode = sc2239->cur_mode; |
|---|
| 928 | + |
|---|
| 929 | + sc2239->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / |
|---|
| 930 | + sc2239->cur_vts; |
|---|
| 931 | +} |
|---|
| 913 | 932 | |
|---|
| 914 | 933 | static int sc2239_set_ctrl(struct v4l2_ctrl *ctrl) |
|---|
| 915 | 934 | { |
|---|
| .. | .. |
|---|
| 953 | 972 | ret = sc2239_write_reg(sc2239->client, SC2239_REG_VTS, |
|---|
| 954 | 973 | SC2239_REG_VALUE_16BIT, |
|---|
| 955 | 974 | ctrl->val + sc2239->cur_mode->height); |
|---|
| 975 | + if (!ret) |
|---|
| 976 | + sc2239->cur_vts = ctrl->val + sc2239->cur_mode->height; |
|---|
| 977 | + sc2239_modify_fps_info(sc2239); |
|---|
| 956 | 978 | break; |
|---|
| 957 | 979 | case V4L2_CID_TEST_PATTERN: |
|---|
| 958 | 980 | ret = sc2239_enable_test_pattern(sc2239, ctrl->val); |
|---|
| .. | .. |
|---|
| 1033 | 1055 | |
|---|
| 1034 | 1056 | sc2239->subdev.ctrl_handler = handler; |
|---|
| 1035 | 1057 | sc2239->old_gain = ANALOG_GAIN_DEFAULT; |
|---|
| 1058 | + sc2239->cur_fps = mode->max_fps; |
|---|
| 1059 | + sc2239->cur_vts = mode->vts_def; |
|---|
| 1060 | + |
|---|
| 1036 | 1061 | return 0; |
|---|
| 1037 | 1062 | |
|---|
| 1038 | 1063 | err_free_handler: |
|---|