| .. | .. |
|---|
| 113 | 113 | |
|---|
| 114 | 114 | #define SC430CS_NUM_SUPPLIES ARRAY_SIZE(sc430cs_supply_names) |
|---|
| 115 | 115 | |
|---|
| 116 | | -enum sc430cs_max_pad { |
|---|
| 117 | | - PAD0, /* link to isp */ |
|---|
| 118 | | - PAD1, /* link to csi wr0 | hdr x2:L x3:M */ |
|---|
| 119 | | - PAD2, /* link to csi wr1 | hdr x3:L */ |
|---|
| 120 | | - PAD3, /* link to csi wr2 | hdr x2:M x3:S */ |
|---|
| 121 | | - PAD_MAX, |
|---|
| 122 | | -}; |
|---|
| 123 | | - |
|---|
| 124 | 116 | struct regval { |
|---|
| 125 | 117 | u16 addr; |
|---|
| 126 | 118 | u8 val; |
|---|
| .. | .. |
|---|
| 149 | 141 | struct pinctrl *pinctrl; |
|---|
| 150 | 142 | struct pinctrl_state *pins_default; |
|---|
| 151 | 143 | struct pinctrl_state *pins_sleep; |
|---|
| 152 | | - |
|---|
| 144 | + struct v4l2_fract cur_fps; |
|---|
| 153 | 145 | struct v4l2_subdev subdev; |
|---|
| 154 | 146 | struct media_pad pad; |
|---|
| 155 | 147 | struct v4l2_ctrl_handler ctrl_handler; |
|---|
| .. | .. |
|---|
| 570 | 562 | __v4l2_ctrl_modify_range(sc430cs->vblank, vblank_def, |
|---|
| 571 | 563 | SC430CS_VTS_MAX - mode->height, |
|---|
| 572 | 564 | 1, vblank_def); |
|---|
| 565 | + sc430cs->cur_fps = mode->max_fps; |
|---|
| 566 | + sc430cs->cur_vts = (u32)mode->vts_def; |
|---|
| 573 | 567 | } |
|---|
| 574 | 568 | |
|---|
| 575 | 569 | mutex_unlock(&sc430cs->mutex); |
|---|
| .. | .. |
|---|
| 662 | 656 | struct sc430cs *sc430cs = to_sc430cs(sd); |
|---|
| 663 | 657 | const struct sc430cs_mode *mode = sc430cs->cur_mode; |
|---|
| 664 | 658 | |
|---|
| 665 | | - mutex_lock(&sc430cs->mutex); |
|---|
| 666 | | - fi->interval = mode->max_fps; |
|---|
| 667 | | - mutex_unlock(&sc430cs->mutex); |
|---|
| 659 | + if (sc430cs->streaming) |
|---|
| 660 | + fi->interval = sc430cs->cur_fps; |
|---|
| 661 | + else |
|---|
| 662 | + fi->interval = mode->max_fps; |
|---|
| 668 | 663 | |
|---|
| 669 | 664 | return 0; |
|---|
| 670 | 665 | } |
|---|
| 671 | 666 | |
|---|
| 672 | | -static int sc430cs_g_mbus_config(struct v4l2_subdev *sd, |
|---|
| 667 | +static int sc430cs_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
|---|
| 673 | 668 | struct v4l2_mbus_config *config) |
|---|
| 674 | 669 | { |
|---|
| 675 | 670 | struct sc430cs *sc430cs = to_sc430cs(sd); |
|---|
| .. | .. |
|---|
| 683 | 678 | if (mode->hdr_mode == HDR_X3) |
|---|
| 684 | 679 | val |= V4L2_MBUS_CSI2_CHANNEL_2; |
|---|
| 685 | 680 | |
|---|
| 686 | | - config->type = V4L2_MBUS_CSI2; |
|---|
| 681 | + config->type = V4L2_MBUS_CSI2_DPHY; |
|---|
| 687 | 682 | config->flags = val; |
|---|
| 688 | 683 | |
|---|
| 689 | 684 | return 0; |
|---|
| .. | .. |
|---|
| 739 | 734 | __v4l2_ctrl_modify_range(sc430cs->hblank, w, w, 1, w); |
|---|
| 740 | 735 | __v4l2_ctrl_modify_range(sc430cs->vblank, h, |
|---|
| 741 | 736 | SC430CS_VTS_MAX - sc430cs->cur_mode->height, 1, h); |
|---|
| 737 | + sc430cs->cur_fps = sc430cs->cur_mode->max_fps; |
|---|
| 738 | + sc430cs->cur_vts = sc430cs->cur_mode->vts_def; |
|---|
| 742 | 739 | } |
|---|
| 743 | 740 | break; |
|---|
| 744 | 741 | case PREISP_CMD_SET_HDRAE_EXP: |
|---|
| .. | .. |
|---|
| 783 | 780 | } |
|---|
| 784 | 781 | |
|---|
| 785 | 782 | ret = sc430cs_ioctl(sd, cmd, inf); |
|---|
| 786 | | - if (!ret) |
|---|
| 783 | + if (!ret) { |
|---|
| 787 | 784 | ret = copy_to_user(up, inf, sizeof(*inf)); |
|---|
| 785 | + if (ret) |
|---|
| 786 | + ret = -EFAULT; |
|---|
| 787 | + } |
|---|
| 788 | 788 | kfree(inf); |
|---|
| 789 | 789 | break; |
|---|
| 790 | 790 | case RKMODULE_AWB_CFG: |
|---|
| .. | .. |
|---|
| 797 | 797 | ret = copy_from_user(cfg, up, sizeof(*cfg)); |
|---|
| 798 | 798 | if (!ret) |
|---|
| 799 | 799 | ret = sc430cs_ioctl(sd, cmd, cfg); |
|---|
| 800 | + else |
|---|
| 801 | + ret = -EFAULT; |
|---|
| 800 | 802 | kfree(cfg); |
|---|
| 801 | 803 | break; |
|---|
| 802 | 804 | case RKMODULE_GET_HDR_CFG: |
|---|
| .. | .. |
|---|
| 807 | 809 | } |
|---|
| 808 | 810 | |
|---|
| 809 | 811 | ret = sc430cs_ioctl(sd, cmd, hdr); |
|---|
| 810 | | - if (!ret) |
|---|
| 812 | + if (!ret) { |
|---|
| 811 | 813 | ret = copy_to_user(up, hdr, sizeof(*hdr)); |
|---|
| 814 | + if (ret) |
|---|
| 815 | + ret = -EFAULT; |
|---|
| 816 | + } |
|---|
| 812 | 817 | kfree(hdr); |
|---|
| 813 | 818 | break; |
|---|
| 814 | 819 | case RKMODULE_SET_HDR_CFG: |
|---|
| .. | .. |
|---|
| 821 | 826 | ret = copy_from_user(hdr, up, sizeof(*hdr)); |
|---|
| 822 | 827 | if (!ret) |
|---|
| 823 | 828 | ret = sc430cs_ioctl(sd, cmd, hdr); |
|---|
| 829 | + else |
|---|
| 830 | + ret = -EFAULT; |
|---|
| 824 | 831 | kfree(hdr); |
|---|
| 825 | 832 | break; |
|---|
| 826 | 833 | case PREISP_CMD_SET_HDRAE_EXP: |
|---|
| .. | .. |
|---|
| 833 | 840 | ret = copy_from_user(hdrae, up, sizeof(*hdrae)); |
|---|
| 834 | 841 | if (!ret) |
|---|
| 835 | 842 | ret = sc430cs_ioctl(sd, cmd, hdrae); |
|---|
| 843 | + else |
|---|
| 844 | + ret = -EFAULT; |
|---|
| 836 | 845 | kfree(hdrae); |
|---|
| 837 | 846 | break; |
|---|
| 838 | 847 | case RKMODULE_SET_QUICK_STREAM: |
|---|
| 839 | 848 | ret = copy_from_user(&stream, up, sizeof(u32)); |
|---|
| 840 | 849 | if (!ret) |
|---|
| 841 | 850 | ret = sc430cs_ioctl(sd, cmd, &stream); |
|---|
| 851 | + else |
|---|
| 852 | + ret = -EFAULT; |
|---|
| 842 | 853 | break; |
|---|
| 843 | 854 | default: |
|---|
| 844 | 855 | ret = -ENOIOCTLCMD; |
|---|
| .. | .. |
|---|
| 1106 | 1117 | static const struct v4l2_subdev_video_ops sc430cs_video_ops = { |
|---|
| 1107 | 1118 | .s_stream = sc430cs_s_stream, |
|---|
| 1108 | 1119 | .g_frame_interval = sc430cs_g_frame_interval, |
|---|
| 1109 | | - .g_mbus_config = sc430cs_g_mbus_config, |
|---|
| 1110 | 1120 | }; |
|---|
| 1111 | 1121 | |
|---|
| 1112 | 1122 | static const struct v4l2_subdev_pad_ops sc430cs_pad_ops = { |
|---|
| .. | .. |
|---|
| 1115 | 1125 | .enum_frame_interval = sc430cs_enum_frame_interval, |
|---|
| 1116 | 1126 | .get_fmt = sc430cs_get_fmt, |
|---|
| 1117 | 1127 | .set_fmt = sc430cs_set_fmt, |
|---|
| 1128 | + .get_mbus_config = sc430cs_g_mbus_config, |
|---|
| 1118 | 1129 | }; |
|---|
| 1119 | 1130 | |
|---|
| 1120 | 1131 | static const struct v4l2_subdev_ops sc430cs_subdev_ops = { |
|---|
| .. | .. |
|---|
| 1122 | 1133 | .video = &sc430cs_video_ops, |
|---|
| 1123 | 1134 | .pad = &sc430cs_pad_ops, |
|---|
| 1124 | 1135 | }; |
|---|
| 1136 | + |
|---|
| 1137 | +static void sc430cs_modify_fps_info(struct sc430cs *sc430cs) |
|---|
| 1138 | +{ |
|---|
| 1139 | + const struct sc430cs_mode *mode = sc430cs->cur_mode; |
|---|
| 1140 | + |
|---|
| 1141 | + sc430cs->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / |
|---|
| 1142 | + sc430cs->cur_vts; |
|---|
| 1143 | +} |
|---|
| 1125 | 1144 | |
|---|
| 1126 | 1145 | static int sc430cs_set_ctrl(struct v4l2_ctrl *ctrl) |
|---|
| 1127 | 1146 | { |
|---|
| .. | .. |
|---|
| 1181 | 1200 | SC430CS_REG_VALUE_08BIT, |
|---|
| 1182 | 1201 | (ctrl->val + sc430cs->cur_mode->height) |
|---|
| 1183 | 1202 | & 0xff); |
|---|
| 1184 | | - sc430cs->cur_vts = ctrl->val + sc430cs->cur_mode->height; |
|---|
| 1203 | + if (!ret) |
|---|
| 1204 | + sc430cs->cur_vts = ctrl->val + sc430cs->cur_mode->height; |
|---|
| 1205 | + sc430cs_modify_fps_info(sc430cs); |
|---|
| 1185 | 1206 | break; |
|---|
| 1186 | 1207 | case V4L2_CID_TEST_PATTERN: |
|---|
| 1187 | 1208 | ret = sc430cs_enable_test_pattern(sc430cs, ctrl->val); |
|---|
| .. | .. |
|---|
| 1275 | 1296 | } |
|---|
| 1276 | 1297 | |
|---|
| 1277 | 1298 | sc430cs->subdev.ctrl_handler = handler; |
|---|
| 1299 | + sc430cs->cur_fps = mode->max_fps; |
|---|
| 1300 | + sc430cs->cur_vts = mode->vts_def; |
|---|
| 1278 | 1301 | |
|---|
| 1279 | 1302 | return 0; |
|---|
| 1280 | 1303 | |
|---|