.. | .. |
---|
121 | 121 | |
---|
122 | 122 | #define SC2310_NUM_SUPPLIES ARRAY_SIZE(sc2310_supply_names) |
---|
123 | 123 | |
---|
124 | | -enum sc2310_max_pad { |
---|
125 | | - PAD0, |
---|
126 | | - PAD1, |
---|
127 | | - PAD2, |
---|
128 | | - PAD3, |
---|
129 | | - PAD_MAX, |
---|
130 | | -}; |
---|
131 | | - |
---|
132 | 124 | struct regval { |
---|
133 | 125 | u16 addr; |
---|
134 | 126 | u8 val; |
---|
.. | .. |
---|
170 | 162 | struct v4l2_ctrl *pixel_rate; |
---|
171 | 163 | struct v4l2_ctrl *link_freq; |
---|
172 | 164 | struct mutex mutex; |
---|
| 165 | + struct v4l2_fract cur_fps; |
---|
173 | 166 | bool streaming; |
---|
174 | 167 | bool power_on; |
---|
175 | 168 | const struct sc2310_mode *cur_mode; |
---|
.. | .. |
---|
776 | 769 | pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / |
---|
777 | 770 | mode->bpp * 2 * SC2310_LANES; |
---|
778 | 771 | __v4l2_ctrl_s_ctrl_int64(sc2310->pixel_rate, pixel_rate); |
---|
| 772 | + sc2310->cur_fps = mode->max_fps; |
---|
| 773 | + sc2310->cur_vts = mode->vts_def; |
---|
779 | 774 | } |
---|
780 | 775 | |
---|
781 | 776 | mutex_unlock(&sc2310->mutex); |
---|
.. | .. |
---|
868 | 863 | struct sc2310 *sc2310 = to_sc2310(sd); |
---|
869 | 864 | const struct sc2310_mode *mode = sc2310->cur_mode; |
---|
870 | 865 | |
---|
871 | | - mutex_lock(&sc2310->mutex); |
---|
872 | | - fi->interval = mode->max_fps; |
---|
873 | | - mutex_unlock(&sc2310->mutex); |
---|
| 866 | + if (sc2310->streaming) |
---|
| 867 | + fi->interval = sc2310->cur_fps; |
---|
| 868 | + else |
---|
| 869 | + fi->interval = mode->max_fps; |
---|
874 | 870 | |
---|
875 | 871 | return 0; |
---|
876 | 872 | } |
---|
877 | 873 | |
---|
878 | | -static int sc2310_g_mbus_config(struct v4l2_subdev *sd, |
---|
| 874 | +static int sc2310_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
---|
879 | 875 | struct v4l2_mbus_config *config) |
---|
880 | 876 | { |
---|
881 | 877 | struct sc2310 *sc2310 = to_sc2310(sd); |
---|
.. | .. |
---|
892 | 888 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | |
---|
893 | 889 | V4L2_MBUS_CSI2_CHANNEL_1; |
---|
894 | 890 | |
---|
895 | | - config->type = V4L2_MBUS_CSI2; |
---|
| 891 | + config->type = V4L2_MBUS_CSI2_DPHY; |
---|
896 | 892 | config->flags = val; |
---|
897 | 893 | |
---|
898 | 894 | return 0; |
---|
.. | .. |
---|
1078 | 1074 | return 0; |
---|
1079 | 1075 | } |
---|
1080 | 1076 | |
---|
| 1077 | +static int sc2310_get_channel_info(struct sc2310 *sc2310, struct rkmodule_channel_info *ch_info) |
---|
| 1078 | +{ |
---|
| 1079 | + if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) |
---|
| 1080 | + return -EINVAL; |
---|
| 1081 | + ch_info->vc = sc2310->cur_mode->vc[ch_info->index]; |
---|
| 1082 | + ch_info->width = sc2310->cur_mode->width; |
---|
| 1083 | + ch_info->height = sc2310->cur_mode->height; |
---|
| 1084 | + ch_info->bus_fmt = sc2310->cur_mode->bus_fmt; |
---|
| 1085 | + return 0; |
---|
| 1086 | +} |
---|
| 1087 | + |
---|
1081 | 1088 | static long sc2310_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
---|
1082 | 1089 | { |
---|
1083 | 1090 | struct sc2310 *sc2310 = to_sc2310(sd); |
---|
1084 | 1091 | struct rkmodule_hdr_cfg *hdr_cfg; |
---|
1085 | 1092 | const struct sc2310_mode *mode; |
---|
| 1093 | + struct rkmodule_channel_info *ch_info; |
---|
1086 | 1094 | long ret = 0; |
---|
1087 | 1095 | u64 pixel_rate = 0; |
---|
1088 | 1096 | u32 i, h, w, stream; |
---|
.. | .. |
---|
1127 | 1135 | mode->bpp * 2 * SC2310_LANES; |
---|
1128 | 1136 | __v4l2_ctrl_s_ctrl_int64(sc2310->pixel_rate, |
---|
1129 | 1137 | pixel_rate); |
---|
| 1138 | + sc2310->cur_fps = mode->max_fps; |
---|
| 1139 | + sc2310->cur_vts = mode->vts_def; |
---|
1130 | 1140 | dev_info(&sc2310->client->dev, |
---|
1131 | 1141 | "sensor mode: %d\n", mode->hdr_mode); |
---|
1132 | 1142 | } |
---|
.. | .. |
---|
1150 | 1160 | ret = sc2310_write_reg(sc2310->client, SC2310_REG_CTRL_MODE, |
---|
1151 | 1161 | SC2310_REG_VALUE_08BIT, SC2310_MODE_SW_STANDBY); |
---|
1152 | 1162 | break; |
---|
| 1163 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 1164 | + ch_info = (struct rkmodule_channel_info *)arg; |
---|
| 1165 | + ret = sc2310_get_channel_info(sc2310, ch_info); |
---|
| 1166 | + break; |
---|
1153 | 1167 | default: |
---|
1154 | 1168 | ret = -ENOIOCTLCMD; |
---|
1155 | 1169 | break; |
---|
.. | .. |
---|
1167 | 1181 | struct rkmodule_awb_cfg *cfg; |
---|
1168 | 1182 | struct rkmodule_hdr_cfg *hdr; |
---|
1169 | 1183 | struct preisp_hdrae_exp_s *hdrae; |
---|
| 1184 | + struct rkmodule_channel_info *ch_info; |
---|
1170 | 1185 | long ret = 0; |
---|
1171 | 1186 | u32 cg = 0; |
---|
1172 | 1187 | u32 stream = 0; |
---|
.. | .. |
---|
1255 | 1270 | if (copy_from_user(&stream, up, sizeof(u32))) |
---|
1256 | 1271 | return -EFAULT; |
---|
1257 | 1272 | ret = sc2310_ioctl(sd, cmd, &stream); |
---|
| 1273 | + break; |
---|
| 1274 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 1275 | + ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); |
---|
| 1276 | + if (!ch_info) { |
---|
| 1277 | + ret = -ENOMEM; |
---|
| 1278 | + return ret; |
---|
| 1279 | + } |
---|
| 1280 | + |
---|
| 1281 | + ret = sc2310_ioctl(sd, cmd, ch_info); |
---|
| 1282 | + if (!ret) { |
---|
| 1283 | + ret = copy_to_user(up, ch_info, sizeof(*ch_info)); |
---|
| 1284 | + if (ret) |
---|
| 1285 | + ret = -EFAULT; |
---|
| 1286 | + } |
---|
| 1287 | + kfree(ch_info); |
---|
1258 | 1288 | break; |
---|
1259 | 1289 | default: |
---|
1260 | 1290 | ret = -ENOIOCTLCMD; |
---|
.. | .. |
---|
1523 | 1553 | static const struct v4l2_subdev_video_ops sc2310_video_ops = { |
---|
1524 | 1554 | .s_stream = sc2310_s_stream, |
---|
1525 | 1555 | .g_frame_interval = sc2310_g_frame_interval, |
---|
1526 | | - .g_mbus_config = sc2310_g_mbus_config, |
---|
1527 | 1556 | }; |
---|
1528 | 1557 | |
---|
1529 | 1558 | static const struct v4l2_subdev_pad_ops sc2310_pad_ops = { |
---|
.. | .. |
---|
1532 | 1561 | .enum_frame_interval = sc2310_enum_frame_interval, |
---|
1533 | 1562 | .get_fmt = sc2310_get_fmt, |
---|
1534 | 1563 | .set_fmt = sc2310_set_fmt, |
---|
| 1564 | + .get_mbus_config = sc2310_g_mbus_config, |
---|
1535 | 1565 | }; |
---|
1536 | 1566 | |
---|
1537 | 1567 | static const struct v4l2_subdev_ops sc2310_subdev_ops = { |
---|
.. | .. |
---|
1539 | 1569 | .video = &sc2310_video_ops, /* */ |
---|
1540 | 1570 | .pad = &sc2310_pad_ops, /* */ |
---|
1541 | 1571 | }; |
---|
| 1572 | + |
---|
| 1573 | +static void sc2310_modify_fps_info(struct sc2310 *sc2310) |
---|
| 1574 | +{ |
---|
| 1575 | + const struct sc2310_mode *mode = sc2310->cur_mode; |
---|
| 1576 | + |
---|
| 1577 | + sc2310->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / |
---|
| 1578 | + sc2310->cur_vts; |
---|
| 1579 | +} |
---|
1542 | 1580 | |
---|
1543 | 1581 | static int sc2310_set_ctrl(struct v4l2_ctrl *ctrl) |
---|
1544 | 1582 | { |
---|
.. | .. |
---|
1613 | 1651 | ret = sc2310_write_reg(sc2310->client, SC2310_REG_VTS, |
---|
1614 | 1652 | SC2310_REG_VALUE_16BIT, |
---|
1615 | 1653 | ctrl->val + sc2310->cur_mode->height); |
---|
| 1654 | + if (!ret) |
---|
| 1655 | + sc2310->cur_vts = ctrl->val + sc2310->cur_mode->height; |
---|
| 1656 | + if (sc2310->cur_vts != sc2310->cur_mode->vts_def) |
---|
| 1657 | + sc2310_modify_fps_info(sc2310); |
---|
1616 | 1658 | dev_dbg(&client->dev, "set vblank 0x%x\n", |
---|
1617 | 1659 | ctrl->val); |
---|
1618 | 1660 | break; |
---|
.. | .. |
---|
1727 | 1769 | |
---|
1728 | 1770 | sc2310->subdev.ctrl_handler = handler; |
---|
1729 | 1771 | sc2310->has_init_exp = false; |
---|
| 1772 | + sc2310->cur_fps = mode->max_fps; |
---|
| 1773 | + sc2310->cur_vts = mode->vts_def; |
---|
1730 | 1774 | |
---|
1731 | 1775 | return 0; |
---|
1732 | 1776 | |
---|