.. | .. |
---|
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 | + if (sc430cs->cur_vts != sc430cs->cur_mode->vts_def) |
---|
| 1206 | + sc430cs_modify_fps_info(sc430cs); |
---|
1185 | 1207 | break; |
---|
1186 | 1208 | case V4L2_CID_TEST_PATTERN: |
---|
1187 | 1209 | ret = sc430cs_enable_test_pattern(sc430cs, ctrl->val); |
---|
.. | .. |
---|
1275 | 1297 | } |
---|
1276 | 1298 | |
---|
1277 | 1299 | sc430cs->subdev.ctrl_handler = handler; |
---|
| 1300 | + sc430cs->cur_fps = mode->max_fps; |
---|
| 1301 | + sc430cs->cur_vts = mode->vts_def; |
---|
1278 | 1302 | |
---|
1279 | 1303 | return 0; |
---|
1280 | 1304 | |
---|