.. | .. |
---|
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: |
---|